diff --git a/.travis.yml b/.travis.yml
index 41ea0c9afa87c..091a5abdaa216 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -183,7 +183,6 @@ matrix:
       if: branch = master AND type = push
       before_install: []
       install: []
-      cache: false
       sudo: false
       script:
         MESSAGE_FILE=$(mktemp -t msg.XXXXXX);
@@ -201,7 +200,12 @@ env:
     - secure: "cFh8thThqEJLC98XKI5pfqflUzOlxsYPRW20AWRaYOOgYHPTiGWypTXiPbGSKaeAXTZoOA+DpQtEmefc0U6lt9dHc7a/MIaK6isFurjlnKYiLOeTruzyu1z7PWCeZ/jKXsU2RK/88DBtlNwfMdaMIeuKj14IVfpepPPL71ETbuk="
 
 before_install:
-  - zcat $HOME/docker/rust-ci.tar.gz | docker load || true
+  # We'll use the AWS cli to download/upload cached docker layers, so install
+  # that here.
+  - if [ "$TRAVIS_OS_NAME" = linux ]; then
+      pip install --user awscli;
+      export PATH=$PATH:$HOME/.local/bin;
+    fi
   - mkdir -p $HOME/rustsrc
   # FIXME(#46924): these two commands are required to enable IPv6,
   # they shouldn't exist, please revert once more official solutions appeared.
@@ -286,23 +290,9 @@ after_failure:
   # it happened
   - dmesg | grep -i kill
 
-# Save tagged docker images we created and load them if they're available
-# Travis saves caches whether the build failed or not, nuke rustsrc if
-# the failure was while updating it (as it may be in a bad state)
-# https://github.com/travis-ci/travis-ci/issues/4472
-before_cache:
-  - docker history -q rust-ci |
-    grep -v missing |
-    xargs docker save |
-    gzip > $HOME/docker/rust-ci.tar.gz
-
 notifications:
   email: false
 
-cache:
-  directories:
-    - $HOME/docker
-
 before_deploy:
   - mkdir -p deploy/$TRAVIS_COMMIT
   - >
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2b389888e5185..7a62405f05967 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -594,7 +594,7 @@ If you're looking for somewhere to start, check out the [E-easy][eeasy] tag.
 [inom]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AI-nominated
 [eeasy]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy
 [lru]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc
-[rfcbot]: https://github.com/dikaiosune/rust-dashboard/blob/master/RFCBOT.md
+[rfcbot]: https://github.com/anp/rfcbot-rs/
 
 ## Out-of-tree Contributions
 [out-of-tree-contributions]: #out-of-tree-contributions
diff --git a/RELEASES.md b/RELEASES.md
index 64e2145e0f37b..100de005990c9 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,117 @@
+Version 1.25.0 (2018-03-29)
+==========================
+
+Language
+--------
+- [Stabilised `#[repr(align(x))]`.][47006] [RFC 1358]
+- [You can now use nested groups of imports.][47948]
+  e.g. `use std::{fs::File, io::Read, path::{Path, PathBuf}};`
+- [You can now have `|` at the start of a match arm.][47947] e.g.
+```rust
+enum Foo { A, B, C }
+
+fn main() {
+    let x = Foo::A;
+    match x {
+        | Foo::A
+        | Foo::B => println!("AB"),
+        | Foo::C => println!("C"),
+    }
+}
+```
+
+Compiler
+--------
+- [Upgraded to LLVM 6.][47828]
+- [Added `-C lto=val` option.][47521]
+- [Added `i586-unknown-linux-musl` target][47282]
+
+Libraries
+---------
+- [Impl Send for `process::Command` on Unix.][47760]
+- [Impl PartialEq and Eq for `ParseCharError`.][47790]
+- [`UnsafeCell::into_inner` is now safe.][47204]
+- [Implement libstd for CloudABI.][47268]
+- [`Float::{from_bits, to_bits}` is now available in libcore.][46931]
+- [Implement `AsRef<Path>` for Component][46985]
+- [Implemented `Write` for `Cursor<&mut Vec<T>>`][46830]
+- [Moved `Duration` to libcore.][46666]
+
+Stabilized APIs
+---------------
+- [`Location::column`]
+- [`ptr::NonNull`]
+
+The following functions can now be used in a constant expression.
+eg. `static MINUTE: Duration = Duration::from_secs(60);`
+- [`Duration::new`][47300]
+- [`Duration::from_secs`][47300]
+- [`Duration::from_millis`][47300]
+- [`Duration::from_micros`][47300]
+- [`Duration::from_nanos`][47300]
+
+Cargo
+-----
+- [`cargo new` no longer removes `rust` or `rs` prefixs/suffixs.][cargo/5013]
+- [`cargo new` now defaults to creating a binary crate, instead of a
+  library crate.][cargo/5029]
+
+Misc
+----
+- [Rust by example is now shipped with new releases][46196]
+
+Compatibility Notes
+-------------------
+- [Deprecated `net::lookup_host`.][47510]
+- [`rustdoc` has switched to pulldown as the default markdown renderer.][47398]
+- The borrow checker was sometimes incorrectly permitting overlapping borrows
+  around indexing operations (see [#47349][47349]). This has been fixed (which also
+  enabled some correct code that used to cause errors (e.g. [#33903][33903] and [#46095][46095]).
+- [Removed deprecated unstable attribute `#[simd]`.][47251]
+
+[33903]: https://github.com/rust-lang/rust/pull/33903
+[47947]: https://github.com/rust-lang/rust/pull/47947
+[47948]: https://github.com/rust-lang/rust/pull/47948
+[47760]: https://github.com/rust-lang/rust/pull/47760
+[47790]: https://github.com/rust-lang/rust/pull/47790
+[47828]: https://github.com/rust-lang/rust/pull/47828
+[47398]: https://github.com/rust-lang/rust/pull/47398
+[47510]: https://github.com/rust-lang/rust/pull/47510
+[47521]: https://github.com/rust-lang/rust/pull/47521
+[47204]: https://github.com/rust-lang/rust/pull/47204
+[47251]: https://github.com/rust-lang/rust/pull/47251
+[47268]: https://github.com/rust-lang/rust/pull/47268
+[47282]: https://github.com/rust-lang/rust/pull/47282
+[47300]: https://github.com/rust-lang/rust/pull/47300
+[47349]: https://github.com/rust-lang/rust/pull/47349
+[46931]: https://github.com/rust-lang/rust/pull/46931
+[46985]: https://github.com/rust-lang/rust/pull/46985
+[47006]: https://github.com/rust-lang/rust/pull/47006
+[46830]: https://github.com/rust-lang/rust/pull/46830
+[46095]: https://github.com/rust-lang/rust/pull/46095
+[46666]: https://github.com/rust-lang/rust/pull/46666
+[46196]: https://github.com/rust-lang/rust/pull/46196
+[cargo/5013]: https://github.com/rust-lang/cargo/pull/5013
+[cargo/5029]: https://github.com/rust-lang/cargo/pull/5029
+[RFC 1358]: https://github.com/rust-lang/rfcs/pull/1358
+[`Location::column`]: https://doc.rust-lang.org/std/panic/struct.Location.html#method.column
+[`ptr::NonNull`]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html
+
+
+Version 1.24.1 (2018-03-01)
+==========================
+
+ - [Do not abort when unwinding through FFI][48251]
+ - [Emit UTF-16 files for linker arguments on Windows][48318]
+ - [Make the error index generator work again][48308]
+ - [Cargo will warn on Windows 7 if an update is needed][cargo/5069].
+
+[48251]: https://github.com/rust-lang/rust/issues/48251
+[48308]: https://github.com/rust-lang/rust/issues/48308
+[48318]: https://github.com/rust-lang/rust/issues/48318
+[cargo/5069]: https://github.com/rust-lang/cargo/pull/5069
+
+
 Version 1.24.0 (2018-02-15)
 ==========================
 
diff --git a/appveyor.yml b/appveyor.yml
index 45e1b4b90d6c7..54c15f662e13e 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -20,10 +20,10 @@ environment:
     SCRIPT: python x.py test
   - MSYS_BITS: 32
     RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
-    SCRIPT: python x.py test --exclude src/test/run-pass --exclude src/test/compile-fail
+    SCRIPT: make appveyor-subset-1
   - MSYS_BITS: 32
     RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
-    SCRIPT: python x.py test src/test/run-pass src/test/compile-fail
+    SCRIPT: make appveyor-subset-2
 
   # MSVC aux tests
   - MSYS_BITS: 64
@@ -53,13 +53,13 @@ environment:
   # SourceForge is notoriously flaky, so we mirror it on our own infrastructure.
   - MSYS_BITS: 32
     RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
-    SCRIPT: python x.py test --exclude src/test/run-pass --exclude src/test/compile-fail
+    SCRIPT: make appveyor-subset-1
     MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
     MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
     MINGW_DIR: mingw32
   - MSYS_BITS: 32
     RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
-    SCRIPT: python x.py test src/test/run-pass src/test/compile-fail
+    SCRIPT: make appveyor-subset-2
     MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
     MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
     MINGW_DIR: mingw32
diff --git a/config.toml.example b/config.toml.example
index aec5e5a0e2c80..9dd3002506e41 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -186,6 +186,10 @@
 # essentially skipping stage0 as the local compiler is recompiling itself again.
 #local-rebuild = false
 
+# Print out how long each rustbuild step took (mostly intended for CI and
+# tracking over time)
+#print-step-timings = false
+
 # =============================================================================
 # General install configuration options
 # =============================================================================
@@ -243,11 +247,6 @@
 # compiler.
 #codegen-units = 1
 
-# Whether to enable ThinLTO (and increase the codegen units to either a default
-# or the configured value). On by default. If we want the fastest possible
-# compiler, we should disable this.
-#thinlto = true
-
 # Whether or not debug assertions are enabled for the compiler and standard
 # library. Also enables compilation of debug! and trace! logging macros.
 #debug-assertions = false
@@ -272,6 +271,9 @@
 # Whether or not `panic!`s generate backtraces (RUST_BACKTRACE)
 #backtrace = true
 
+# Build rustc with experimental parallelization
+#experimental-parallel-queries = false
+
 # The default linker that will be hard-coded into the generated compiler for
 # targets that don't specify linker explicitly in their target specifications.
 # Note that this is not the linker used to link said compiler.
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 5c912ef6d1f43..8ace51ddac2b5 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -1,20 +1,3 @@
-[[package]]
-name = "advapi32-sys"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi 0.2.8 (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 = "aho-corasick"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "aho-corasick"
 version = "0.6.4"
@@ -39,7 +22,7 @@ dependencies = [
  "alloc 0.0.0",
  "alloc_system 0.0.0",
  "build_helper 0.1.0",
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "libc 0.0.0",
 ]
@@ -56,8 +39,11 @@ dependencies = [
 
 [[package]]
 name = "ansi_term"
-version = "0.10.2"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
 
 [[package]]
 name = "ar"
@@ -81,7 +67,7 @@ name = "atty"
 version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -93,7 +79,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -103,8 +89,8 @@ name = "backtrace-sys"
 version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -131,16 +117,16 @@ name = "bootstrap"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -158,8 +144,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "build-manifest"
 version = "0.1.0"
 dependencies = [
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -181,42 +167,42 @@ version = "0.27.0"
 dependencies = [
  "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "crates-io 0.16.0",
  "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "git2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "git2-curl 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "home 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -227,21 +213,9 @@ name = "cargo_metadata"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "cargo_metadata"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -251,9 +225,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -262,7 +236,7 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.0.6"
+version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -281,13 +255,13 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "2.29.0"
+version = "2.31.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -296,18 +270,18 @@ dependencies = [
 
 [[package]]
 name = "clippy"
-version = "0.0.188"
+version = "0.0.189"
 dependencies = [
  "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "clippy-mini-macro-test 0.2.0",
- "clippy_lints 0.0.188",
+ "clippy_lints 0.0.189",
  "compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -316,7 +290,7 @@ version = "0.2.0"
 
 [[package]]
 name = "clippy_lints"
-version = "0.0.188"
+version = "0.0.189"
 dependencies = [
  "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -324,10 +298,10 @@ dependencies = [
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -338,7 +312,7 @@ name = "cmake"
 version = "0.1.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -354,14 +328,14 @@ name = "commoncrypto-sys"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "compiler_builtins"
 version = "0.0.0"
 dependencies = [
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -370,16 +344,16 @@ name = "compiletest"
 version = "0.0.0"
 dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -391,13 +365,13 @@ dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -418,7 +392,7 @@ version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -426,7 +400,7 @@ name = "core-foundation-sys"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -435,9 +409,9 @@ version = "0.16.0"
 dependencies = [
  "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -495,11 +469,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "socket2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "socket2 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -508,8 +482,8 @@ name = "curl-sys"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -544,18 +518,6 @@ dependencies = [
  "core 0.0.0",
 ]
 
-[[package]]
-name = "docopt"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "dtoa"
 version = "0.4.2"
@@ -589,32 +551,14 @@ dependencies = [
 
 [[package]]
 name = "env_logger"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "env_logger"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "env_logger"
-version = "0.5.5"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -661,7 +605,7 @@ version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -678,7 +622,7 @@ name = "flate2"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -709,7 +653,7 @@ name = "fs2"
 version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -739,12 +683,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "git2"
-version = "0.7.0"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -752,12 +697,12 @@ dependencies = [
 
 [[package]]
 name = "git2-curl"
-version = "0.8.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "git2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -775,7 +720,7 @@ dependencies = [
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -791,9 +736,9 @@ dependencies = [
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -803,14 +748,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "home"
-version = "0.3.0"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -846,7 +789,7 @@ dependencies = [
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -869,7 +812,7 @@ version = "0.1.0"
 name = "installer"
 version = "0.0.0"
 dependencies = [
- "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -895,15 +838,15 @@ dependencies = [
 
 [[package]]
 name = "itoa"
-version = "0.3.4"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "jobserver"
-version = "0.1.10"
+version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -920,9 +863,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -940,9 +883,9 @@ version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -971,7 +914,7 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.39"
+version = "0.2.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -979,10 +922,10 @@ name = "libgit2-sys"
 version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -995,7 +938,7 @@ version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1006,8 +949,8 @@ name = "libz-sys"
 version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1045,9 +988,9 @@ name = "lzma-sys"
 version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1062,8 +1005,8 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1072,30 +1015,22 @@ dependencies = [
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "memchr"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "memchr"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1108,8 +1043,8 @@ name = "miniz-sys"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1117,7 +1052,7 @@ name = "miow"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "socket2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "socket2 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1129,7 +1064,7 @@ dependencies = [
  "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1153,7 +1088,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1161,7 +1096,7 @@ name = "num-integer"
 version = "0.1.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1170,7 +1105,7 @@ version = "0.1.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1178,12 +1113,12 @@ name = "num-traits"
 version = "0.1.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1191,7 +1126,7 @@ name = "num_cpus"
 version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1207,7 +1142,7 @@ dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1221,8 +1156,8 @@ name = "openssl-sys"
 version = "0.9.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1267,7 +1202,7 @@ name = "parking_lot_core"
 version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1310,7 +1245,7 @@ dependencies = [
 name = "profiler_builtins"
 version = "0.0.0"
 dependencies = [
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -1348,13 +1283,13 @@ dependencies = [
 
 [[package]]
 name = "racer"
-version = "2.0.12"
+version = "2.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1375,7 +1310,7 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1395,7 +1330,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1423,36 +1358,19 @@ version = "0.1.0"
 
 [[package]]
 name = "regex"
-version = "0.1.80"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "regex"
-version = "0.2.7"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "regex-syntax"
-version = "0.5.0"
+version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1468,11 +1386,10 @@ version = "0.1.0"
 
 [[package]]
 name = "remove_dir_all"
-version = "0.3.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1481,8 +1398,8 @@ version = "0.126.0"
 dependencies = [
  "cargo 0.27.0",
  "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "clippy_lints 0.0.188",
- "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clippy_lints 0.0.189",
+ "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1490,7 +1407,7 @@ dependencies = [
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1498,10 +1415,10 @@ dependencies = [
  "rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfmt-nightly 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustfmt-nightly 0.4.1",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1530,8 +1447,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1545,8 +1462,8 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1554,7 +1471,7 @@ name = "rls-vfs"
 version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1562,7 +1479,7 @@ dependencies = [
 name = "rustbook"
 version = "0.1.0"
 dependencies = [
- "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "mdbook 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1577,7 +1494,7 @@ dependencies = [
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fmt_macros 0.0.0",
  "graphviz 0.0.0",
- "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
@@ -1589,11 +1506,12 @@ dependencies = [
  "serialize 0.0.0",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
+ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_cratesio_shim"
-version = "29.0.0"
+version = "73.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1602,57 +1520,62 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "29.0.0"
+version = "73.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "29.0.0"
+version = "73.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "29.0.0"
+version = "73.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc-ap-syntax"
-version = "29.0.0"
+version = "73.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-syntax_pos"
-version = "29.0.0"
+version = "73.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1763,7 +1686,7 @@ version = "0.0.0"
 dependencies = [
  "ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "arena 0.0.0",
- "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -1798,7 +1721,7 @@ dependencies = [
  "rustc_data_structures 0.0.0",
  "serialize 0.0.0",
  "syntax_pos 0.0.0",
- "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1833,8 +1756,8 @@ version = "0.0.0"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "build_helper 0.1.0",
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
 ]
 
@@ -1984,11 +1907,11 @@ name = "rustc_trans"
 version = "0.0.0"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -2007,7 +1930,7 @@ dependencies = [
  "serialize 0.0.0",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
- "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2058,7 +1981,7 @@ name = "rustdoc"
 version = "0.0.0"
 dependencies = [
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2074,52 +1997,26 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-nightly"
-version = "0.3.8"
+version = "0.4.1"
 dependencies = [
- "cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "rustfmt-nightly"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2144,32 +2041,18 @@ name = "scoped-tls"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "scopeguard"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "scopeguard"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "semver"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "semver"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2179,23 +2062,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
-version = "1.0.29"
+version = "1.0.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde_derive"
-version = "1.0.29"
+version = "1.0.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive_internals 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_derive_internals"
-version = "0.20.0"
+version = "0.22.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2207,18 +2090,18 @@ name = "serde_ignored"
 version = "0.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.10"
+version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2242,11 +2125,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "socket2"
-version = "0.3.3"
+version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2287,7 +2170,7 @@ dependencies = [
 
 [[package]]
 name = "strsim"
-version = "0.6.0"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -2368,7 +2251,7 @@ name = "syntex_errors"
 version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2390,7 +2273,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2405,18 +2288,18 @@ version = "0.4.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "tempdir"
-version = "0.3.6"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2432,9 +2315,18 @@ dependencies = [
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "term"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "termcolor"
-version = "0.3.5"
+version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2445,7 +2337,7 @@ name = "termion"
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2466,23 +2358,6 @@ dependencies = [
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "thread-id"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "thread_local"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "thread_local"
 version = "0.3.5"
@@ -2496,9 +2371,9 @@ dependencies = [
 name = "tidy"
 version = "0.1.0"
 dependencies = [
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2506,7 +2381,7 @@ name = "time"
 version = "0.1.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2524,7 +2399,7 @@ name = "toml"
 version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2535,7 +2410,7 @@ dependencies = [
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2594,6 +2469,7 @@ dependencies = [
 name = "unstable-book-gen"
 version = "0.1.0"
 dependencies = [
+ "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "tidy 0.1.0",
 ]
 
@@ -2620,7 +2496,7 @@ name = "url_serde"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2633,11 +2509,6 @@ dependencies = [
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "utf8-ranges"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "utf8-ranges"
 version = "1.0.0"
@@ -2713,7 +2584,7 @@ name = "xattr"
 version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2730,10 +2601,8 @@ version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
-"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a"
-"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
 "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
-"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
+"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
 "checksum ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35c7a5669cb64f085739387e1308b74e6d44022464b7f1b63bbd4ceb6379ec31"
 "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
 "checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4"
@@ -2745,12 +2614,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
 "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
 "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b"
-"checksum cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20d6fb2b5574726329c85cdba0df0347fddfec3cf9c8b588f9931708280f5643"
 "checksum cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5caae26de3704081ef638f87f05a6891b04f2b7d5ce9429a3de21095528ae22"
-"checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49"
+"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
 "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9"
-"checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f"
+"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
 "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb"
 "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007"
 "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2"
@@ -2766,15 +2634,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46e49c7125131f5afaded06944d6888b55cbdf8eba05dae73c954019b907961"
 "checksum derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "92f8b8e1d6c8a5f5ea0849a0e4c55941576115c62d3fc425e96918bbbeb3d3c2"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
-"checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3"
 "checksum ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b449f3b18c89d2dbe40548d2ee4fa58ea0a08b761992da6ecb9788e4688834"
 "checksum endian-type 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
 "checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
-"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
-"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
-"checksum env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0628f04f7c26ebccf40d7fc2c1cf92236c05ec88cf2132641cc956812312f0f"
+"checksum env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0561146661ae44c579e993456bc76d11ce1e0c7d745e57b2fa7146b6e49fa2ad"
 "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
 "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
 "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
@@ -2788,21 +2653,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1"
 "checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9"
-"checksum git2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4813cd7ad02e53275e6e51aaaf21c30f9ef500b579ad7a54a92f6091a7ac296"
-"checksum git2-curl 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27245f4c3a65ab19fd1ab5b52659bd60ed0ce8d0d129202c4737044d1d21db29"
+"checksum git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f41c0035c37ec11ed3f1e1946a76070b0c740393687e9a9c7612f6a709036b3"
+"checksum git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b502f6b1b467957403d168f0039e0c46fa6a1220efa2adaef25d5b267b5fe024"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
 "checksum globset 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e96ab92362c06811385ae9a34d2698e8a1160745e0c78fbb434a44c8de3fabc"
 "checksum handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04af2006ea09d985fef82b81e0eb25337e51b691c76403332378a53d521edc"
 "checksum hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "459d3cf58137bb02ad4adeef5036377ff59f066dbb82517b7192e3a5462a2abc"
-"checksum home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f25ae61099d8f3fee8b483df0bd4ecccf4b2731897aad40d50eca1b641fe6db"
+"checksum home 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f94f6fbdc000a6eba0c8cf08632b2091bb59141d36ac321a2a96d6365e5e4dc"
 "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
 "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8"
 "checksum ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "245bea0ba52531a3739cb8ba99f8689eda13d7faf8c36b6a73ce4421aab42588"
 "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053"
 "checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394"
-"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
-"checksum jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2abd9fd3242accb0e2e30986f2cf30cda3e19eec5cc6d584b218ce2b1c0e3c"
+"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
+"checksum jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "60af5f849e1981434e4a31d3d782c4774ae9b434ce55b101a96ecfd09147e8be"
 "checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483"
 "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
@@ -2810,7 +2675,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
 "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
 "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
-"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff"
+"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
 "checksum libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecbd6428006c321c29b6c8a895f0d90152f1cf4fd8faab69fc436a3d9594f63"
 "checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75"
 "checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16"
@@ -2820,7 +2685,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c1b93b78f89e8737dac81837fc8f5521ac162abcba902e1a3db949d55346d1da"
 "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
 "checksum mdbook 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fef236caad7ba3b5b3944df946f19ab3e190bca53c111dd00fe05fa8d879f2fd"
-"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
 "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
@@ -2831,7 +2695,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe"
 "checksum num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "4b226df12c5a59b63569dd57fafb926d91b385dfce33d8074a412411b689d593"
 "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
-"checksum num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3c2bd9b9d21e48e956b763c9f37134dc62d9e95da6edb3f672cacb6caf3cd3"
+"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364"
 "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
 "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113"
 "checksum openssl 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1636c9f1d78af9cbcc50e523bfff4a30274108aad5e86761afd4d31e4e184fa7"
@@ -2849,52 +2713,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
-"checksum racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "034f1c4528581c40a60e96875467c03315868084e08ff4ceb46a00f7be3b16b4"
+"checksum racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "40d44bc30fc8d403b665286b2c9a83466ddbf69297668fb02b785c3e58eb8e0d"
 "checksum radix_trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "211c49b6a9995cac0fd1dd9ca60b42cf3a51e151a12eb954b3a9e75513426ee8"
 "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
 "checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d"
 "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
 "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
-"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
-"checksum regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a62bf8bb734ab90b7f234b681b01af396e5d39b028906c210dc04fa1d5e9e5b3"
-"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
-"checksum regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48d7391e7e90e06eaf3aefbe4652464153ecfec64806f3bf77ffc59638a63e77"
-"checksum remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d2f806b0fcdabd98acd380dc8daef485e22bcb7cddc811d1337967f2528cf5"
+"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb"
+"checksum regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b2550876c31dc914696a6c2e01cbce8afba79a93c8ae979d2fe051c0230b3756"
+"checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24"
 "checksum rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4b9a3a3f2345854e39768e6425d1c893855da217183d1c0b3ff6f1664b6b6d"
 "checksum rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56fb7b8e4850b988fbcf277fbdb1eff36879070d02fc1ca243b559273866973d"
 "checksum rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bea04462e94b5512a78499837eecb7db182ff082144cd1b4bc32ef5d43de6510"
 "checksum rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "885f66b92757420572cbb02e033d4a9558c7413ca9b7ac206f28fd58ffdb44ea"
 "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a"
 "checksum rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be231e1e559c315bc60ced5ad2cc2d7a9c208ed7d4e2c126500149836fda19bb"
-"checksum rustc-ap-rustc_cratesio_shim 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ad5e562044ea78a6764dd75ae8afe4b21fde49f4548024b5fdf6345c21fb524"
-"checksum rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c0d65325492aba7db72899e3edbab34d39af98c42ab7c7e450c9a288ffe4ad"
-"checksum rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87d4ab2e06a671b5b5c5b0359dac346f164c99d059dce6a22feb08f2f56bd182"
-"checksum rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0745fa445ff41c4b6699936cf35ce3ca49502377dd7b3929c829594772c3a7b"
-"checksum rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82efedabe30f393161e11214a9130edfa01ad476372d1c6f3fec1f8d30488c9d"
-"checksum rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9de2e927e280c75b8efab9c5f591ad31082d5d2c4c562c68fdba2ee77286b0"
+"checksum rustc-ap-rustc_cratesio_shim 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "421262e22426c06306e46057a75048f883dbc43886f78dbe1e750397a9c9b8e6"
+"checksum rustc-ap-rustc_data_structures 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8460c1207f9abb48a9720aee8be418bcfac018b6eee7b740b98a410e7799d24a"
+"checksum rustc-ap-rustc_errors 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad2077469162e52fcd84543334e18632088b9e342fe54e3b78c37d7077d09714"
+"checksum rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "69943901ae255dca5f63faeae2ff08b402d34a56d1eb50d34fbff6e83e6ace60"
+"checksum rustc-ap-syntax 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a44363359a43df753e26a4d4fef72720af183de635ebae8699686cb5d5de813"
+"checksum rustc-ap-syntax_pos 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "413f464657e8d5f3864de308dba1867526f21a44809b6f338b34e8c0caf88fb0"
 "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
-"checksum rustfmt-nightly 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "554256054eae37ead2f799ffa9cf8be8249496c6c3cf005c28b7cfa55f4efaa5"
 "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
 "checksum schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fbaffce35eb61c5b00846e73128b0cd62717e7c0ec46abbec132370d013975b4"
 "checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4"
-"checksum scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59a076157c1e2dc561d8de585151ee6965d910dd4dcb5dabb7ae3e83981a6c57"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
-"checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4763b773978e495252615e814d2ad04773b2c1f85421c7913869a537f35cb406"
-"checksum serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "8ab31f00ae5574bb643c196d5e302961c122da1c768604c6d16a35c5d551948a"
-"checksum serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc848d073be32cd982380c06587ea1d433bc1a4c4a111de07ec2286a3ddade8"
+"checksum serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "800fdb0a894572994f3970035a8a5f65d8ec2cd40e6cdf7d8cd9001d7b30648e"
+"checksum serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "90f1f8f7784452461db5b73dc5097c18f21011fbcc6d1178f1897bfa8e1cb4bd"
+"checksum serde_derive_internals 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f9525ada08124ee1a9b8b1e6f3bf035ffff6fc0c96d56ddda98d4506d3533e4"
 "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142"
-"checksum serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57781ed845b8e742fc2bf306aba8e3b408fe8c366b900e3769fbc39f49eb8b39"
+"checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74"
 "checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8"
 "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
 "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
-"checksum socket2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78e4c1cde1adbc6bc4c394da2e7727c916b9b7d0b53d6984c890c65c1f4e6437"
+"checksum socket2 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "71ebbe82fcdd697244ba7fe6e05e63b5c45910c3927e28469a04947494ff48d8"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
-"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
+"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8c5bc2d6ff27891209efa5f63e9de78648d7801f085e4653701a692ce938d6fd"
 "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
@@ -2903,13 +2762,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "955ef4b16af4c468e4680d1497f873ff288f557d338180649e18f915af5e15ac"
 "checksum syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76a302e717e348aa372ff577791c3832395650073b8d8432f8b3cb170b34afde"
 "checksum tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1605d3388ceb50252952ffebab4b5dc43017ead7e4481b175961c283bb951195"
-"checksum tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f73eebdb68c14bcb24aef74ea96079830e7fa7b31a6106e42ea7ee887c1e134e"
+"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
 "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
-"checksum termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "56c456352e44f9f91f774ddeeed27c1ec60a2455ed66d692059acfb1d731bda1"
+"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
+"checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
 "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
-"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
-"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
 "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
 "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
 "checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4"
@@ -2927,7 +2785,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7"
 "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"
 "checksum userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d28ea36bbd9192d75bd9fa9b39f96ddb986eaee824adae5d53b6e51919b2f3"
-"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
 "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"
 "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 4be16475590f4..6701f58ba8e92 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -31,9 +31,11 @@ extern crate bootstrap;
 
 use std::env;
 use std::ffi::OsString;
-use std::str::FromStr;
+use std::io;
 use std::path::PathBuf;
-use std::process::{Command, ExitStatus};
+use std::process::Command;
+use std::str::FromStr;
+use std::time::Instant;
 
 fn main() {
     let mut args = env::args_os().skip(1).collect::<Vec<_>>();
@@ -90,7 +92,7 @@ fn main() {
     };
     let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
     let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
-    let mut on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of));
+    let on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of));
 
     let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc));
     let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir));
@@ -103,6 +105,7 @@ fn main() {
         .arg(format!("stage{}", stage))
         .env(bootstrap::util::dylib_path_var(),
              env::join_paths(&dylib_path).unwrap());
+    let mut maybe_crate = None;
 
     if let Some(target) = target {
         // The stage0 compiler has a special sysroot distinct from what we
@@ -134,6 +137,7 @@ fn main() {
             .find(|a| &*a[0] == "--crate-name")
             .unwrap();
         let crate_name = &*crate_name[1];
+        maybe_crate = Some(crate_name);
 
         // If we're compiling specifically the `panic_abort` crate then we pass
         // the `-C panic=abort` option. Note that we do not do this for any
@@ -281,31 +285,52 @@ fn main() {
         eprintln!("libdir: {:?}", libdir);
     }
 
-    // Actually run the compiler!
-    std::process::exit(if let Some(ref mut on_fail) = on_fail {
-        match cmd.status() {
-            Ok(s) if s.success() => 0,
-            _ => {
-                println!("\nDid not run successfully:\n{:?}\n-------------", cmd);
-                exec_cmd(on_fail).expect("could not run the backup command");
-                1
+    if let Some(mut on_fail) = on_fail {
+        let e = match cmd.status() {
+            Ok(s) if s.success() => std::process::exit(0),
+            e => e,
+        };
+        println!("\nDid not run successfully: {:?}\n{:?}\n-------------", e, cmd);
+        exec_cmd(&mut on_fail).expect("could not run the backup command");
+        std::process::exit(1);
+    }
+
+    if env::var_os("RUSTC_PRINT_STEP_TIMINGS").is_some() {
+        if let Some(krate) = maybe_crate {
+            let start = Instant::now();
+            let status = cmd
+                .status()
+                .expect(&format!("\n\n failed to run {:?}", cmd));
+            let dur = start.elapsed();
+
+            let is_test = args.iter().any(|a| a == "--test");
+            eprintln!("[RUSTC-TIMING] {} test:{} {}.{:03}",
+                      krate.to_string_lossy(),
+                      is_test,
+                      dur.as_secs(),
+                      dur.subsec_nanos() / 1_000_000);
+
+            match status.code() {
+                Some(i) => std::process::exit(i),
+                None => {
+                    eprintln!("rustc exited with {}", status);
+                    std::process::exit(0xfe);
+                }
             }
         }
-    } else {
-        std::process::exit(match exec_cmd(&mut cmd) {
-            Ok(s) => s.code().unwrap_or(0xfe),
-            Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e),
-        })
-    })
+    }
+
+    let code = exec_cmd(&mut cmd).expect(&format!("\n\n failed to run {:?}", cmd));
+    std::process::exit(code);
 }
 
 #[cfg(unix)]
-fn exec_cmd(cmd: &mut Command) -> ::std::io::Result<ExitStatus> {
+fn exec_cmd(cmd: &mut Command) -> io::Result<i32> {
     use std::os::unix::process::CommandExt;
     Err(cmd.exec())
 }
 
 #[cfg(not(unix))]
-fn exec_cmd(cmd: &mut Command) -> ::std::io::Result<ExitStatus> {
-    cmd.status()
+fn exec_cmd(cmd: &mut Command) -> io::Result<i32> {
+    cmd.status().map(|status| status.code().unwrap())
 }
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 675d3dd437eef..eb23236638b13 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::any::Any;
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
 use std::collections::BTreeSet;
 use std::env;
 use std::fmt::Debug;
@@ -18,6 +18,7 @@ use std::hash::Hash;
 use std::ops::Deref;
 use std::path::{Path, PathBuf};
 use std::process::Command;
+use std::time::{Instant, Duration};
 
 use compile;
 use install;
@@ -40,6 +41,7 @@ pub struct Builder<'a> {
     pub kind: Kind,
     cache: Cache,
     stack: RefCell<Vec<Box<Any>>>,
+    time_spent_on_dependencies: Cell<Duration>,
 }
 
 impl<'a> Deref for Builder<'a> {
@@ -308,19 +310,24 @@ impl<'a> Builder<'a> {
                 test::UiFullDeps, test::RunPassFullDeps, test::RunFailFullDeps,
                 test::CompileFailFullDeps, test::IncrementalFullDeps, test::Rustdoc, test::Pretty,
                 test::RunPassPretty, test::RunFailPretty, test::RunPassValgrindPretty,
-                test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::RunMake,
+                test::RunPassFullDepsPretty, test::RunFailFullDepsPretty,
                 test::Crate, test::CrateLibrustc, test::CrateRustdoc, test::Linkcheck,
                 test::Cargotest, test::Cargo, test::Rls, test::ErrorIndex, test::Distcheck,
+                test::RunMakeFullDeps,
                 test::Nomicon, test::Reference, test::RustdocBook, test::RustByExample,
                 test::TheBook, test::UnstableBook,
-                test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme),
+                test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme,
+                // Run run-make last, since these won't pass without make on Windows
+                test::RunMake),
             Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
             Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
-                doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon,
-                doc::Reference, doc::Rustdoc, doc::RustByExample, doc::CargoBook),
-            Kind::Dist => describe!(dist::Docs, dist::Mingw, dist::Rustc, dist::DebuggerScripts,
-                dist::Std, dist::Analysis, dist::Src, dist::PlainSourceTarball, dist::Cargo,
-                dist::Rls, dist::Rustfmt, dist::Extended, dist::HashSign),
+                doc::Standalone, doc::Std, doc::Test, doc::WhitelistedRustc, doc::Rustc,
+                doc::ErrorIndex, doc::Nomicon, doc::Reference, doc::Rustdoc, doc::RustByExample,
+                doc::CargoBook),
+            Kind::Dist => describe!(dist::Docs, dist::RustcDocs, dist::Mingw, dist::Rustc,
+                dist::DebuggerScripts, dist::Std, dist::Analysis, dist::Src,
+                dist::PlainSourceTarball, dist::Cargo, dist::Rls, dist::Rustfmt, dist::Extended,
+                dist::HashSign),
             Kind::Install => describe!(install::Docs, install::Std, install::Cargo, install::Rls,
                 install::Rustfmt, install::Analysis, install::Src, install::Rustc),
         }
@@ -343,6 +350,7 @@ impl<'a> Builder<'a> {
             kind,
             cache: Cache::new(),
             stack: RefCell::new(Vec::new()),
+            time_spent_on_dependencies: Cell::new(Duration::new(0, 0)),
         };
 
         let builder = &builder;
@@ -383,6 +391,7 @@ impl<'a> Builder<'a> {
             kind,
             cache: Cache::new(),
             stack: RefCell::new(Vec::new()),
+            time_spent_on_dependencies: Cell::new(Duration::new(0, 0)),
         };
 
         if kind == Kind::Dist {
@@ -662,6 +671,10 @@ impl<'a> Builder<'a> {
             cargo.env("RUSTC_ON_FAIL", on_fail);
         }
 
+        if self.config.print_step_timings {
+            cargo.env("RUSTC_PRINT_STEP_TIMINGS", "1");
+        }
+
         cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity));
 
         // Throughout the build Cargo can execute a number of build scripts
@@ -818,7 +831,24 @@ impl<'a> Builder<'a> {
             self.build.verbose(&format!("{}> {:?}", "  ".repeat(stack.len()), step));
             stack.push(Box::new(step.clone()));
         }
-        let out = step.clone().run(self);
+
+        let (out, dur) = {
+            let start = Instant::now();
+            let zero = Duration::new(0, 0);
+            let parent = self.time_spent_on_dependencies.replace(zero);
+            let out = step.clone().run(self);
+            let dur = start.elapsed();
+            let deps = self.time_spent_on_dependencies.replace(parent + dur);
+            (out, dur - deps)
+        };
+
+        if self.build.config.print_step_timings && dur > Duration::from_millis(100) {
+            println!("[TIMING] {:?} -- {}.{:03}",
+                     step,
+                     dur.as_secs(),
+                     dur.subsec_nanos() / 1_000_000);
+        }
+
         {
             let mut stack = self.stack.borrow_mut();
             let cur_step = stack.pop().expect("step stack empty");
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 33bcfaa80ca31..a9dccea827b6e 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -40,17 +40,18 @@ impl Step for Std {
         let target = self.target;
         let compiler = builder.compiler(0, build.build);
 
-        let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage));
-        println!("Checking std artifacts ({} -> {})", &compiler.host, target);
-
         let out_dir = build.stage_out(compiler, Mode::Libstd);
         build.clear_if_dirty(&out_dir, &builder.rustc(compiler));
         let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "check");
         std_cargo(builder, &compiler, target, &mut cargo);
+
+        let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage));
+        println!("Checking std artifacts ({} -> {})", &compiler.host, target);
         run_cargo(build,
                   &mut cargo,
                   &libstd_stamp(build, compiler, target),
                   true);
+
         let libdir = builder.sysroot_libdir(compiler, target);
         add_to_sysroot(&libdir, &libstd_stamp(build, compiler, target));
     }
@@ -86,19 +87,20 @@ impl Step for Rustc {
         let compiler = builder.compiler(0, build.build);
         let target = self.target;
 
-        let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage));
-        println!("Checking compiler artifacts ({} -> {})", &compiler.host, target);
-
         let stage_out = builder.stage_out(compiler, Mode::Librustc);
         build.clear_if_dirty(&stage_out, &libstd_stamp(build, compiler, target));
         build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target));
 
         let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check");
         rustc_cargo(build, &mut cargo);
+
+        let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage));
+        println!("Checking compiler artifacts ({} -> {})", &compiler.host, target);
         run_cargo(build,
                   &mut cargo,
                   &librustc_stamp(build, compiler, target),
                   true);
+
         let libdir = builder.sysroot_libdir(compiler, target);
         add_to_sysroot(&libdir, &librustc_stamp(build, compiler, target));
     }
@@ -128,16 +130,18 @@ impl Step for Test {
         let target = self.target;
         let compiler = builder.compiler(0, build.build);
 
-        let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
-        println!("Checking test artifacts ({} -> {})", &compiler.host, target);
         let out_dir = build.stage_out(compiler, Mode::Libtest);
         build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target));
         let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "check");
         test_cargo(build, &compiler, target, &mut cargo);
+
+        let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
+        println!("Checking test artifacts ({} -> {})", &compiler.host, target);
         run_cargo(build,
                   &mut cargo,
                   &libtest_stamp(build, compiler, target),
                   true);
+
         let libdir = builder.sysroot_libdir(compiler, target);
         add_to_sysroot(&libdir, &libtest_stamp(build, compiler, target));
     }
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 86263c8fa0733..9f33935b6e933 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -16,6 +16,7 @@
 //! compiler. This module is also responsible for assembling the sysroot as it
 //! goes along from the output of the previous stage.
 
+use std::borrow::Cow;
 use std::env;
 use std::fs::{self, File};
 use std::io::BufReader;
@@ -93,19 +94,19 @@ impl Step for Std {
             return;
         }
 
-        let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage));
-        println!("Building stage{} std artifacts ({} -> {})", compiler.stage,
-                &compiler.host, target);
-
         if target.contains("musl") {
             let libdir = builder.sysroot_libdir(compiler, target);
             copy_musl_third_party_objects(build, target, &libdir);
         }
 
-        let out_dir = build.stage_out(compiler, Mode::Libstd);
+        let out_dir = build.cargo_out(compiler, Mode::Libstd, target);
         build.clear_if_dirty(&out_dir, &builder.rustc(compiler));
         let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build");
         std_cargo(builder, &compiler, target, &mut cargo);
+
+        let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage));
+        println!("Building stage{} std artifacts ({} -> {})", compiler.stage,
+                &compiler.host, target);
         run_cargo(build,
                   &mut cargo,
                   &libstd_stamp(build, compiler, target),
@@ -360,13 +361,14 @@ impl Step for Test {
             return;
         }
 
-        let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
-        println!("Building stage{} test artifacts ({} -> {})", compiler.stage,
-                &compiler.host, target);
-        let out_dir = build.stage_out(compiler, Mode::Libtest);
+        let out_dir = build.cargo_out(compiler, Mode::Libtest, target);
         build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target));
         let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "build");
         test_cargo(build, &compiler, target, &mut cargo);
+
+        let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
+        println!("Building stage{} test artifacts ({} -> {})", compiler.stage,
+                &compiler.host, target);
         run_cargo(build,
                   &mut cargo,
                   &libtest_stamp(build, compiler, target),
@@ -481,17 +483,16 @@ impl Step for Rustc {
             compiler: builder.compiler(self.compiler.stage, build.build),
             target: build.build,
         });
+        let cargo_out = builder.cargo_out(compiler, Mode::Librustc, target);
+        build.clear_if_dirty(&cargo_out, &libstd_stamp(build, compiler, target));
+        build.clear_if_dirty(&cargo_out, &libtest_stamp(build, compiler, target));
+
+        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
+        rustc_cargo(build, &mut cargo);
 
         let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage));
         println!("Building stage{} compiler artifacts ({} -> {})",
                  compiler.stage, &compiler.host, target);
-
-        let stage_out = builder.stage_out(compiler, Mode::Librustc);
-        build.clear_if_dirty(&stage_out, &libstd_stamp(build, compiler, target));
-        build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target));
-
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
-        rustc_cargo(build, &mut cargo);
         run_cargo(build,
                   &mut cargo,
                   &librustc_stamp(build, compiler, target),
@@ -634,8 +635,6 @@ impl Step for CodegenBackend {
             .arg(build.src.join("src/librustc_trans/Cargo.toml"));
         rustc_cargo_env(build, &mut cargo);
 
-        let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage));
-
         match &*self.backend {
             "llvm" | "emscripten" => {
                 // Build LLVM for our target. This will implicitly build the
@@ -685,6 +684,8 @@ impl Step for CodegenBackend {
 
         let tmp_stamp = build.cargo_out(compiler, Mode::Librustc, target)
             .join(".tmp.stamp");
+
+        let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage));
         let files = run_cargo(build,
                               cargo.arg("--features").arg(features),
                               &tmp_stamp,
@@ -915,7 +916,7 @@ impl Step for Assemble {
             }
         }
 
-        let lld_install = if build.config.lld_enabled && target_compiler.stage > 0 {
+        let lld_install = if build.config.lld_enabled {
             Some(builder.ensure(native::Lld {
                 target: target_compiler.host,
             }))
@@ -996,24 +997,6 @@ fn stderr_isatty() -> bool {
 pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: bool)
     -> Vec<PathBuf>
 {
-    // Instruct Cargo to give us json messages on stdout, critically leaving
-    // stderr as piped so we can get those pretty colors.
-    cargo.arg("--message-format").arg("json")
-         .stdout(Stdio::piped());
-
-    if stderr_isatty() && build.ci_env == CiEnv::None {
-        // since we pass message-format=json to cargo, we need to tell the rustc
-        // wrapper to give us colored output if necessary. This is because we
-        // only want Cargo's JSON output, not rustcs.
-        cargo.env("RUSTC_COLOR", "1");
-    }
-
-    build.verbose(&format!("running: {:?}", cargo));
-    let mut child = match cargo.spawn() {
-        Ok(child) => child,
-        Err(e) => panic!("failed to execute command: {:?}\nerror: {}", cargo, e),
-    };
-
     // `target_root_dir` looks like $dir/$target/release
     let target_root_dir = stamp.parent().unwrap();
     // `target_deps_dir` looks like $dir/$target/release/deps
@@ -1028,46 +1011,33 @@ pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: boo
     // files we need to probe for later.
     let mut deps = Vec::new();
     let mut toplevel = Vec::new();
-    let stdout = BufReader::new(child.stdout.take().unwrap());
-    for line in stdout.lines() {
-        let line = t!(line);
-        let json: serde_json::Value = if line.starts_with("{") {
-            t!(serde_json::from_str(&line))
-        } else {
-            // If this was informational, just print it out and continue
-            println!("{}", line);
-            continue
+    let ok = stream_cargo(build, cargo, &mut |msg| {
+        let filenames = match msg {
+            CargoMessage::CompilerArtifact { filenames, .. } => filenames,
+            _ => return,
         };
-        if json["reason"].as_str() != Some("compiler-artifact") {
-            if build.config.rustc_error_format.as_ref().map_or(false, |e| e == "json") {
-                // most likely not a cargo message, so let's send it out as well
-                println!("{}", line);
-            }
-            continue
-        }
-        for filename in json["filenames"].as_array().unwrap() {
-            let filename = filename.as_str().unwrap();
+        for filename in filenames {
             // Skip files like executables
             if !filename.ends_with(".rlib") &&
                !filename.ends_with(".lib") &&
                !is_dylib(&filename) &&
                !(is_check && filename.ends_with(".rmeta")) {
-                continue
+                return;
             }
 
-            let filename = Path::new(filename);
+            let filename = Path::new(&*filename);
 
             // If this was an output file in the "host dir" we don't actually
             // worry about it, it's not relevant for us.
             if filename.starts_with(&host_root_dir) {
-                continue;
+                return;
             }
 
             // If this was output in the `deps` dir then this is a precise file
             // name (hash included) so we start tracking it.
             if filename.starts_with(&target_deps_dir) {
                 deps.push(filename.to_path_buf());
-                continue;
+                return;
             }
 
             // Otherwise this was a "top level artifact" which right now doesn't
@@ -1088,15 +1058,10 @@ pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: boo
 
             toplevel.push((file_stem, extension, expected_len));
         }
-    }
+    });
 
-    // Make sure Cargo actually succeeded after we read all of its stdout.
-    let status = t!(child.wait());
-    if !status.success() {
-        panic!("command did not execute successfully: {:?}\n\
-                expected success, got: {}",
-               cargo,
-               status);
+    if !ok {
+        panic!("cargo must succeed");
     }
 
     // Ok now we need to actually find all the files listed in `toplevel`. We've
@@ -1167,3 +1132,63 @@ pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: boo
     t!(t!(File::create(stamp)).write_all(&new_contents));
     deps
 }
+
+pub fn stream_cargo(
+    build: &Build,
+    cargo: &mut Command,
+    cb: &mut FnMut(CargoMessage),
+) -> bool {
+    // Instruct Cargo to give us json messages on stdout, critically leaving
+    // stderr as piped so we can get those pretty colors.
+    cargo.arg("--message-format").arg("json")
+         .stdout(Stdio::piped());
+
+    if stderr_isatty() && build.ci_env == CiEnv::None {
+        // since we pass message-format=json to cargo, we need to tell the rustc
+        // wrapper to give us colored output if necessary. This is because we
+        // only want Cargo's JSON output, not rustcs.
+        cargo.env("RUSTC_COLOR", "1");
+    }
+
+    build.verbose(&format!("running: {:?}", cargo));
+    let mut child = match cargo.spawn() {
+        Ok(child) => child,
+        Err(e) => panic!("failed to execute command: {:?}\nerror: {}", cargo, e),
+    };
+
+    // Spawn Cargo slurping up its JSON output. We'll start building up the
+    // `deps` array of all files it generated along with a `toplevel` array of
+    // files we need to probe for later.
+    let stdout = BufReader::new(child.stdout.take().unwrap());
+    for line in stdout.lines() {
+        let line = t!(line);
+        match serde_json::from_str::<CargoMessage>(&line) {
+            Ok(msg) => cb(msg),
+            // If this was informational, just print it out and continue
+            Err(_) => println!("{}", line)
+        }
+    }
+
+    // Make sure Cargo actually succeeded after we read all of its stdout.
+    let status = t!(child.wait());
+    if !status.success() {
+        println!("command did not execute successfully: {:?}\n\
+                  expected success, got: {}",
+                 cargo,
+                 status);
+    }
+    status.success()
+}
+
+#[derive(Deserialize)]
+#[serde(tag = "reason", rename_all = "kebab-case")]
+pub enum CargoMessage<'a> {
+    CompilerArtifact {
+        package_id: Cow<'a, str>,
+        features: Vec<Cow<'a, str>>,
+        filenames: Vec<Cow<'a, str>>,
+    },
+    BuildScriptExecuted {
+        package_id: Cow<'a, str>,
+    }
+}
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 920a8ffc2fc86..3ef4b0f8ae7ac 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -121,6 +121,7 @@ pub struct Config {
     pub quiet_tests: bool,
     pub test_miri: bool,
     pub save_toolstates: Option<PathBuf>,
+    pub print_step_timings: bool,
 
     // Fallback musl-root for all targets
     pub musl_root: Option<PathBuf>,
@@ -204,6 +205,7 @@ struct Build {
     openssl_static: Option<bool>,
     configure_args: Option<Vec<String>>,
     local_rebuild: Option<bool>,
+    print_step_timings: Option<bool>,
 }
 
 /// TOML representation of various global install decisions.
@@ -413,6 +415,7 @@ impl Config {
         set(&mut config.openssl_static, build.openssl_static);
         set(&mut config.configure_args, build.configure_args);
         set(&mut config.local_rebuild, build.local_rebuild);
+        set(&mut config.print_step_timings, build.print_step_timings);
         config.verbose = cmp::max(config.verbose, flags.verbose);
 
         if let Some(ref install) = toml.install {
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 97da7cae07f7c..a5c373d5d5e77 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -44,6 +44,7 @@ def v(*args):
 o("docs", "build.docs", "build standard library documentation")
 o("compiler-docs", "build.compiler-docs", "build compiler documentation")
 o("optimize-tests", "rust.optimize-tests", "build tests with optimizations")
+o("experimental-parallel-queries", "rust.experimental-parallel-queries", "build rustc with experimental parallelization")
 o("test-miri", "rust.test-miri", "run miri's test suite")
 o("debuginfo-tests", "rust.debuginfo-tests", "build tests with debugger metadata")
 o("quiet-tests", "rust.quiet-tests", "enable quieter output when running tests")
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index dcb572416594e..23b7b265a94be 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -102,7 +102,7 @@ impl Step for Docs {
 
         let dst = image.join("share/doc/rust/html");
         t!(fs::create_dir_all(&dst));
-        let src = build.out.join(host).join("doc");
+        let src = build.doc_out(host);
         cp_r(&src, &dst);
 
         let mut cmd = rust_installer(builder);
@@ -120,14 +120,69 @@ impl Step for Docs {
         build.run(&mut cmd);
         t!(fs::remove_dir_all(&image));
 
-        // As part of this step, *also* copy the docs directory to a directory which
-        // buildbot typically uploads.
-        if host == build.build {
-            let dst = distdir(build).join("doc").join(build.rust_package_vers());
-            t!(fs::create_dir_all(&dst));
-            cp_r(&src, &dst);
+        distdir(build).join(format!("{}-{}.tar.gz", name, host))
+    }
+}
+
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct RustcDocs {
+    pub stage: u32,
+    pub host: Interned<String>,
+}
+
+impl Step for RustcDocs {
+    type Output = PathBuf;
+    const DEFAULT: bool = true;
+
+    fn should_run(run: ShouldRun) -> ShouldRun {
+        run.path("src/librustc")
+    }
+
+    fn make_run(run: RunConfig) {
+        run.builder.ensure(RustcDocs {
+            stage: run.builder.top_stage,
+            host: run.target,
+        });
+    }
+
+    /// Builds the `rustc-docs` installer component.
+    fn run(self, builder: &Builder) -> PathBuf {
+        let build = builder.build;
+        let host = self.host;
+
+        let name = pkgname(build, "rustc-docs");
+
+        println!("Dist compiler docs ({})", host);
+        if !build.config.compiler_docs {
+            println!("\tskipping - compiler docs disabled");
+            return distdir(build).join(format!("{}-{}.tar.gz", name, host));
         }
 
+        builder.default_doc(None);
+
+        let image = tmpdir(build).join(format!("{}-{}-image", name, host));
+        let _ = fs::remove_dir_all(&image);
+
+        let dst = image.join("share/doc/rust/html");
+        t!(fs::create_dir_all(&dst));
+        let src = build.compiler_doc_out(host);
+        cp_r(&src, &dst);
+
+        let mut cmd = rust_installer(builder);
+        cmd.arg("generate")
+           .arg("--product-name=Rustc-Documentation")
+           .arg("--rel-manifest-dir=rustlib")
+           .arg("--success-message=Rustc-documentation-is-installed.")
+           .arg("--image-dir").arg(&image)
+           .arg("--work-dir").arg(&tmpdir(build))
+           .arg("--output-dir").arg(&distdir(build))
+           .arg(format!("--package-name={}-{}", name, host))
+           .arg("--component-name=rustc-docs")
+           .arg("--legacy-manifest-dirs=rustlib,cargo")
+           .arg("--bulk-dirs=share/doc/rust/html");
+        build.run(&mut cmd);
+        t!(fs::remove_dir_all(&image));
+
         distdir(build).join(format!("{}-{}.tar.gz", name, host))
     }
 }
@@ -221,6 +276,7 @@ fn make_win_dist(
         "libsecur32.a",
         "libsetupapi.a",
         "libshell32.a",
+        "libsynchronization.a",
         "libuser32.a",
         "libuserenv.a",
         "libuuid.a",
@@ -1185,7 +1241,6 @@ impl Step for Rustfmt {
         let build = builder.build;
         let stage = self.stage;
         let target = self.target;
-        assert!(build.config.extended);
 
         println!("Dist Rustfmt stage{} ({})", stage, target);
         let src = build.src.join("src/tools/rustfmt");
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 5bc582b3507bb..44073a5b07572 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -17,12 +17,13 @@
 //! Everything here is basically just a shim around calling either `rustbook` or
 //! `rustdoc`.
 
+use std::collections::HashSet;
 use std::fs::{self, File};
 use std::io::prelude::*;
 use std::io;
 use std::path::{PathBuf, Path};
 
-use Mode;
+use {Build, Mode};
 use build_helper::up_to_date;
 
 use util::{cp_r, symlink_dir};
@@ -483,21 +484,17 @@ impl Step for Std {
         let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "doc");
         compile::std_cargo(builder, &compiler, target, &mut cargo);
 
-        // We don't want to build docs for internal std dependencies unless
-        // in compiler-docs mode. When not in that mode, we whitelist the crates
-        // for which docs must be built.
-        if !build.config.compiler_docs {
-            cargo.arg("--no-deps");
-            for krate in &["alloc", "core", "std", "std_unicode"] {
-                cargo.arg("-p").arg(krate);
-                // Create all crate output directories first to make sure rustdoc uses
-                // relative links.
-                // FIXME: Cargo should probably do this itself.
-                t!(fs::create_dir_all(out_dir.join(krate)));
-            }
+        // Keep a whitelist so we do not build internal stdlib crates, these will be
+        // build by the rustc step later if enabled.
+        cargo.arg("--no-deps");
+        for krate in &["alloc", "core", "std", "std_unicode"] {
+            cargo.arg("-p").arg(krate);
+            // Create all crate output directories first to make sure rustdoc uses
+            // relative links.
+            // FIXME: Cargo should probably do this itself.
+            t!(fs::create_dir_all(out_dir.join(krate)));
         }
 
-
         build.run(&mut cargo);
         cp_r(&my_out, &out);
     }
@@ -564,12 +561,12 @@ impl Step for Test {
 }
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
-pub struct Rustc {
+pub struct WhitelistedRustc {
     stage: u32,
     target: Interned<String>,
 }
 
-impl Step for Rustc {
+impl Step for WhitelistedRustc {
     type Output = ();
     const DEFAULT: bool = true;
     const ONLY_HOSTS: bool = true;
@@ -580,21 +577,26 @@ impl Step for Rustc {
     }
 
     fn make_run(run: RunConfig) {
-        run.builder.ensure(Rustc {
+        run.builder.ensure(WhitelistedRustc {
             stage: run.builder.top_stage,
             target: run.target,
         });
     }
 
-    /// Generate all compiler documentation.
+    /// Generate whitelisted compiler crate documentation.
     ///
-    /// This will generate all documentation for the compiler libraries and their
-    /// dependencies. This is largely just a wrapper around `cargo doc`.
+    /// This will generate all documentation for crates that are whitelisted
+    /// to be included in the standard documentation. This documentation is
+    /// included in the standard Rust documentation, so we should always
+    /// document it and symlink to merge with the rest of the std and test
+    /// documentation. We don't build other compiler documentation
+    /// here as we want to be able to keep it separate from the standard
+    /// documentation. This is largely just a wrapper around `cargo doc`.
     fn run(self, builder: &Builder) {
         let build = builder.build;
         let stage = self.stage;
         let target = self.target;
-        println!("Documenting stage{} compiler ({})", stage, target);
+        println!("Documenting stage{} whitelisted compiler ({})", stage, target);
         let out = build.doc_out(target);
         t!(fs::create_dir_all(&out));
         let compiler = builder.compiler(stage, build.build);
@@ -620,17 +622,12 @@ impl Step for Rustc {
         let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
         compile::rustc_cargo(build, &mut cargo);
 
-        if build.config.compiler_docs {
-            // src/rustc/Cargo.toml contains a bin crate called rustc which
-            // would otherwise overwrite the docs for the real rustc lib crate.
-            cargo.arg("-p").arg("rustc_driver");
-        } else {
-            // Like with libstd above if compiler docs aren't enabled then we're not
-            // documenting internal dependencies, so we have a whitelist.
-            cargo.arg("--no-deps");
-            for krate in &["proc_macro"] {
-                cargo.arg("-p").arg(krate);
-            }
+        // We don't want to build docs for internal compiler dependencies in this
+        // step (there is another step for that). Therefore, we whitelist the crates
+        // for which docs must be built.
+        cargo.arg("--no-deps");
+        for krate in &["proc_macro"] {
+            cargo.arg("-p").arg(krate);
         }
 
         build.run(&mut cargo);
@@ -638,6 +635,103 @@ impl Step for Rustc {
     }
 }
 
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct Rustc {
+    stage: u32,
+    target: Interned<String>,
+}
+
+impl Step for Rustc {
+    type Output = ();
+    const DEFAULT: bool = true;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun) -> ShouldRun {
+        let builder = run.builder;
+        run.krate("rustc-main").default_condition(builder.build.config.docs)
+    }
+
+    fn make_run(run: RunConfig) {
+        run.builder.ensure(Rustc {
+            stage: run.builder.top_stage,
+            target: run.target,
+        });
+    }
+
+    /// Generate compiler documentation.
+    ///
+    /// This will generate all documentation for compiler and dependencies.
+    /// Compiler documentation is distributed separately, so we make sure
+    /// we do not merge it with the other documentation from std, test and
+    /// proc_macros. This is largely just a wrapper around `cargo doc`.
+    fn run(self, builder: &Builder) {
+        let build = builder.build;
+        let stage = self.stage;
+        let target = self.target;
+        println!("Documenting stage{} compiler ({})", stage, target);
+        let out = build.compiler_doc_out(target);
+        t!(fs::create_dir_all(&out));
+        let compiler = builder.compiler(stage, build.build);
+        let rustdoc = builder.rustdoc(compiler.host);
+        let compiler = if build.force_use_stage1(compiler, target) {
+            builder.compiler(1, compiler.host)
+        } else {
+            compiler
+        };
+
+        if !build.config.compiler_docs {
+            println!("\tskipping - compiler docs disabled");
+            return;
+        }
+
+        // Build libstd docs so that we generate relative links
+        builder.ensure(Std { stage, target });
+
+        builder.ensure(compile::Rustc { compiler, target });
+        let out_dir = build.stage_out(compiler, Mode::Librustc)
+                           .join(target).join("doc");
+        // We do not symlink to the same shared folder that already contains std library
+        // documentation from previous steps as we do not want to include that.
+        build.clear_if_dirty(&out, &rustdoc);
+        t!(symlink_dir_force(&out, &out_dir));
+
+        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
+        compile::rustc_cargo(build, &mut cargo);
+
+        // Only include compiler crates, no dependencies of those, such as `libc`.
+        cargo.arg("--no-deps");
+
+        // Find dependencies for top level crates.
+        let mut compiler_crates = HashSet::new();
+        for root_crate in &["rustc", "rustc_driver"] {
+            let interned_root_crate = INTERNER.intern_str(root_crate);
+            find_compiler_crates(&build, &interned_root_crate, &mut compiler_crates);
+        }
+
+        for krate in &compiler_crates {
+            cargo.arg("-p").arg(krate);
+        }
+
+        build.run(&mut cargo);
+    }
+}
+
+fn find_compiler_crates(
+    build: &Build,
+    name: &Interned<String>,
+    crates: &mut HashSet<Interned<String>>
+) {
+    // Add current crate.
+    crates.insert(*name);
+
+    // Look for dependencies.
+    for dep in build.crates.get(name).unwrap().deps.iter() {
+        if build.crates.get(dep).unwrap().is_local(build) {
+            find_compiler_crates(build, dep, crates);
+        }
+    }
+}
+
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct ErrorIndex {
     target: Interned<String>,
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index b778ba33d89cc..833faf3618d67 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -254,6 +254,10 @@ pub struct Build {
     ci_env: CiEnv,
     delayed_failures: RefCell<Vec<String>>,
     prerelease_version: Cell<Option<u32>>,
+    tool_artifacts: RefCell<HashMap<
+        Interned<String>,
+        HashMap<String, (&'static str, PathBuf, Vec<String>)>
+    >>,
 }
 
 #[derive(Debug)]
@@ -353,6 +357,7 @@ impl Build {
             ci_env: CiEnv::current(),
             delayed_failures: RefCell::new(Vec::new()),
             prerelease_version: Cell::new(None),
+            tool_artifacts: Default::default(),
         }
     }
 
@@ -511,6 +516,11 @@ impl Build {
         self.out.join(&*target).join("doc")
     }
 
+    /// Output directory for all documentation for a target
+    fn compiler_doc_out(&self, target: Interned<String>) -> PathBuf {
+        self.out.join(&*target).join("compiler-doc")
+    }
+
     /// Output directory for some generated md crate documentation for a target (temporary)
     fn md_doc_out(&self, target: Interned<String>) -> Interned<PathBuf> {
         INTERNER.intern_path(self.out.join(&*target).join("md-doc"))
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 7897af4f72470..bcf2f6a675e02 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -85,5 +85,12 @@ check-stage2-T-arm-linux-androideabi-H-x86_64-unknown-linux-gnu:
 check-stage2-T-x86_64-unknown-linux-musl-H-x86_64-unknown-linux-gnu:
 	$(Q)$(BOOTSTRAP) test --target x86_64-unknown-linux-musl
 
+TESTS_IN_2 := src/test/run-pass src/test/compile-fail src/test/run-pass-fulldeps
+
+appveyor-subset-1:
+	$(Q)$(BOOTSTRAP) test $(TESTS_IN_2:%=--exclude %)
+appveyor-subset-2:
+	$(Q)$(BOOTSTRAP) test $(TESTS_IN_2)
+
 
 .PHONY: dist
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index de938ec8e8306..76f1a4efbf014 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -530,8 +530,6 @@ impl Step for Tidy {
     fn run(self, builder: &Builder) {
         let build = builder.build;
 
-        let _folder = build.fold_output(|| "tidy");
-        println!("tidy check");
         let mut cmd = builder.tool_cmd(Tool::Tidy);
         cmd.arg(build.src.join("src"));
         cmd.arg(&build.initial_cargo);
@@ -541,6 +539,9 @@ impl Step for Tidy {
         if build.config.quiet_tests {
             cmd.arg("--quiet");
         }
+
+        let _folder = build.fold_output(|| "tidy");
+        println!("tidy check");
         try_run(build, &mut cmd);
     }
 
@@ -759,12 +760,18 @@ test!(RunFailFullDepsPretty {
     host: true
 });
 
-host_test!(RunMake {
+default_test!(RunMake {
     path: "src/test/run-make",
     mode: "run-make",
     suite: "run-make"
 });
 
+host_test!(RunMakeFullDeps {
+    path: "src/test/run-make-fulldeps",
+    mode: "run-make",
+    suite: "run-make-fulldeps"
+});
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 struct Compiletest {
     compiler: Compiler,
@@ -827,8 +834,7 @@ impl Step for Compiletest {
             // FIXME: Does pretty need librustc compiled? Note that there are
             // fulldeps test suites with mode = pretty as well.
             mode == "pretty" ||
-            mode == "rustdoc" ||
-            mode == "run-make" {
+            mode == "rustdoc" {
             builder.ensure(compile::Rustc { compiler, target });
         }
 
@@ -836,9 +842,6 @@ impl Step for Compiletest {
         builder.ensure(native::TestHelpers { target });
         builder.ensure(RemoteCopyLibs { compiler, target });
 
-        let _folder = build.fold_output(|| format!("test_{}", suite));
-        println!("Check compiletest suite={} mode={} ({} -> {})",
-                 suite, mode, &compiler.host, target);
         let mut cmd = builder.tool_cmd(Tool::Compiletest);
 
         // compiletest currently has... a lot of arguments, so let's just pass all
@@ -849,7 +852,7 @@ impl Step for Compiletest {
         cmd.arg("--rustc-path").arg(builder.rustc(compiler));
 
         // Avoid depending on rustdoc when we don't need it.
-        if mode == "rustdoc" || mode == "run-make" {
+        if mode == "rustdoc" || (mode == "run-make" && suite.ends_with("fulldeps")) {
             cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler.host));
         }
 
@@ -931,7 +934,7 @@ impl Step for Compiletest {
 
             // Only pass correct values for these flags for the `run-make` suite as it
             // requires that a C++ compiler was configured which isn't always the case.
-            if suite == "run-make" {
+            if suite == "run-make-fulldeps" {
                 let llvm_components = output(Command::new(&llvm_config).arg("--components"));
                 let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags"));
                 cmd.arg("--cc").arg(build.cc(target))
@@ -944,12 +947,12 @@ impl Step for Compiletest {
                 }
             }
         }
-        if suite == "run-make" && !build.config.llvm_enabled {
+        if suite == "run-make-fulldeps" && !build.config.llvm_enabled {
             println!("Ignoring run-make test suite as they generally don't work without LLVM");
             return;
         }
 
-        if suite != "run-make" {
+        if suite != "run-make-fulldeps" {
             cmd.arg("--cc").arg("")
                .arg("--cxx").arg("")
                .arg("--cflags").arg("")
@@ -998,6 +1001,9 @@ impl Step for Compiletest {
 
         build.ci_env.force_coloring_in_ci(&mut cmd);
 
+        let _folder = build.fold_output(|| format!("test_{}", suite));
+        println!("Check compiletest suite={} mode={} ({} -> {})",
+                 suite, mode, &compiler.host, target);
         let _time = util::timeit();
         try_run(build, &mut cmd);
     }
@@ -1142,20 +1148,21 @@ impl Step for ErrorIndex {
 
         builder.ensure(compile::Std { compiler, target: compiler.host });
 
-        let _folder = build.fold_output(|| "test_error_index");
-        println!("Testing error-index stage{}", compiler.stage);
-
         let dir = testdir(build, compiler.host);
         t!(fs::create_dir_all(&dir));
         let output = dir.join("error-index.md");
 
-        let _time = util::timeit();
-        build.run(builder.tool_cmd(Tool::ErrorIndex)
-                    .arg("markdown")
-                    .arg(&output)
-                    .env("CFG_BUILD", &build.build)
-                    .env("RUSTC_ERROR_METADATA_DST", build.extended_error_dir()));
+        let mut tool = builder.tool_cmd(Tool::ErrorIndex);
+        tool.arg("markdown")
+            .arg(&output)
+            .env("CFG_BUILD", &build.build)
+            .env("RUSTC_ERROR_METADATA_DST", build.extended_error_dir());
 
+
+        let _folder = build.fold_output(|| "test_error_index");
+        println!("Testing error-index stage{}", compiler.stage);
+        let _time = util::timeit();
+        build.run(&mut tool);
         markdown_test(builder, compiler, &output);
     }
 }
@@ -1400,11 +1407,6 @@ impl Step for Crate {
             }
             _ => panic!("can only test libraries"),
         };
-        let _folder = build.fold_output(|| {
-            format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, krate)
-        });
-        println!("{} {} stage{} ({} -> {})", test_kind, krate, compiler.stage,
-                &compiler.host, target);
 
         // Build up the base `cargo test` command.
         //
@@ -1436,8 +1438,6 @@ impl Step for Crate {
             cargo.arg("--quiet");
         }
 
-        let _time = util::timeit();
-
         if target.contains("emscripten") {
             cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target)),
                       build.config.nodejs.as_ref().expect("nodejs not configured"));
@@ -1465,6 +1465,13 @@ impl Step for Crate {
                       format!("{} run",
                               builder.tool_exe(Tool::RemoteTestClient).display()));
         }
+
+        let _folder = build.fold_output(|| {
+            format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, krate)
+        });
+        println!("{} {} stage{} ({} -> {})", test_kind, krate, compiler.stage,
+                &compiler.host, target);
+        let _time = util::timeit();
         try_run(build, &mut cargo);
     }
 }
@@ -1513,12 +1520,6 @@ impl Step for CrateRustdoc {
                                                  target,
                                                  test_kind.subcommand(),
                                                  "src/tools/rustdoc");
-        let _folder = build.fold_output(|| {
-            format!("{}_stage{}-rustdoc", test_kind.subcommand(), compiler.stage)
-        });
-        println!("{} rustdoc stage{} ({} -> {})", test_kind, compiler.stage,
-                &compiler.host, target);
-
         if test_kind.subcommand() == "test" && !build.fail_fast {
             cargo.arg("--no-fail-fast");
         }
@@ -1532,6 +1533,11 @@ impl Step for CrateRustdoc {
             cargo.arg("--quiet");
         }
 
+        let _folder = build.fold_output(|| {
+            format!("{}_stage{}-rustdoc", test_kind.subcommand(), compiler.stage)
+        });
+        println!("{} rustdoc stage{} ({} -> {})", test_kind, compiler.stage,
+                &compiler.host, target);
         let _time = util::timeit();
 
         try_run(build, &mut cargo);
@@ -1689,6 +1695,12 @@ impl Step for Bootstrap {
            .env("CARGO_TARGET_DIR", build.out.join("bootstrap"))
            .env("RUSTC_BOOTSTRAP", "1")
            .env("RUSTC", &build.initial_rustc);
+        if let Some(flags) = option_env!("RUSTFLAGS") {
+            // Use the same rustc flags for testing as for "normal" compilation,
+            // so that Cargo doesn’t recompile the entire dependency graph every time:
+            // https://github.com/rust-lang/rust/issues/49215
+            cmd.env("RUSTFLAGS", flags);
+        }
         if !build.fail_fast {
             cmd.arg("--no-fail-fast");
         }
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 5f5b10a07b865..2bb46cc5171d6 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -112,12 +112,85 @@ impl Step for ToolBuild {
             Mode::Tool => panic!("unexpected Mode::Tool for tool build")
         }
 
+        let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path);
+        cargo.arg("--features").arg(self.extra_features.join(" "));
+
         let _folder = build.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
         println!("Building stage{} tool {} ({})", compiler.stage, tool, target);
+        let mut duplicates = Vec::new();
+        let is_expected = compile::stream_cargo(build, &mut cargo, &mut |msg| {
+            // Only care about big things like the RLS/Cargo for now
+            if tool != "rls" && tool != "cargo" {
+                return
+            }
+            let (id, features, filenames) = match msg {
+                compile::CargoMessage::CompilerArtifact {
+                    package_id,
+                    features,
+                    filenames
+                } => {
+                    (package_id, features, filenames)
+                }
+                _ => return,
+            };
+            let features = features.iter().map(|s| s.to_string()).collect::<Vec<_>>();
+
+            for path in filenames {
+                let val = (tool, PathBuf::from(&*path), features.clone());
+                // we're only interested in deduplicating rlibs for now
+                if val.1.extension().and_then(|s| s.to_str()) != Some("rlib") {
+                    continue
+                }
+
+                // Don't worry about libs that turn out to be host dependencies
+                // or build scripts, we only care about target dependencies that
+                // are in `deps`.
+                if let Some(maybe_target) = val.1
+                    .parent()                   // chop off file name
+                    .and_then(|p| p.parent())   // chop off `deps`
+                    .and_then(|p| p.parent())   // chop off `release`
+                    .and_then(|p| p.file_name())
+                    .and_then(|p| p.to_str())
+                {
+                    if maybe_target != &*target {
+                        continue
+                    }
+                }
+
+                let mut artifacts = build.tool_artifacts.borrow_mut();
+                let prev_artifacts = artifacts
+                    .entry(target)
+                    .or_insert_with(Default::default);
+                if let Some(prev) = prev_artifacts.get(&*id) {
+                    if prev.1 != val.1 {
+                        duplicates.push((
+                            id.to_string(),
+                            val,
+                            prev.clone(),
+                        ));
+                    }
+                    return
+                }
+                prev_artifacts.insert(id.to_string(), val);
+            }
+        });
+
+        if is_expected && duplicates.len() != 0 {
+            println!("duplicate artfacts found when compiling a tool, this \
+                      typically means that something was recompiled because \
+                      a transitive dependency has different features activated \
+                      than in a previous build:\n");
+            for (id, cur, prev) in duplicates {
+                println!("  {}", id);
+                println!("    `{}` enabled features {:?} at {:?}",
+                         cur.0, cur.2, cur.1);
+                println!("    `{}` enabled features {:?} at {:?}",
+                         prev.0, prev.2, prev.1);
+            }
+            println!("");
+            panic!("tools should not compile multiple copies of the same crate");
+        }
 
-        let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path);
-        cargo.arg("--features").arg(self.extra_features.join(" "));
-        let is_expected = build.try_run(&mut cargo);
         build.save_toolstate(tool, if is_expected {
             ToolState::TestFail
         } else {
@@ -338,9 +411,10 @@ impl Step for Rustdoc {
         };
 
         builder.ensure(compile::Rustc { compiler: build_compiler, target });
-
-        let _folder = build.fold_output(|| format!("stage{}-rustdoc", target_compiler.stage));
-        println!("Building rustdoc for stage{} ({})", target_compiler.stage, target_compiler.host);
+        builder.ensure(compile::Rustc {
+            compiler: build_compiler,
+            target: builder.build.build,
+        });
 
         let mut cargo = prepare_tool_cargo(builder,
                                            build_compiler,
@@ -352,7 +426,10 @@ impl Step for Rustdoc {
         cargo.env("RUSTC_DEBUGINFO", builder.config.rust_debuginfo.to_string())
              .env("RUSTC_DEBUGINFO_LINES", builder.config.rust_debuginfo_lines.to_string());
 
+        let _folder = build.fold_output(|| format!("stage{}-rustdoc", target_compiler.stage));
+        println!("Building rustdoc for stage{} ({})", target_compiler.stage, target_compiler.host);
         build.run(&mut cargo);
+
         // Cargo adds a number of paths to the dylib search path on windows, which results in
         // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
         // rustdoc a different name.
diff --git a/src/ci/docker/asmjs/Dockerfile b/src/ci/docker/asmjs/Dockerfile
index 2a0901691a55a..cb85cf3d9e9f0 100644
--- a/src/ci/docker/asmjs/Dockerfile
+++ b/src/ci/docker/asmjs/Dockerfile
@@ -29,6 +29,11 @@ ENV EM_CONFIG=/emsdk-portable/.emscripten
 
 ENV TARGETS=asmjs-unknown-emscripten
 
-ENV RUST_CONFIGURE_ARGS --enable-emscripten
+ENV RUST_CONFIGURE_ARGS --enable-emscripten --disable-optimize-tests
 
-ENV SCRIPT python2.7 ../x.py test --target $TARGETS
+ENV SCRIPT python2.7 ../x.py test --target $TARGETS \
+  src/test/run-pass \
+  src/test/run-fail \
+  src/libstd \
+  src/liballoc \
+  src/libcore
diff --git a/src/ci/docker/dist-aarch64-linux/Dockerfile b/src/ci/docker/dist-aarch64-linux/Dockerfile
index dbc319312aa9f..cddfa557f6aed 100644
--- a/src/ci/docker/dist-aarch64-linux/Dockerfile
+++ b/src/ci/docker/dist-aarch64-linux/Dockerfile
@@ -32,5 +32,5 @@ ENV CC_aarch64_unknown_linux_gnu=aarch64-unknown-linux-gnueabi-gcc \
 
 ENV HOSTS=aarch64-unknown-linux-gnu
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-android/Dockerfile b/src/ci/docker/dist-android/Dockerfile
index aa5da136758a0..e00c23dac89b0 100644
--- a/src/ci/docker/dist-android/Dockerfile
+++ b/src/ci/docker/dist-android/Dockerfile
@@ -26,7 +26,8 @@ ENV RUST_CONFIGURE_ARGS \
       --armv7-linux-androideabi-ndk=/android/ndk/arm-14 \
       --i686-linux-android-ndk=/android/ndk/x86-14 \
       --aarch64-linux-android-ndk=/android/ndk/arm64-21 \
-      --x86_64-linux-android-ndk=/android/ndk/x86_64-21
+      --x86_64-linux-android-ndk=/android/ndk/x86_64-21 \
+      --disable-docs
 
 ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
 
diff --git a/src/ci/docker/dist-arm-linux/Dockerfile b/src/ci/docker/dist-arm-linux/Dockerfile
index 89f7f85cb3b17..6ddc5c1e04ae3 100644
--- a/src/ci/docker/dist-arm-linux/Dockerfile
+++ b/src/ci/docker/dist-arm-linux/Dockerfile
@@ -32,5 +32,5 @@ ENV CC_arm_unknown_linux_gnueabi=arm-unknown-linux-gnueabi-gcc \
 
 ENV HOSTS=arm-unknown-linux-gnueabi
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-armhf-linux/Dockerfile b/src/ci/docker/dist-armhf-linux/Dockerfile
index e0c1b9a9e8589..e4d4b2feeec40 100644
--- a/src/ci/docker/dist-armhf-linux/Dockerfile
+++ b/src/ci/docker/dist-armhf-linux/Dockerfile
@@ -32,5 +32,5 @@ ENV CC_arm_unknown_linux_gnueabihf=arm-unknown-linux-gnueabihf-gcc \
 
 ENV HOSTS=arm-unknown-linux-gnueabihf
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-armv7-linux/Dockerfile b/src/ci/docker/dist-armv7-linux/Dockerfile
index e7d4f464ffcd2..99fe7bd7b8f78 100644
--- a/src/ci/docker/dist-armv7-linux/Dockerfile
+++ b/src/ci/docker/dist-armv7-linux/Dockerfile
@@ -32,5 +32,5 @@ ENV CC_armv7_unknown_linux_gnueabihf=armv7-unknown-linux-gnueabihf-gcc \
 
 ENV HOSTS=armv7-unknown-linux-gnueabihf
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile
index 7bcc649f4aa5c..e12bed3abc5ad 100644
--- a/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile
+++ b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile
@@ -32,7 +32,8 @@ RUN sh /scripts/sccache.sh
 ENV RUST_CONFIGURE_ARGS \
       --musl-root-i586=/musl-i586 \
       --musl-root-i686=/musl-i686 \
-      --enable-extended
+      --enable-extended \
+      --disable-docs
 
 # Newer binutils broke things on some vms/distros (i.e., linking against
 # unknown relocs disabled by the following flag), so we need to go out of our
diff --git a/src/ci/docker/dist-i686-freebsd/Dockerfile b/src/ci/docker/dist-i686-freebsd/Dockerfile
index 1f595ba7a290f..6f6a663a33093 100644
--- a/src/ci/docker/dist-i686-freebsd/Dockerfile
+++ b/src/ci/docker/dist-i686-freebsd/Dockerfile
@@ -29,5 +29,5 @@ ENV \
 
 ENV HOSTS=i686-unknown-freebsd
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-i686-linux/build-gcc.sh b/src/ci/docker/dist-i686-linux/build-gcc.sh
index 6b991bb59e4b0..08020e533ff19 100755
--- a/src/ci/docker/dist-i686-linux/build-gcc.sh
+++ b/src/ci/docker/dist-i686-linux/build-gcc.sh
@@ -17,6 +17,23 @@ GCC=4.8.5
 
 curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.bz2 | tar xjf -
 cd gcc-$GCC
+
+# FIXME(#49246): Remove the `sed` below.
+#
+# On 2018 March 21st, two Travis builders' cache for Docker are suddenly invalidated. Normally this
+# is fine, because we just need to rebuild the Docker image. However, it reveals a network issue:
+# downloading from `ftp://gcc.gnu.org/` from Travis (using passive mode) often leads to "Connection
+# timed out" error, and even when the download completed, the file is usually corrupted. This causes
+# nothing to be landed that day.
+#
+# We observed that the `gcc-4.8.5.tar.bz2` above can be downloaded successfully, so as a stability
+# improvement we try to download from the HTTPS mirror instead. Turns out this uncovered the third
+# bug: the host `gcc.gnu.org` and `cygwin.com` share the same IP, and the TLS certificate of the
+# latter host is presented to `wget`! Therefore, we choose to download from the insecure HTTP server
+# instead here.
+#
+sed -i'' 's|ftp://gcc\.gnu\.org/|http://gcc.gnu.org/|g' ./contrib/download_prerequisites
+
 ./contrib/download_prerequisites
 mkdir ../gcc-build
 cd ../gcc-build
diff --git a/src/ci/docker/dist-i686-linux/build-git.sh b/src/ci/docker/dist-i686-linux/build-git.sh
index ff62a68629a8b..aa31f50ba0343 100755
--- a/src/ci/docker/dist-i686-linux/build-git.sh
+++ b/src/ci/docker/dist-i686-linux/build-git.sh
@@ -12,7 +12,7 @@
 set -ex
 source shared.sh
 
-curl https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf -
+curl -L https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf -
 
 cd git-2.10.0
 make configure
diff --git a/src/ci/docker/dist-mips-linux/Dockerfile b/src/ci/docker/dist-mips-linux/Dockerfile
index 37ab5bdcce555..466def1f80fbf 100644
--- a/src/ci/docker/dist-mips-linux/Dockerfile
+++ b/src/ci/docker/dist-mips-linux/Dockerfile
@@ -22,5 +22,5 @@ RUN sh /scripts/sccache.sh
 
 ENV HOSTS=mips-unknown-linux-gnu
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-mips64-linux/Dockerfile b/src/ci/docker/dist-mips64-linux/Dockerfile
index a5180780b2259..2205b733e99f1 100644
--- a/src/ci/docker/dist-mips64-linux/Dockerfile
+++ b/src/ci/docker/dist-mips64-linux/Dockerfile
@@ -21,5 +21,5 @@ RUN sh /scripts/sccache.sh
 
 ENV HOSTS=mips64-unknown-linux-gnuabi64
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-mips64el-linux/Dockerfile b/src/ci/docker/dist-mips64el-linux/Dockerfile
index d38ed24f6255f..f1d9dad46ea3f 100644
--- a/src/ci/docker/dist-mips64el-linux/Dockerfile
+++ b/src/ci/docker/dist-mips64el-linux/Dockerfile
@@ -22,5 +22,5 @@ RUN sh /scripts/sccache.sh
 
 ENV HOSTS=mips64el-unknown-linux-gnuabi64
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-mipsel-linux/Dockerfile b/src/ci/docker/dist-mipsel-linux/Dockerfile
index 491c57ba67737..ee73e29c76e35 100644
--- a/src/ci/docker/dist-mipsel-linux/Dockerfile
+++ b/src/ci/docker/dist-mipsel-linux/Dockerfile
@@ -21,5 +21,5 @@ RUN sh /scripts/sccache.sh
 
 ENV HOSTS=mipsel-unknown-linux-gnu
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-powerpc-linux/Dockerfile b/src/ci/docker/dist-powerpc-linux/Dockerfile
index c503f2af9cdaa..f03aff060c103 100644
--- a/src/ci/docker/dist-powerpc-linux/Dockerfile
+++ b/src/ci/docker/dist-powerpc-linux/Dockerfile
@@ -34,7 +34,7 @@ ENV \
 
 ENV HOSTS=powerpc-unknown-linux-gnu
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
 
 # FIXME(#36150) this will fail the bootstrap. Probably means something bad is
diff --git a/src/ci/docker/dist-powerpc64-linux/Dockerfile b/src/ci/docker/dist-powerpc64-linux/Dockerfile
index 4a3691777360b..bb30210c0563a 100644
--- a/src/ci/docker/dist-powerpc64-linux/Dockerfile
+++ b/src/ci/docker/dist-powerpc64-linux/Dockerfile
@@ -35,5 +35,5 @@ ENV \
 
 ENV HOSTS=powerpc64-unknown-linux-gnu
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-powerpc64le-linux/Dockerfile b/src/ci/docker/dist-powerpc64le-linux/Dockerfile
index bf6c8b4b71211..ee9e455048352 100644
--- a/src/ci/docker/dist-powerpc64le-linux/Dockerfile
+++ b/src/ci/docker/dist-powerpc64le-linux/Dockerfile
@@ -32,5 +32,5 @@ ENV \
 
 ENV HOSTS=powerpc64le-unknown-linux-gnu
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-s390x-linux/Dockerfile b/src/ci/docker/dist-s390x-linux/Dockerfile
index a2ebf590bab74..7ba6fe643c2ae 100644
--- a/src/ci/docker/dist-s390x-linux/Dockerfile
+++ b/src/ci/docker/dist-s390x-linux/Dockerfile
@@ -34,5 +34,5 @@ ENV \
 
 ENV HOSTS=s390x-unknown-linux-gnu
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index a23153645cde2..b398e9a3c92ef 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -95,7 +95,8 @@ ENV RUST_CONFIGURE_ARGS \
       --musl-root-aarch64=/musl-aarch64 \
       --musl-root-mips=/musl-mips \
       --musl-root-mipsel=/musl-mipsel \
-      --enable-emscripten
+      --enable-emscripten \
+      --disable-docs
 
 ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
 
diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile
index 4505a60e46396..e8d6c12de4474 100644
--- a/src/ci/docker/dist-various-2/Dockerfile
+++ b/src/ci/docker/dist-various-2/Dockerfile
@@ -55,5 +55,5 @@ ENV TARGETS=$TARGETS,x86_64-sun-solaris
 ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
 ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
diff --git a/src/ci/docker/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/dist-x86_64-freebsd/Dockerfile
index dd595a192051f..698b81a92e935 100644
--- a/src/ci/docker/dist-x86_64-freebsd/Dockerfile
+++ b/src/ci/docker/dist-x86_64-freebsd/Dockerfile
@@ -29,5 +29,5 @@ ENV \
 
 ENV HOSTS=x86_64-unknown-freebsd
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile
index 3b98b0aa926bd..28c97e8c6dbf9 100644
--- a/src/ci/docker/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/dist-x86_64-linux/Dockerfile
@@ -84,7 +84,8 @@ ENV HOSTS=x86_64-unknown-linux-gnu
 ENV RUST_CONFIGURE_ARGS \
       --enable-full-tools \
       --enable-sanitizers \
-      --enable-profiler
+      --enable-profiler \
+      --enable-compiler-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
 
 # This is the only builder which will create source tarballs
diff --git a/src/ci/docker/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/dist-x86_64-linux/build-gcc.sh
index 6b991bb59e4b0..08020e533ff19 100755
--- a/src/ci/docker/dist-x86_64-linux/build-gcc.sh
+++ b/src/ci/docker/dist-x86_64-linux/build-gcc.sh
@@ -17,6 +17,23 @@ GCC=4.8.5
 
 curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.bz2 | tar xjf -
 cd gcc-$GCC
+
+# FIXME(#49246): Remove the `sed` below.
+#
+# On 2018 March 21st, two Travis builders' cache for Docker are suddenly invalidated. Normally this
+# is fine, because we just need to rebuild the Docker image. However, it reveals a network issue:
+# downloading from `ftp://gcc.gnu.org/` from Travis (using passive mode) often leads to "Connection
+# timed out" error, and even when the download completed, the file is usually corrupted. This causes
+# nothing to be landed that day.
+#
+# We observed that the `gcc-4.8.5.tar.bz2` above can be downloaded successfully, so as a stability
+# improvement we try to download from the HTTPS mirror instead. Turns out this uncovered the third
+# bug: the host `gcc.gnu.org` and `cygwin.com` share the same IP, and the TLS certificate of the
+# latter host is presented to `wget`! Therefore, we choose to download from the insecure HTTP server
+# instead here.
+#
+sed -i'' 's|ftp://gcc\.gnu\.org/|http://gcc.gnu.org/|g' ./contrib/download_prerequisites
+
 ./contrib/download_prerequisites
 mkdir ../gcc-build
 cd ../gcc-build
diff --git a/src/ci/docker/dist-x86_64-linux/build-git.sh b/src/ci/docker/dist-x86_64-linux/build-git.sh
index ff62a68629a8b..aa31f50ba0343 100755
--- a/src/ci/docker/dist-x86_64-linux/build-git.sh
+++ b/src/ci/docker/dist-x86_64-linux/build-git.sh
@@ -12,7 +12,7 @@
 set -ex
 source shared.sh
 
-curl https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf -
+curl -L https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf -
 
 cd git-2.10.0
 make configure
diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile
index 3a9ad178c6390..06f8a2fbba836 100644
--- a/src/ci/docker/dist-x86_64-musl/Dockerfile
+++ b/src/ci/docker/dist-x86_64-musl/Dockerfile
@@ -31,7 +31,8 @@ RUN sh /scripts/sccache.sh
 
 ENV RUST_CONFIGURE_ARGS \
       --musl-root-x86_64=/musl-x86_64 \
-      --enable-extended
+      --enable-extended \
+      --disable-docs
 
 # Newer binutils broke things on some vms/distros (i.e., linking against
 # unknown relocs disabled by the following flag), so we need to go out of our
diff --git a/src/ci/docker/dist-x86_64-netbsd/Dockerfile b/src/ci/docker/dist-x86_64-netbsd/Dockerfile
index 06298a12fc70a..a17a7ebc03dd1 100644
--- a/src/ci/docker/dist-x86_64-netbsd/Dockerfile
+++ b/src/ci/docker/dist-x86_64-netbsd/Dockerfile
@@ -33,5 +33,5 @@ ENV \
 
 ENV HOSTS=x86_64-unknown-netbsd
 
-ENV RUST_CONFIGURE_ARGS --enable-extended
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index f743c976f91a2..2946cf7fc503f 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -27,6 +27,21 @@ travis_fold start build_docker
 travis_time_start
 
 if [ -f "$docker_dir/$image/Dockerfile" ]; then
+    if [ "$CI" != "" ]; then
+      cksum=$(find $docker_dir/$image $docker_dir/scripts -type f | \
+        sort | \
+        xargs cat | \
+        sha512sum | \
+        awk '{print $1}')
+      s3url="s3://$SCCACHE_BUCKET/docker/$cksum"
+      url="https://s3-us-west-1.amazonaws.com/$SCCACHE_BUCKET/docker/$cksum"
+      echo "Attempting to download $s3url"
+      set +e
+      loaded_images=$(curl $url | docker load | sed 's/.* sha/sha/')
+      set -e
+      echo "Downloaded containers:\n$loaded_images"
+    fi
+
     dockerfile="$docker_dir/$image/Dockerfile"
     if [ -x /usr/bin/cygpath ]; then
         context="`cygpath -w $docker_dir`"
@@ -40,6 +55,23 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
       -t rust-ci \
       -f "$dockerfile" \
       "$context"
+
+    if [ "$s3url" != "" ]; then
+      digest=$(docker inspect rust-ci --format '{{.Id}}')
+      echo "Built container $digest"
+      if ! grep -q "$digest" <(echo "$loaded_images"); then
+        echo "Uploading finished image to $s3url"
+        set +e
+        docker history -q rust-ci | \
+          grep -v missing | \
+          xargs docker save | \
+          gzip | \
+          aws s3 cp - $s3url
+        set -e
+      else
+        echo "Looks like docker image is the same as before, not uploading"
+      fi
+    fi
 elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then
     if [ -n "$TRAVIS_OS_NAME" ]; then
         echo Cannot run disabled images on travis!
diff --git a/src/ci/docker/wasm32-unknown/Dockerfile b/src/ci/docker/wasm32-unknown/Dockerfile
index 0972eb85191a9..6c0ec1ad9d4e1 100644
--- a/src/ci/docker/wasm32-unknown/Dockerfile
+++ b/src/ci/docker/wasm32-unknown/Dockerfile
@@ -26,6 +26,7 @@ ENV RUST_CONFIGURE_ARGS \
   --set rust.lld
 
 ENV SCRIPT python2.7 /checkout/x.py test --target $TARGETS \
+  src/test/run-make \
   src/test/ui \
   src/test/run-pass \
   src/test/compile-fail \
diff --git a/src/ci/docker/x86_64-gnu-debug/Dockerfile b/src/ci/docker/x86_64-gnu-debug/Dockerfile
index 95d41028595f8..ff6ab1013b4c2 100644
--- a/src/ci/docker/x86_64-gnu-debug/Dockerfile
+++ b/src/ci/docker/x86_64-gnu-debug/Dockerfile
@@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+ENV PARALLEL_CHECK 1
 ENV RUST_CONFIGURE_ARGS \
       --build=x86_64-unknown-linux-gnu \
       --enable-debug \
diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh
index 8ab4276fa3b05..f2664e6d196c7 100755
--- a/src/ci/init_repo.sh
+++ b/src/ci/init_repo.sh
@@ -17,6 +17,7 @@ ci_dir=$(cd $(dirname $0) && pwd)
 . "$ci_dir/shared.sh"
 
 travis_fold start init_repo
+travis_time_start
 
 REPO_DIR="$1"
 CACHE_DIR="$2"
@@ -42,54 +43,39 @@ if grep -q RUST_RELEASE_CHANNEL=beta src/ci/run.sh; then
   git fetch origin --unshallow beta master
 fi
 
-travis_fold start update_cache
-travis_time_start
-
-# Update the cache (a pristine copy of the rust source master)
-retry sh -c "rm -rf $cache_src_dir && mkdir -p $cache_src_dir && \
-    git clone --depth 1 https://github.com/rust-lang/rust.git $cache_src_dir"
-if [ -d $cache_src_dir/src/llvm ]; then
-  (cd $cache_src_dir && git rm src/llvm)
-fi
-if [ -d $cache_src_dir/src/llvm-emscripten ]; then
-  (cd $cache_src_dir && git rm src/llvm-emscripten)
-fi
-retry sh -c "cd $cache_src_dir && \
-    git submodule deinit -f . && git submodule sync && git submodule update --init"
-
-travis_fold end update_cache
-travis_time_finish
+function fetch_submodule {
+    local module=$1
+    local cached="download-${module//\//-}.tar.gz"
+    retry sh -c "rm -f $cached && \
+        curl -sSL -o $cached $2"
+    mkdir $module
+    touch "$module/.git"
+    tar -C $module --strip-components=1 -xf $cached
+    rm $cached
+}
 
-travis_fold start update_submodules
-travis_time_start
-
-# Update the submodules of the repo we're in, using the pristine repo as
-# a cache for any object files
-# No, `git submodule foreach` won't work:
-# http://stackoverflow.com/questions/12641469/list-submodules-in-a-git-repository
+included="src/llvm src/llvm-emscripten src/doc/book src/doc/rust-by-example"
 modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)"
-for module in $modules; do
-    if [ "$module" = src/llvm ] || [ "$module" = src/llvm-emscripten ]; then
+modules=($modules)
+use_git=""
+urls="$(git config --file .gitmodules --get-regexp '\.url$' | cut -d' ' -f2)"
+urls=($urls)
+for i in ${!modules[@]}; do
+    module=${modules[$i]}
+    if [[ " $included " = *" $module "* ]]; then
         commit="$(git ls-tree HEAD $module | awk '{print $3}')"
         git rm $module
-        retry sh -c "rm -f $commit.tar.gz && \
-            curl -sSL -O https://github.com/rust-lang/llvm/archive/$commit.tar.gz"
-        tar -C src/ -xf "$commit.tar.gz"
-        rm "$commit.tar.gz"
-        mv "src/llvm-$commit" $module
-        continue
-    fi
-    if [ ! -e "$cache_src_dir/$module/.git" ]; then
-        echo "WARNING: $module not found in pristine repo"
-        retry sh -c "git submodule deinit -f $module && \
-            git submodule update --init --recursive $module"
+        url=${urls[$i]}
+        url=${url/\.git/}
+        fetch_submodule $module "$url/archive/$commit.tar.gz" &
         continue
+    else
+        use_git="$use_git $module"
     fi
-    retry sh -c "git submodule deinit -f $module && \
-        git submodule update --init --recursive --reference $cache_src_dir/$module $module"
 done
-
-travis_fold end update_submodules
-travis_time_finish
-
+retry sh -c "git submodule deinit -f $use_git && \
+    git submodule sync && \
+    git submodule update -j 16 --init --recursive $use_git"
+wait
 travis_fold end init_repo
+travis_time_finish
diff --git a/src/ci/run.sh b/src/ci/run.sh
index e3f38e4834a92..44eae0d180047 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -25,6 +25,8 @@ source "$ci_dir/shared.sh"
 
 if [ "$TRAVIS" == "true" ] && [ "$TRAVIS_BRANCH" != "auto" ]; then
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-quiet-tests"
+else
+    RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.print-step-timings"
 fi
 
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-sccache"
@@ -72,6 +74,13 @@ fi
 # sccache server at the start of the build, but no need to worry if this fails.
 SCCACHE_IDLE_TIMEOUT=10800 sccache --start-server || true
 
+if [ "$PARALLEL_CHECK" != "" ]; then
+  $SRC/configure --enable-experimental-parallel-queries
+  python2.7 ../x.py check
+  rm -f config.toml
+  rm -rf build
+fi
+
 travis_fold start configure
 travis_time_start
 $SRC/configure $RUST_CONFIGURE_ARGS
diff --git a/src/doc/book b/src/doc/book
index 98921e9de849a..b889e1e30c5e9 160000
--- a/src/doc/book
+++ b/src/doc/book
@@ -1 +1 @@
-Subproject commit 98921e9de849acdaeaed08cfad6758bb89769b7d
+Subproject commit b889e1e30c5e9953834aa9fa6c982bb28df46ac9
diff --git a/src/doc/nomicon b/src/doc/nomicon
index ad5ddd62c098d..6a8f0a27e9a58 160000
--- a/src/doc/nomicon
+++ b/src/doc/nomicon
@@ -1 +1 @@
-Subproject commit ad5ddd62c098d5b424151beda574ae7df2154df1
+Subproject commit 6a8f0a27e9a58c55c89d07bc43a176fdae5e051c
diff --git a/src/doc/reference b/src/doc/reference
index 254df654a9b75..76296346e97c3 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit 254df654a9b75abf6ca08806535dbe1fad41be3f
+Subproject commit 76296346e97c3702974d3398fdb94af9e10111a2
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index ebb28c95b2ea6..d5ec87eabe573 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit ebb28c95b2ea68b96eddb9e71aff4d32eacc74f0
+Subproject commit d5ec87eabe5733cc2348c7dada89fc67c086f391
diff --git a/src/doc/rustdoc/src/SUMMARY.md b/src/doc/rustdoc/src/SUMMARY.md
index 6315cb81a8495..46528187c1175 100644
--- a/src/doc/rustdoc/src/SUMMARY.md
+++ b/src/doc/rustdoc/src/SUMMARY.md
@@ -5,3 +5,4 @@
 - [The `#[doc]` attribute](the-doc-attribute.md)
 - [Documentation tests](documentation-tests.md)
 - [Passes](passes.md)
+- [Unstable features](unstable-features.md)
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
new file mode 100644
index 0000000000000..16356c20c7069
--- /dev/null
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -0,0 +1,362 @@
+# Unstable features
+
+Rustdoc is under active developement, and like the Rust compiler, some features are only available
+on the nightly releases. Some of these are new and need some more testing before they're able to get
+released to the world at large, and some of them are tied to features in the Rust compiler that are
+themselves unstable. Several features here require a matching `#![feature(...)]` attribute to
+enable, and thus are more fully documented in the [Unstable Book]. Those sections will link over
+there as necessary.
+
+[Unstable Book]: ../unstable-book/index.html
+
+## Nightly-gated functionality
+
+These features just require a nightly build to operate. Unlike the other features on this page,
+these don't need to be "turned on" with a command-line flag or a `#![feature(...)]` attribute in
+your crate. This can give them some subtle fallback modes when used on a stable release, so be
+careful!
+
+### Error numbers for `compile-fail` doctests
+
+As detailed in [the chapter on documentation tests][doctest-attributes], you can add a
+`compile_fail` attribute to a doctest to state that the test should fail to compile. However, on
+nightly, you can optionally add an error number to state that a doctest should emit a specific error
+number:
+
+[doctest-attributes]: documentation-tests.html#attributes
+
+``````markdown
+```compile_fail,E0044
+extern { fn some_func<T>(x: T); }
+```
+``````
+
+This is used by the error index to ensure that the samples that correspond to a given error number
+properly emit that error code. However, these error codes aren't guaranteed to be the only thing
+that a piece of code emits from version to version, so this is unlikely to be stabilized in the
+future.
+
+Attempting to use these error numbers on stable will result in the code sample being interpreted as
+plain text.
+
+### Linking to items by type
+
+As designed in [RFC 1946], Rustdoc can parse paths to items when you use them as links. To resolve
+these type names, it uses the items currently in-scope, either by declaration or by `use` statement.
+For modules, the "active scope" depends on whether the documentation is written outside the module
+(as `///` comments on the `mod` statement) or inside the module (at `//!` comments inside the file
+or block). For all other items, it uses the enclosing module's scope.
+
+[RFC 1946]: https://github.com/rust-lang/rfcs/pull/1946
+
+For example, in the following code:
+
+```rust
+/// Does the thing.
+pub fn do_the_thing(_: SomeType) {
+	println!("Let's do the thing!");
+}
+
+/// Token you use to [`do_the_thing`].
+pub struct SomeType;
+```
+
+The link to ``[`do_the_thing`]`` in `SomeType`'s docs will properly link to the page for `fn
+do_the_thing`. Note that here, rustdoc will insert the link target for you, but manually writing the
+target out also works:
+
+```rust
+pub mod some_module {
+	/// Token you use to do the thing.
+	pub struct SomeStruct;
+}
+
+/// Does the thing. Requires one [`SomeStruct`] for the thing to work.
+///
+/// [`SomeStruct`]: some_module::SomeStruct
+pub fn do_the_thing(_: some_module::SomeStruct) {
+	println!("Let's do the thing!");
+}
+```
+
+For more details, check out [the RFC][RFC 1946], and see [the tracking issue][43466] for more
+information about what parts of the feature are available.
+
+[43466]: https://github.com/rust-lang/rust/issues/43466
+
+## Extensions to the `#[doc]` attribute
+
+These features operate by extending the `#[doc]` attribute, and thus can be caught by the compiler
+and enabled with a `#![feature(...)]` attribute in your crate.
+
+### Documenting platform-/feature-specific information
+
+Because of the way Rustdoc documents a crate, the documentation it creates is specific to the target
+rustc compiles for. Anything that's specific to any other target is dropped via `#[cfg]` attribute
+processing early in the compilation process. However, Rustdoc has a trick up its sleeve to handle
+platform-specific code if it *does* receive it.
+
+Because Rustdoc doesn't need to fully compile a crate to binary, it replaces function bodies with
+`loop {}` to prevent having to process more than necessary. This means that any code within a
+function that requires platform-specific pieces is ignored. Combined with a special attribute,
+`#[doc(cfg(...))]`, you can tell Rustdoc exactly which platform something is supposed to run on,
+ensuring that doctests are only run on the appropriate platforms.
+
+The `#[doc(cfg(...))]` attribute has another effect: When Rustdoc renders documentation for that
+item, it will be accompanied by a banner explaining that the item is only available on certain
+platforms.
+
+As mentioned earlier, getting the items to Rustdoc requires some extra preparation. The standard
+library adds a `--cfg dox` flag to every Rustdoc command, but the same thing can be accomplished by
+adding a feature to your Cargo.toml and adding `--feature dox` (or whatever you choose to name the
+feature) to your `cargo doc` calls.
+
+Either way, once you create an environment for the documentation, you can start to augment your
+`#[cfg]` attributes to allow both the target platform *and* the documentation configuration to leave
+the item in. For example, `#[cfg(any(windows, feature = "dox"))]` will preserve the item either on
+Windows or during the documentation process. Then, adding a new attribute `#[doc(cfg(windows))]`
+will tell Rustdoc that the item is supposed to be used on Windows. For example:
+
+```rust
+#![feature(doc_cfg)]
+
+/// Token struct that can only be used on Windows.
+#[cfg(any(windows, feature = "dox"))]
+#[doc(cfg(windows))]
+pub struct WindowsToken;
+
+/// Token struct that can only be used on Unix.
+#[cfg(any(unix, feature = "dox"))]
+#[doc(cfg(unix))]
+pub struct UnixToken;
+```
+
+In this sample, the tokens will only appear on their respective platforms, but they will both appear
+in documentation.
+
+`#[doc(cfg(...))]` was introduced to be used by the standard library and currently requires the
+`#![feature(doc_cfg)]` feature gate. For more information, see [its chapter in the Unstable
+Book][unstable-doc-cfg] and [its tracking issue][issue-doc-cfg].
+
+[unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html
+[issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781
+
+### Adding your trait to the "Important Traits" dialog
+
+Rustdoc keeps a list of a few traits that are believed to be "fundamental" to a given type when
+implemented on it. These traits are intended to be the primary interface for their types, and are
+often the only thing available to be documented on their types. For this reason, Rustdoc will track
+when a given type implements one of these traits and call special attention to it when a function
+returns one of these types. This is the "Important Traits" dialog, visible as a circle-i button next
+to the function, which, when clicked, shows the dialog.
+
+In the standard library, the traits that qualify for inclusion are `Iterator`, `io::Read`, and
+`io::Write`. However, rather than being implemented as a hard-coded list, these traits have a
+special marker attribute on them: `#[doc(spotlight)]`. This means that you could apply this
+attribute to your own trait to include it in the "Important Traits" dialog in documentation.
+
+The `#[doc(spotlight)]` attribute currently requires the `#![feature(doc_spotlight)]` feature gate.
+For more information, see [its chapter in the Unstable Book][unstable-spotlight] and [its tracking
+issue][issue-spotlight].
+
+[unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html
+[issue-spotlight]: https://github.com/rust-lang/rust/issues/45040
+
+### Exclude certain dependencies from documentation
+
+The standard library uses several dependencies which, in turn, use several types and traits from the
+standard library. In addition, there are several compiler-internal crates that are not considered to
+be part of the official standard library, and thus would be a distraction to include in
+documentation. It's not enough to exclude their crate documentation, since information about trait
+implementations appears on the pages for both the type and the trait, which can be in different
+crates!
+
+To prevent internal types from being included in documentation, the standard library adds an
+attribute to their `extern crate` declarations: `#[doc(masked)]`. This causes Rustdoc to "mask out"
+types from these crates when building lists of trait implementations.
+
+The `#[doc(masked)]` attribute is intended to be used internally, and requires the
+`#![feature(doc_masked)]` feature gate.  For more information, see [its chapter in the Unstable
+Book][unstable-masked] and [its tracking issue][issue-masked].
+
+[unstable-masked]: ../unstable-book/language-features/doc-masked.html
+[issue-masked]: https://github.com/rust-lang/rust/issues/44027
+
+### Include external files as API documentation
+
+As designed in [RFC 1990], Rustdoc can read an external file to use as a type's documentation. This
+is useful if certain documentation is so long that it would break the flow of reading the source.
+Instead of writing it all inline, writing `#[doc(include = "sometype.md")]` (where `sometype.md` is
+a file adjacent to the `lib.rs` for the crate) will ask Rustdoc to instead read that file and use it
+as if it were written inline.
+
+[RFC 1990]: https://github.com/rust-lang/rfcs/pull/1990
+
+`#[doc(include = "...")]` currently requires the `#![feature(external_doc)]` feature gate. For more
+information, see [its chapter in the Unstable Book][unstable-include] and [its tracking
+issue][issue-include].
+
+[unstable-include]: ../unstable-book/language-features/external-doc.html
+[issue-include]: https://github.com/rust-lang/rust/issues/44732
+
+## Unstable command-line arguments
+
+These features are enabled by passing a command-line flag to Rustdoc, but the flags in question are
+themselves marked as unstable. To use any of these options, pass `-Z unstable-options` as well as
+the flag in question to Rustdoc on the command-line. To do this from Cargo, you can either use the
+`RUSTDOCFLAGS` environment variable or the `cargo rustdoc` command.
+
+### `--markdown-before-content`: include rendered Markdown before the content
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --markdown-before-content extra.md
+$ rustdoc README.md -Z unstable-options --markdown-before-content extra.md
+```
+
+Just like `--html-before-content`, this allows you to insert extra content inside the `<body>` tag
+but before the other content `rustdoc` would normally produce in the rendered documentation.
+However, instead of directly inserting the file verbatim, `rustdoc` will pass the files through a
+Markdown renderer before inserting the result into the file.
+
+### `--markdown-after-content`: include rendered Markdown after the content
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --markdown-after-content extra.md
+$ rustdoc README.md -Z unstable-options --markdown-after-content extra.md
+```
+
+Just like `--html-after-content`, this allows you to insert extra content before the `</body>` tag
+but after the other content `rustdoc` would normally produce in the rendered documentation.
+However, instead of directly inserting the file verbatim, `rustdoc` will pass the files through a
+Markdown renderer before inserting the result into the file.
+
+### `--playground-url`: control the location of the playground
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --playground-url https://play.rust-lang.org/
+```
+
+When rendering a crate's docs, this flag gives the base URL of the Rust Playground, to use for
+generating `Run` buttons. Unlike `--markdown-playground-url`, this argument works for standalone
+Markdown files *and* Rust crates. This works the same way as adding `#![doc(html_playground_url =
+"url")]` to your crate root, as mentioned in [the chapter about the `#[doc]`
+attribute][doc-playground]. Please be aware that the official Rust Playground at
+https://play.rust-lang.org does not have every crate available, so if your examples require your
+crate, make sure the playground you provide has your crate available.
+
+[doc-playground]: the-doc-attribute.html#html_playground_url
+
+If both `--playground-url` and `--markdown-playground-url` are present when rendering a standalone
+Markdown file, the URL given to `--markdown-playground-url` will take precedence. If both
+`--playground-url` and `#![doc(html_playground_url = "url")]` are present when rendering crate docs,
+the attribute will take precedence.
+
+### `--crate-version`: control the crate version
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --crate-version 1.3.37
+```
+
+When `rustdoc` receives this flag, it will print an extra "Version (version)" into the sidebar of
+the crate root's docs. You can use this flag to differentiate between different versions of your
+library's documentation.
+
+### `--linker`: control the linker used for documentation tests
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc --test src/lib.rs -Z unstable-options --linker foo
+$ rustdoc --test README.md -Z unstable-options --linker foo
+```
+
+When `rustdoc` runs your documentation tests, it needs to compile and link the tests as executables
+before running them. This flag can be used to change the linker used on these executables. It's
+equivalent to passing `-C linker=foo` to `rustc`.
+
+### `--sort-modules-by-appearance`: control how items on module pages are sorted
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --sort-modules-by-appearance
+```
+
+Ordinarily, when `rustdoc` prints items in module pages, it will sort them alphabetically (taking
+some consideration for their stability, and names that end in a number). Giving this flag to
+`rustdoc` will disable this sorting and instead make it print the items in the order they appear in
+the source.
+
+### `--themes`: provide additional themes
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --themes theme.css
+```
+
+Giving this flag to `rustdoc` will make it copy your theme into the generated crate docs and enable
+it in the theme selector. Note that `rustdoc` will reject your theme file if it doesn't style
+everything the "main" theme does. See `--theme-checker` below for details.
+
+### `--theme-checker`: verify theme CSS for validity
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc -Z unstable-options --theme-checker theme.css
+```
+
+Before including your theme in crate docs, `rustdoc` will compare all the CSS rules it contains
+against the "main" theme included by default. Using this flag will allow you to see which rules are
+missing if `rustdoc` rejects your theme.
+
+### `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --resource-suffix suf
+```
+
+When rendering docs, `rustdoc` creates several CSS and JavaScript files as part of the output. Since
+all these files are linked from every page, changing where they are can be cumbersome if you need to
+specially cache them. This flag will rename all these files in the output to include the suffix in
+the filename. For example, `main.css` would become `main-suf.css` with the above command.
+
+### `--display-warnings`: display warnings when documenting or running documentation tests
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --display-warnings
+$ rustdoc --test src/lib.rs -Z unstable-options --display-warnings
+```
+
+The intent behind this flag is to allow the user to see warnings that occur within their library or
+their documentation tests, which are usually suppressed. However, [due to a
+bug][issue-display-warnings], this flag doesn't 100% work as intended. See the linked issue for
+details.
+
+[issue-display-warnings]: https://github.com/rust-lang/rust/issues/41574
+
+### `-Z force-unstable-if-unmarked`
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z force-unstable-if-unmarked
+```
+
+This is an internal flag intended for the standard library and compiler that applies an
+`#[unstable]` attribute to any dependent crate that doesn't have another stability attribute. This
+allows `rustdoc` to be able to generate documentation for the compiler crates and the standard
+library, as an equivalent command-line argument is provided to `rustc` when building those crates.
diff --git a/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md b/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md
deleted file mode 100644
index e8256469b1450..0000000000000
--- a/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# `advanced_slice_patterns`
-
-The tracking issue for this feature is: [#23121]
-
-[#23121]: https://github.com/rust-lang/rust/issues/23121
-
-See also [`slice_patterns`](language-features/slice-patterns.html).
-
-------------------------
-
-
-The `advanced_slice_patterns` gate lets you use `..` to indicate any number of
-elements inside a pattern matching a slice. This wildcard can only be used once
-for a given array. If there's an identifier before the `..`, the result of the
-slice will be bound to that name. For example:
-
-```rust
-#![feature(advanced_slice_patterns, slice_patterns)]
-
-fn is_symmetric(list: &[u32]) -> bool {
-    match list {
-        &[] | &[_] => true,
-        &[x, ref inside.., y] if x == y => is_symmetric(inside),
-        _ => false
-    }
-}
-
-fn main() {
-    let sym = &[0, 1, 4, 2, 4, 1, 0];
-    assert!(is_symmetric(sym));
-
-    let not_sym = &[0, 1, 7, 2, 4, 1, 0];
-    assert!(!is_symmetric(not_sym));
-}
-```
diff --git a/src/doc/unstable-book/src/language-features/conservative-impl-trait.md b/src/doc/unstable-book/src/language-features/conservative-impl-trait.md
deleted file mode 100644
index 0be6a321103f0..0000000000000
--- a/src/doc/unstable-book/src/language-features/conservative-impl-trait.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# `conservative_impl_trait`
-
-The tracking issue for this feature is: [#34511]
-
-[#34511]: https://github.com/rust-lang/rust/issues/34511
-
-------------------------
-
-The `conservative_impl_trait` feature allows a conservative form of abstract
-return types.
-
-Abstract return types allow a function to hide a concrete return type behind a
-trait interface similar to trait objects, while still generating the same
-statically dispatched code as with concrete types.
-
-## Examples
-
-```rust
-#![feature(conservative_impl_trait)]
-
-fn even_iter() -> impl Iterator<Item=u32> {
-    (0..).map(|n| n * 2)
-}
-
-fn main() {
-    let first_four_even_numbers = even_iter().take(4).collect::<Vec<_>>();
-    assert_eq!(first_four_even_numbers, vec![0, 2, 4, 6]);
-}
-```
-
-## Background
-
-In today's Rust, you can write function signatures like:
-
-````rust,ignore
-fn consume_iter_static<I: Iterator<Item=u8>>(iter: I) { }
-
-fn consume_iter_dynamic(iter: Box<Iterator<Item=u8>>) { }
-````
-
-In both cases, the function does not depend on the exact type of the argument.
-The type held is "abstract", and is assumed only to satisfy a trait bound.
-
-* In the `_static` version using generics, each use of the function is
-  specialized to a concrete, statically-known type, giving static dispatch,
-  inline layout, and other performance wins.
-* In the `_dynamic` version using trait objects, the concrete argument type is
-  only known at runtime using a vtable.
-
-On the other hand, while you can write:
-
-````rust,ignore
-fn produce_iter_dynamic() -> Box<Iterator<Item=u8>> { }
-````
-
-...but you _cannot_ write something like:
-
-````rust,ignore
-fn produce_iter_static() -> Iterator<Item=u8> { }
-````
-
-That is, in today's Rust, abstract return types can only be written using trait
-objects, which can be a significant performance penalty. This RFC proposes
-"unboxed abstract types" as a way of achieving signatures like
-`produce_iter_static`. Like generics, unboxed abstract types guarantee static
-dispatch and inline data layout.
diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md
index e8e2132dca254..8e888de90a951 100644
--- a/src/doc/unstable-book/src/language-features/generators.md
+++ b/src/doc/unstable-book/src/language-features/generators.md
@@ -36,11 +36,11 @@ fn main() {
         return "foo"
     };
 
-    match generator.resume() {
+    match unsafe { generator.resume() } {
         GeneratorState::Yielded(1) => {}
         _ => panic!("unexpected value from resume"),
     }
-    match generator.resume() {
+    match unsafe { generator.resume() } {
         GeneratorState::Complete("foo") => {}
         _ => panic!("unexpected value from resume"),
     }
@@ -69,9 +69,9 @@ fn main() {
     };
 
     println!("1");
-    generator.resume();
+    unsafe { generator.resume() };
     println!("3");
-    generator.resume();
+    unsafe { generator.resume() };
     println!("5");
 }
 ```
@@ -92,7 +92,7 @@ The `Generator` trait in `std::ops` currently looks like:
 pub trait Generator {
     type Yield;
     type Return;
-    fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>;
+    unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>;
 }
 ```
 
@@ -175,8 +175,8 @@ fn main() {
         return ret
     };
 
-    generator.resume();
-    generator.resume();
+    unsafe { generator.resume() };
+    unsafe { generator.resume() };
 }
 ```
 
@@ -200,7 +200,7 @@ fn main() {
             type Yield = i32;
             type Return = &'static str;
 
-            fn resume(&mut self) -> GeneratorState<i32, &'static str> {
+            unsafe fn resume(&mut self) -> GeneratorState<i32, &'static str> {
                 use std::mem;
                 match mem::replace(self, __Generator::Done) {
                     __Generator::Start(s) => {
@@ -223,8 +223,8 @@ fn main() {
         __Generator::Start(ret)
     };
 
-    generator.resume();
-    generator.resume();
+    unsafe { generator.resume() };
+    unsafe { generator.resume() };
 }
 ```
 
diff --git a/src/doc/unstable-book/src/language-features/i128-type.md b/src/doc/unstable-book/src/language-features/i128-type.md
deleted file mode 100644
index a850b7644c3a7..0000000000000
--- a/src/doc/unstable-book/src/language-features/i128-type.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# `i128_type`
-
-The tracking issue for this feature is: [#35118]
-
-[#35118]: https://github.com/rust-lang/rust/issues/35118
-
-------------------------
-
-The `i128_type` feature adds support for 128 bit signed and unsigned integer
-types.
-
-```rust
-#![feature(i128_type)]
-
-fn main() {
-    assert_eq!(1u128 + 1u128, 2u128);
-    assert_eq!(u128::min_value(), 0);
-    assert_eq!(u128::max_value(), 340282366920938463463374607431768211455);
-
-    assert_eq!(1i128 - 2i128, -1i128);
-    assert_eq!(i128::min_value(), -170141183460469231731687303715884105728);
-    assert_eq!(i128::max_value(), 170141183460469231731687303715884105727);
-}
-```
-
diff --git a/src/doc/unstable-book/src/language-features/match-default-bindings.md b/src/doc/unstable-book/src/language-features/match-default-bindings.md
deleted file mode 100644
index cc542931cbe1f..0000000000000
--- a/src/doc/unstable-book/src/language-features/match-default-bindings.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# `match_default_bindings`
-
-The tracking issue for this feature is: [#42640]
-
-[#42640]: https://github.com/rust-lang/rust/issues/42640
-
-------------------------
-
-Match default bindings (also called "default binding modes in match") improves ergonomics for
-pattern-matching on references by introducing automatic dereferencing (and a corresponding shift
-in binding modes) for large classes of patterns that would otherwise not compile.
-
-For example, under match default bindings,
-
-```rust
-#![feature(match_default_bindings)]
-
-fn main() {
-    let x: &Option<_> = &Some(0);
-
-    match x {
-        Some(y) => {
-            println!("y={}", *y);
-        },
-        None => {},
-    }
-}
-```
-
-compiles and is equivalent to either of the below:
-
-```rust
-fn main() {
-    let x: &Option<_> = &Some(0);
-
-    match *x {
-        Some(ref y) => {
-            println!("y={}", *y);
-        },
-        None => {},
-    }
-}
-```
-
-or
-
-```rust
-fn main() {
-    let x: &Option<_> = &Some(0);
-
-    match x {
-        &Some(ref y) => {
-            println!("y={}", *y);
-        },
-        &None => {},
-    }
-}
-```
diff --git a/src/doc/unstable-book/src/language-features/repr128.md b/src/doc/unstable-book/src/language-features/repr128.md
new file mode 100644
index 0000000000000..0858988952c10
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/repr128.md
@@ -0,0 +1,18 @@
+# `repr128`
+
+The tracking issue for this feature is: [#35118]
+
+[#35118]: https://github.com/rust-lang/rust/issues/35118
+
+------------------------
+
+The `repr128` feature adds support for `#[repr(u128)]` on `enum`s.
+
+```rust
+#![feature(repr128)]
+
+#[repr(u128)]
+enum Foo {
+    Bar(u64),
+}
+```
diff --git a/src/doc/unstable-book/src/language-features/slice-patterns.md b/src/doc/unstable-book/src/language-features/slice-patterns.md
index 69857297582da..133174268ef93 100644
--- a/src/doc/unstable-book/src/language-features/slice-patterns.md
+++ b/src/doc/unstable-book/src/language-features/slice-patterns.md
@@ -4,25 +4,29 @@ The tracking issue for this feature is: [#23121]
 
 [#23121]: https://github.com/rust-lang/rust/issues/23121
 
-See also
-[`advanced_slice_patterns`](language-features/advanced-slice-patterns.html).
-
 ------------------------
 
-
-If you want to match against a slice or array, you can use `&` with the
-`slice_patterns` feature:
+The `slice_patterns` feature gate lets you use `..` to indicate any number of
+elements inside a pattern matching a slice. This wildcard can only be used once
+for a given array. If there's an pattern before the `..`, the subslice will be
+matched against that pattern. For example:
 
 ```rust
 #![feature(slice_patterns)]
 
+fn is_symmetric(list: &[u32]) -> bool {
+    match list {
+        &[] | &[_] => true,
+        &[x, ref inside.., y] if x == y => is_symmetric(inside),
+        &[..] => false,
+    }
+}
+
 fn main() {
-    let v = vec!["match_this", "1"];
+    let sym = &[0, 1, 4, 2, 4, 1, 0];
+    assert!(is_symmetric(sym));
 
-    match &v[..] {
-        &["match_this", second] => println!("The second element is {}", second),
-        _ => {},
-    }
+    let not_sym = &[0, 1, 7, 2, 4, 1, 0];
+    assert!(!is_symmetric(not_sym));
 }
 ```
-
diff --git a/src/doc/unstable-book/src/language-features/universal-impl-trait.md b/src/doc/unstable-book/src/language-features/universal-impl-trait.md
deleted file mode 100644
index 6b3c5e92720df..0000000000000
--- a/src/doc/unstable-book/src/language-features/universal-impl-trait.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# `universal_impl_trait`
-
-The tracking issue for this feature is: [#34511].
-
-[#34511]: https://github.com/rust-lang/rust/issues/34511
-
---------------------
-
-The `universal_impl_trait` feature extends the [`conservative_impl_trait`]
-feature allowing the `impl Trait` syntax in arguments (universal
-quantification).
-
-[`conservative_impl_trait`]: ./language-features/conservative-impl-trait.html
-
-## Examples
-
-```rust
-#![feature(universal_impl_trait)]
-use std::ops::Not;
-
-fn any_zero(values: impl IntoIterator<Item = i32>) -> bool {
-    for val in values { if val == 0 { return true; } }
-    false
-}
-
-fn main() {
-    let test1 = -5..;
-    let test2 = vec![1, 8, 42, -87, 60];
-    assert!(any_zero(test1));
-    assert!(bool::not(any_zero(test2)));
-}
-```
diff --git a/src/etc/cat-and-grep.sh b/src/etc/cat-and-grep.sh
index ef9884d2e980d..361e8d8e60eed 100755
--- a/src/etc/cat-and-grep.sh
+++ b/src/etc/cat-and-grep.sh
@@ -63,6 +63,11 @@ done
 
 shift $((OPTIND - 1))
 
+# use gnu version of tool if available (for bsd)
+if command -v "g${GREPPER}"; then
+    GREPPER="g${GREPPER}"
+fi
+
 LOG=$(mktemp -t cgrep.XXXXXX)
 trap "rm -f $LOG" EXIT
 
diff --git a/src/liballoc/benches/lib.rs b/src/liballoc/benches/lib.rs
index 2de0ffb4b2611..a43aadfe9a23a 100644
--- a/src/liballoc/benches/lib.rs
+++ b/src/liballoc/benches/lib.rs
@@ -10,9 +10,10 @@
 
 #![deny(warnings)]
 
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(rand)]
 #![feature(repr_simd)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(test)]
 
 extern crate rand;
diff --git a/src/liballoc/benches/slice.rs b/src/liballoc/benches/slice.rs
index ee5182a1d4663..a699ff9c0a76e 100644
--- a/src/liballoc/benches/slice.rs
+++ b/src/liballoc/benches/slice.rs
@@ -284,6 +284,17 @@ macro_rules! sort_expensive {
     }
 }
 
+macro_rules! sort_lexicographic {
+    ($f:ident, $name:ident, $gen:expr, $len:expr) => {
+        #[bench]
+        fn $name(b: &mut Bencher) {
+            let v = $gen($len);
+            b.iter(|| v.clone().$f(|x| x.to_string()));
+            b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
+        }
+    }
+}
+
 sort!(sort, sort_small_ascending, gen_ascending, 10);
 sort!(sort, sort_small_descending, gen_descending, 10);
 sort!(sort, sort_small_random, gen_random, 10);
@@ -312,6 +323,10 @@ sort!(sort_unstable, sort_unstable_large_big, gen_big_random, 10000);
 sort_strings!(sort_unstable, sort_unstable_large_strings, gen_strings, 10000);
 sort_expensive!(sort_unstable_by, sort_unstable_large_expensive, gen_random, 10000);
 
+sort_lexicographic!(sort_by_key, sort_by_key_lexicographic, gen_random, 10000);
+sort_lexicographic!(sort_unstable_by_key, sort_unstable_by_key_lexicographic, gen_random, 10000);
+sort_lexicographic!(sort_by_cached_key, sort_by_cached_key_lexicographic, gen_random, 10000);
+
 macro_rules! reverse {
     ($name:ident, $ty:ty, $f:expr) => {
         #[bench]
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index b776556d59f11..bfd806f99e784 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -64,8 +64,8 @@ use core::cmp::Ordering;
 use core::fmt;
 use core::hash::{self, Hash, Hasher};
 use core::iter::FusedIterator;
-use core::marker::{self, Unsize};
-use core::mem;
+use core::marker::{self, Unpin, Unsize};
+use core::mem::{self, Pin};
 use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
 use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer};
 use core::ptr::{self, NonNull, Unique};
@@ -892,7 +892,104 @@ impl<T> Generator for Box<T>
 {
     type Yield = T::Yield;
     type Return = T::Return;
-    fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
+    unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
         (**self).resume()
     }
 }
+
+/// A pinned, heap allocated reference.
+#[unstable(feature = "pin", issue = "49150")]
+#[fundamental]
+pub struct PinBox<T: ?Sized> {
+    inner: Box<T>,
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T> PinBox<T> {
+    /// Allocate memory on the heap, move the data into it and pin it.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub fn new(data: T) -> PinBox<T> {
+        PinBox { inner: Box::new(data) }
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized> PinBox<T> {
+    /// Get a pinned reference to the data in this PinBox.
+    pub fn as_pin<'a>(&'a mut self) -> Pin<'a, T> {
+        unsafe { Pin::new_unchecked(&mut *self.inner) }
+    }
+
+    /// Get a mutable reference to the data inside this PinBox.
+    ///
+    /// This function is unsafe. Users must guarantee that the data is never
+    /// moved out of this reference.
+    pub unsafe fn get_mut<'a>(this: &'a mut PinBox<T>) -> &'a mut T {
+        &mut *this.inner
+    }
+
+    /// Convert this PinBox into an unpinned Box.
+    ///
+    /// This function is unsafe. Users must guarantee that the data is never
+    /// moved out of the box.
+    pub unsafe fn unpin(this: PinBox<T>) -> Box<T> {
+        this.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized> From<Box<T>> for PinBox<T> {
+    fn from(boxed: Box<T>) -> PinBox<T> {
+        PinBox { inner: boxed }
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: Unpin + ?Sized> From<PinBox<T>> for Box<T> {
+    fn from(pinned: PinBox<T>) -> Box<T> {
+        pinned.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized> Deref for PinBox<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &*self.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: Unpin + ?Sized> DerefMut for PinBox<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut *self.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: fmt::Display + ?Sized> fmt::Display for PinBox<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&*self.inner, f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: fmt::Debug + ?Sized> fmt::Debug for PinBox<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&*self.inner, f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized> fmt::Pointer for PinBox<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // It's not possible to extract the inner Uniq directly from the Box,
+        // instead we cast it to a *const which aliases the Unique
+        let ptr: *const T = &*self.inner;
+        fmt::Pointer::fmt(&ptr, f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinBox<U>> for PinBox<T> {}
diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs
index ed9c8c18f0d6d..cada190032aa0 100644
--- a/src/liballoc/btree/map.rs
+++ b/src/liballoc/btree/map.rs
@@ -576,6 +576,33 @@ impl<K: Ord, V> BTreeMap<K, V> {
         }
     }
 
+    /// Returns the key-value pair corresponding to the supplied key.
+    ///
+    /// The supplied key may be any borrowed form of the map's key type, but the ordering
+    /// on the borrowed form *must* match the ordering on the key type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(map_get_key_value)]
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map = BTreeMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
+    /// assert_eq!(map.get_key_value(&2), None);
+    /// ```
+    #[unstable(feature = "map_get_key_value", issue = "49347")]
+    pub fn get_key_value<Q: ?Sized>(&self, k: &Q) -> Option<(&K, &V)>
+        where K: Borrow<Q>,
+              Q: Ord
+    {
+        match search::search_tree(self.root.as_ref(), k) {
+            Found(handle) => Some(handle.into_kv()),
+            GoDown(_) => None,
+        }
+    }
+
     /// Returns `true` if the map contains a value for the specified key.
     ///
     /// The key may be any borrowed form of the map's key type, but the ordering
diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs
index a092bfb3b0a8a..b2c4582e8406f 100644
--- a/src/liballoc/fmt.rs
+++ b/src/liballoc/fmt.rs
@@ -113,6 +113,8 @@
 //!
 //! * *nothing* ⇒ [`Display`]
 //! * `?` ⇒ [`Debug`]
+//! * `x?` ⇒ [`Debug`] with lower-case hexadecimal integers
+//! * `X?` ⇒ [`Debug`] with upper-case hexadecimal integers
 //! * `o` ⇒ [`Octal`](trait.Octal.html)
 //! * `x` ⇒ [`LowerHex`](trait.LowerHex.html)
 //! * `X` ⇒ [`UpperHex`](trait.UpperHex.html)
@@ -324,7 +326,7 @@
 //! sign := '+' | '-'
 //! width := count
 //! precision := count | '*'
-//! type := identifier | ''
+//! type := identifier | '?' | ''
 //! count := parameter | integer
 //! parameter := argument '$'
 //! ```
@@ -514,17 +516,17 @@ pub use core::fmt::rt;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::fmt::{Formatter, Result, Write};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use core::fmt::{Octal, Binary};
+pub use core::fmt::{Binary, Octal};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use core::fmt::{Display, Debug};
+pub use core::fmt::{Debug, Display};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use core::fmt::{LowerHex, UpperHex, Pointer};
+pub use core::fmt::{LowerHex, Pointer, UpperHex};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::fmt::{LowerExp, UpperExp};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::fmt::Error;
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use core::fmt::{ArgumentV1, Arguments, write};
+pub use core::fmt::{write, ArgumentV1, Arguments};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
 
@@ -561,7 +563,8 @@ use string;
 pub fn format(args: Arguments) -> string::String {
     let capacity = args.estimated_capacity();
     let mut output = string::String::with_capacity(capacity);
-    output.write_fmt(args)
-          .expect("a formatting trait implementation returned an error");
+    output
+        .write_fmt(args)
+        .expect("a formatting trait implementation returned an error");
     output
 }
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 2727bcaa28a93..19d64d8fea9ec 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -97,7 +97,7 @@
 #![feature(from_ref)]
 #![feature(fundamental)]
 #![feature(generic_param_attrs)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(iter_rfold)]
 #![feature(lang_items)]
 #![feature(needs_allocator)]
@@ -105,12 +105,12 @@
 #![feature(offset_to)]
 #![feature(optin_builtin_traits)]
 #![feature(pattern)]
+#![feature(pin)]
 #![feature(placement_in_syntax)]
 #![feature(placement_new_protocol)]
 #![feature(ptr_internals)]
 #![feature(rustc_attrs)]
 #![feature(slice_get_slice)]
-#![feature(slice_patterns)]
 #![feature(slice_rsplit)]
 #![feature(specialization)]
 #![feature(staged_api)]
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index dc40062ef13df..68f2313843c31 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -102,6 +102,7 @@ use core::mem::size_of;
 use core::mem;
 use core::ptr;
 use core::slice as core_slice;
+use core::{u8, u16, u32};
 
 use borrow::{Borrow, BorrowMut, ToOwned};
 use boxed::Box;
@@ -1302,7 +1303,8 @@ impl<T> [T] {
 
     /// Sorts the slice with a key extraction function.
     ///
-    /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
+    /// This sort is stable (i.e. does not reorder equal elements) and `O(m n log(m n))`
+    /// worst-case, where the key function is `O(m)`.
     ///
     /// When applicable, unstable sorting is preferred because it is generally faster than stable
     /// sorting and it doesn't allocate auxiliary memory.
@@ -1328,12 +1330,82 @@ impl<T> [T] {
     /// ```
     #[stable(feature = "slice_sort_by_key", since = "1.7.0")]
     #[inline]
-    pub fn sort_by_key<B, F>(&mut self, mut f: F)
-        where F: FnMut(&T) -> B, B: Ord
+    pub fn sort_by_key<K, F>(&mut self, mut f: F)
+        where F: FnMut(&T) -> K, K: Ord
     {
         merge_sort(self, |a, b| f(a).lt(&f(b)));
     }
 
+    /// Sorts the slice with a key extraction function.
+    ///
+    /// During sorting, the key function is called only once per element.
+    ///
+    /// This sort is stable (i.e. does not reorder equal elements) and `O(m n + n log n)`
+    /// worst-case, where the key function is `O(m)`.
+    ///
+    /// For simple key functions (e.g. functions that are property accesses or
+    /// basic operations), [`sort_by_key`](#method.sort_by_key) is likely to be
+    /// faster.
+    ///
+    /// # Current implementation
+    ///
+    /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters,
+    /// which combines the fast average case of randomized quicksort with the fast worst case of
+    /// heapsort, while achieving linear time on slices with certain patterns. It uses some
+    /// randomization to avoid degenerate cases, but with a fixed seed to always provide
+    /// deterministic behavior.
+    ///
+    /// In the worst case, the algorithm allocates temporary storage in a `Vec<(K, usize)>` the
+    /// length of the slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_sort_by_cached_key)]
+    /// let mut v = [-5i32, 4, 32, -3, 2];
+    ///
+    /// v.sort_by_cached_key(|k| k.to_string());
+    /// assert!(v == [-3, -5, 2, 32, 4]);
+    /// ```
+    ///
+    /// [pdqsort]: https://github.com/orlp/pdqsort
+    #[unstable(feature = "slice_sort_by_cached_key", issue = "34447")]
+    #[inline]
+    pub fn sort_by_cached_key<K, F>(&mut self, f: F)
+        where F: FnMut(&T) -> K, K: Ord
+    {
+        // Helper macro for indexing our vector by the smallest possible type, to reduce allocation.
+        macro_rules! sort_by_key {
+            ($t:ty, $slice:ident, $f:ident) => ({
+                let mut indices: Vec<_> =
+                    $slice.iter().map($f).enumerate().map(|(i, k)| (k, i as $t)).collect();
+                // The elements of `indices` are unique, as they are indexed, so any sort will be
+                // stable with respect to the original slice. We use `sort_unstable` here because
+                // it requires less memory allocation.
+                indices.sort_unstable();
+                for i in 0..$slice.len() {
+                    let mut index = indices[i].1;
+                    while (index as usize) < i {
+                        index = indices[index as usize].1;
+                    }
+                    indices[i].1 = index;
+                    $slice.swap(i, index as usize);
+                }
+            })
+        }
+
+        let sz_u8    = mem::size_of::<(K, u8)>();
+        let sz_u16   = mem::size_of::<(K, u16)>();
+        let sz_u32   = mem::size_of::<(K, u32)>();
+        let sz_usize = mem::size_of::<(K, usize)>();
+
+        let len = self.len();
+        if sz_u8  < sz_u16   && len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) }
+        if sz_u16 < sz_u32   && len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) }
+        if sz_u32 < sz_usize && len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) }
+        sort_by_key!(usize, self, f)
+    }
+
     /// Sorts the slice, but may not preserve the order of equal elements.
     ///
     /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
@@ -1410,7 +1482,7 @@ impl<T> [T] {
     /// elements.
     ///
     /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
-    /// and `O(n log n)` worst-case.
+    /// and `O(m n log(m n))` worst-case, where the key function is `O(m)`.
     ///
     /// # Current implementation
     ///
@@ -1420,9 +1492,6 @@ impl<T> [T] {
     /// randomization to avoid degenerate cases, but with a fixed seed to always provide
     /// deterministic behavior.
     ///
-    /// It is typically faster than stable sorting, except in a few special cases, e.g. when the
-    /// slice consists of several concatenated sorted sequences.
-    ///
     /// # Examples
     ///
     /// ```
@@ -1435,9 +1504,8 @@ impl<T> [T] {
     /// [pdqsort]: https://github.com/orlp/pdqsort
     #[stable(feature = "sort_unstable", since = "1.20.0")]
     #[inline]
-    pub fn sort_unstable_by_key<B, F>(&mut self, f: F)
-        where F: FnMut(&T) -> B,
-              B: Ord
+    pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
+        where F: FnMut(&T) -> K, K: Ord
     {
         core_slice::SliceExt::sort_unstable_by_key(self, f);
     }
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 14d5e96d2e73a..d5ef41df0d850 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -2122,6 +2122,48 @@ impl str {
         unsafe { String::from_utf8_unchecked(buf) }
     }
 
+    /// Returns true if this `str` is entirely whitespace, and false otherwise.
+    ///
+    /// 'Whitespace' is defined according to the terms of the Unicode Derived Core
+    /// Property `White_Space`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// assert!("    \t ".is_whitespace());
+    ///
+    /// // a non-breaking space
+    /// assert!("\u{A0}".is_whitespace());
+    ///
+    /// assert!(!"   越".is_whitespace());
+    /// ```
+    #[stable(feature = "unicode_methods_on_intrinsics", since = "1.27.0")]
+    #[inline]
+    pub fn is_whitespace(&self) -> bool {
+        UnicodeStr::is_whitespace(self)
+    }
+
+    /// Returns true if this `str` is entirely alphanumeric, and false otherwise.
+    ///
+    /// 'Alphanumeric'-ness is defined in terms of the Unicode General Categories
+    /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// assert!("٣7৬Kو藏".is_alphanumeric());
+    /// assert!(!"¾①".is_alphanumeric());
+    /// ```
+    #[stable(feature = "unicode_methods_on_intrinsics", since = "1.27.0")]
+    #[inline]
+    pub fn is_alphanumeric(&self) -> bool {
+        UnicodeStr::is_alphanumeric(self)
+    }
+
     /// Checks if all characters in this string are within the ASCII range.
     ///
     /// # Examples
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 9fec90914985d..e253122ffd6b6 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -1576,7 +1576,6 @@ impl FromUtf8Error {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(from_utf8_error_as_bytes)]
     /// // some invalid bytes, in a vector
     /// let bytes = vec![0, 159];
     ///
@@ -1584,7 +1583,7 @@ impl FromUtf8Error {
     ///
     /// assert_eq!(&[0, 159], value.unwrap_err().as_bytes());
     /// ```
-    #[unstable(feature = "from_utf8_error_as_bytes", reason = "recently added", issue = "40895")]
+    #[stable(feature = "from_utf8_error_as_bytes", since = "1.26.0")]
     pub fn as_bytes(&self) -> &[u8] {
         &self.bytes[..]
     }
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index bcd2ef2760583..0a7e9a8be94f9 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -23,6 +23,7 @@
 #![feature(pattern)]
 #![feature(placement_in_syntax)]
 #![feature(rand)]
+#![feature(slice_sort_by_cached_key)]
 #![feature(splice)]
 #![feature(str_escape)]
 #![feature(string_retain)]
diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs
index d9e9d91cea88a..99d9c51efc757 100644
--- a/src/liballoc/tests/slice.rs
+++ b/src/liballoc/tests/slice.rs
@@ -425,6 +425,14 @@ fn test_sort() {
                 v.sort_by(|a, b| b.cmp(a));
                 assert!(v.windows(2).all(|w| w[0] >= w[1]));
 
+                // Sort in lexicographic order.
+                let mut v1 = orig.clone();
+                let mut v2 = orig.clone();
+                v1.sort_by_key(|x| x.to_string());
+                v2.sort_by_cached_key(|x| x.to_string());
+                assert!(v1.windows(2).all(|w| w[0].to_string() <= w[1].to_string()));
+                assert!(v1 == v2);
+
                 // Sort with many pre-sorted runs.
                 let mut v = orig.clone();
                 v.sort();
@@ -477,7 +485,7 @@ fn test_sort_stability() {
             // the second item represents which occurrence of that
             // number this element is, i.e. the second elements
             // will occur in sorted order.
-            let mut v: Vec<_> = (0..len)
+            let mut orig: Vec<_> = (0..len)
                 .map(|_| {
                     let n = thread_rng().gen::<usize>() % 10;
                     counts[n] += 1;
@@ -485,16 +493,21 @@ fn test_sort_stability() {
                 })
                 .collect();
 
-            // only sort on the first element, so an unstable sort
+            let mut v = orig.clone();
+            // Only sort on the first element, so an unstable sort
             // may mix up the counts.
             v.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
 
-            // this comparison includes the count (the second item
+            // This comparison includes the count (the second item
             // of the tuple), so elements with equal first items
             // will need to be ordered with increasing
             // counts... i.e. exactly asserting that this sort is
             // stable.
             assert!(v.windows(2).all(|w| w[0] <= w[1]));
+
+            let mut v = orig.clone();
+            v.sort_by_cached_key(|&(x, _)| x);
+            assert!(v.windows(2).all(|w| w[0] <= w[1]));
         }
     }
 }
@@ -1351,7 +1364,7 @@ fn test_copy_from_slice_dst_shorter() {
 const MAX_LEN: usize = 80;
 
 static DROP_COUNTS: [AtomicUsize; MAX_LEN] = [
-    // FIXME #5244: AtomicUsize is not Copy.
+    // FIXME(RFC 1109): AtomicUsize is not Copy.
     AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
     AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
     AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins
index 266ea0740a5bd..2a2f6d96c8dc5 160000
--- a/src/libcompiler_builtins
+++ b/src/libcompiler_builtins
@@ -1 +1 @@
-Subproject commit 266ea0740a5bdd262a38bbd88fb55fc3d2a7a96e
+Subproject commit 2a2f6d96c8dc578d2474742f14c9bab0b36b0408
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 3d24f8902bd83..87144c27c9e11 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -59,7 +59,7 @@ unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
 }
 
 /// The error type returned when a conversion from a slice to an array fails.
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 #[derive(Debug, Copy, Clone)]
 pub struct TryFromSliceError(());
 
@@ -148,7 +148,7 @@ macro_rules! array_impls {
                 }
             }
 
-            #[unstable(feature = "try_from", issue = "33417")]
+            #[stable(feature = "try_from", since = "1.26.0")]
             impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
                 type Error = TryFromSliceError;
 
@@ -162,7 +162,7 @@ macro_rules! array_impls {
                 }
             }
 
-            #[unstable(feature = "try_from", issue = "33417")]
+            #[stable(feature = "try_from", since = "1.26.0")]
             impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
                 type Error = TryFromSliceError;
 
diff --git a/src/libcore/benches/lib.rs b/src/libcore/benches/lib.rs
index 201064e823b1e..c947b003ccbff 100644
--- a/src/libcore/benches/lib.rs
+++ b/src/libcore/benches/lib.rs
@@ -11,7 +11,6 @@
 #![deny(warnings)]
 
 #![feature(flt2dec)]
-#![feature(slice_patterns)]
 #![feature(test)]
 
 extern crate core;
diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs
index 61558034e63eb..f45a32d4b94ac 100644
--- a/src/libcore/borrow.rs
+++ b/src/libcore/borrow.rs
@@ -14,24 +14,154 @@
 
 /// A trait for borrowing data.
 ///
-/// In general, there may be several ways to "borrow" a piece of data.  The
-/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
-/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
-/// borrows: the borrowed slices `&[T]` and `&mut [T]`.
+/// In Rust, it is common to provide different representations of a type for
+/// different use cases. For instance, storage location and management for a
+/// value can be specifically chosen as appropriate for a particular use via
+/// pointer types such as [`Box<T>`] or [`Rc<T>`]. Beyond these generic
+/// wrappers that can be used with any type, some types provide optional
+/// facets providing potentially costly functionality. An example for such a
+/// type is [`String`] which adds the ability to extend a string to the basic
+/// [`str`]. This requires keeping additional information unnecessary for a
+/// simple, immutable string.
 ///
-/// When writing generic code, it is often desirable to abstract over all ways
-/// of borrowing data from a given type. That is the role of the `Borrow`
-/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
-/// type can be borrowed as multiple different types. In particular, `Vec<T>:
-/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
+/// These types provide access to the underlying data through references
+/// to the type of that data. They are said to be ‘borrowed as’ that type.
+/// For instance, a [`Box<T>`] can be borrowed as `T` while a [`String`]
+/// can be borrowed as `str`.
 ///
-/// If you are implementing `Borrow` and both `Self` and `Borrowed` implement
-/// `Hash`, `Eq`, and/or `Ord`, they must produce the same result.
+/// Types express that they can be borrowed as some type `T` by implementing
+/// `Borrow<T>`, providing a reference to a `T` in the trait’s
+/// [`borrow`] method. A type is free to borrow as several different types.
+/// If it wishes to mutably borrow as the type – allowing the underlying data
+/// to be modified, it can additionally implement [`BorrowMut<T>`].
 ///
-/// `Borrow` is very similar to, but different than, `AsRef`. See
-/// [the book][book] for more.
+/// Further, when providing implementations for additional traits, it needs
+/// to be considered whether they should behave identical to those of the
+/// underlying type as a consequence of acting as a representation of that
+/// underlying type. Generic code typically uses `Borrow<T>` when it relies
+/// on the identical behavior of these additional trait implementations.
+/// These traits will likely appear as additional trait bounds.
 ///
-/// [book]: ../../book/first-edition/borrow-and-asref.html
+/// If generic code merely needs to work for all types that can
+/// provide a reference to related type `T`, it is often better to use
+/// [`AsRef<T>`] as more types can safely implement it.
+///
+/// [`AsRef<T>`]: ../../std/convert/trait.AsRef.html
+/// [`BorrowMut<T>`]: trait.BorrowMut.html
+/// [`Box<T>`]: ../../std/boxed/struct.Box.html
+/// [`Mutex<T>`]: ../../std/sync/struct.Mutex.html
+/// [`Rc<T>`]: ../../std/rc/struct.Rc.html
+/// [`str`]: ../../std/primitive.str.html
+/// [`String`]: ../../std/string/struct.String.html
+/// [`borrow`]: #tymethod.borrow
+///
+/// # Examples
+///
+/// As a data collection, [`HashMap<K, V>`] owns both keys and values. If
+/// the key’s actual data is wrapped in a managing type of some kind, it
+/// should, however, still be possible to search for a value using a
+/// reference to the key’s data. For instance, if the key is a string, then
+/// it is likely stored with the hash map as a [`String`], while it should
+/// be possible to search using a [`&str`][`str`]. Thus, `insert` needs to
+/// operate on a `String` while `get` needs to be able to use a `&str`.
+///
+/// Slightly simplified, the relevant parts of `HashMap<K, V>` look like
+/// this:
+///
+/// ```
+/// use std::borrow::Borrow;
+/// use std::hash::Hash;
+///
+/// pub struct HashMap<K, V> {
+///     # marker: ::std::marker::PhantomData<(K, V)>,
+///     // fields omitted
+/// }
+///
+/// impl<K, V> HashMap<K, V> {
+///     pub fn insert(&self, key: K, value: V) -> Option<V>
+///     where K: Hash + Eq
+///     {
+///         # unimplemented!()
+///         // ...
+///     }
+///
+///     pub fn get<Q>(&self, k: &Q) -> Option<&V>
+///     where
+///         K: Borrow<Q>,
+///         Q: Hash + Eq + ?Sized
+///     {
+///         # unimplemented!()
+///         // ...
+///     }
+/// }
+/// ```
+///
+/// The entire hash map is generic over a key type `K`. Because these keys
+/// are stored with the hash map, this type has to own the key’s data.
+/// When inserting a key-value pair, the map is given such a `K` and needs
+/// to find the correct hash bucket and check if the key is already present
+/// based on that `K`. It therefore requires `K: Hash + Eq`.
+///
+/// When searching for a value in the map, however, having to provide a
+/// reference to a `K` as the key to search for would require to always
+/// create such an owned value. For string keys, this would mean a `String`
+/// value needs to be created just for the search for cases where only a
+/// `str` is available.
+///
+/// Instead, the `get` method is generic over the type of the underlying key
+/// data, called `Q` in the method signature above. It states that `K`
+/// borrows as a `Q` by requiring that `K: Borrow<Q>`. By additionally
+/// requiring `Q: Hash + Eq`, it signals the requirement that `K` and `Q`
+/// have implementations of the `Hash` and `Eq` traits that produce identical
+/// results.
+///
+/// The implementation of `get` relies in particular on identical
+/// implementations of `Hash` by determining the key’s hash bucket by calling
+/// `Hash::hash` on the `Q` value even though it inserted the key based on
+/// the hash value calculated from the `K` value.
+///
+/// As a consequence, the hash map breaks if a `K` wrapping a `Q` value
+/// produces a different hash than `Q`. For instance, imagine you have a
+/// type that wraps a string but compares ASCII letters ignoring their case:
+///
+/// ```
+/// pub struct CaseInsensitiveString(String);
+///
+/// impl PartialEq for CaseInsensitiveString {
+///     fn eq(&self, other: &Self) -> bool {
+///         self.0.eq_ignore_ascii_case(&other.0)
+///     }
+/// }
+///
+/// impl Eq for CaseInsensitiveString { }
+/// ```
+///
+/// Because two equal values need to produce the same hash value, the
+/// implementation of `Hash` needs to ignore ASCII case, too:
+///
+/// ```
+/// # use std::hash::{Hash, Hasher};
+/// # pub struct CaseInsensitiveString(String);
+/// impl Hash for CaseInsensitiveString {
+///     fn hash<H: Hasher>(&self, state: &mut H) {
+///         for c in self.0.as_bytes() {
+///             c.to_ascii_lowercase().hash(state)
+///         }
+///     }
+/// }
+/// ```
+///
+/// Can `CaseInsensitiveString` implement `Borrow<str>`? It certainly can
+/// provide a reference to a string slice via its contained owned string.
+/// But because its `Hash` implementation differs, it behaves differently
+/// from `str` and therefore must not, in fact, implement `Borrow<str>`.
+/// If it wants to allow others access to the underlying `str`, it can do
+/// that via `AsRef<str>` which doesn’t carry any extra requirements.
+///
+/// [`Hash`]: ../../std/hash/trait.Hash.html
+/// [`HashMap<K, V>`]: ../../std/collections/struct.HashMap.html
+/// [`String`]: ../../std/string/struct.String.html
+/// [`str`]: ../../std/primitive.str.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Borrow<Borrowed: ?Sized> {
     /// Immutably borrows from an owned value.
@@ -59,7 +189,11 @@ pub trait Borrow<Borrowed: ?Sized> {
 
 /// A trait for mutably borrowing data.
 ///
-/// Similar to `Borrow`, but for mutable borrows.
+/// As a companion to [`Borrow<T>`] this trait allows a type to borrow as
+/// an underlying type by providing a mutable reference. See [`Borrow<T>`]
+/// for more information on borrowing as another type.
+///
+/// [`Borrow<T>`]: trait.Borrow.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
     /// Mutably borrows from an owned value.
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 1638f9710f597..bbeebf52a73c1 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -265,7 +265,7 @@ impl FromStr for char {
 }
 
 
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl TryFrom<u32> for char {
     type Error = CharTryFromError;
 
@@ -280,11 +280,11 @@ impl TryFrom<u32> for char {
 }
 
 /// The error type returned when a conversion from u32 to char fails.
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct CharTryFromError(());
 
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl fmt::Display for CharTryFromError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         "converted integer out of range for `char`".fmt(f)
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index 826420a0c001c..d25f498b99efe 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -63,6 +63,11 @@
 /// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d
 /// implementation of [`clone`] calls [`clone`] on each field.
 ///
+/// ## Closures
+///
+/// Closure types automatically implement `Clone` if they capture no value from the environment
+/// or if all such captured values implement `Clone` themselves.
+///
 /// ## How can I implement `Clone`?
 ///
 /// Types that are [`Copy`] should have a trivial implementation of `Clone`. More formally:
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index d3a83dc795c85..637213957848c 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -48,25 +48,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use fmt;
-
-/// A type used as the error type for implementations of fallible conversion
-/// traits in cases where conversions cannot actually fail.
-///
-/// Because `Infallible` has no variants, a value of this type can never exist.
-/// It is used only to satisfy trait signatures that expect an error type, and
-/// signals to both the compiler and the user that the error case is impossible.
-#[unstable(feature = "try_from", issue = "33417")]
-#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
-pub enum Infallible {}
-
-#[unstable(feature = "try_from", issue = "33417")]
-impl fmt::Display for Infallible {
-    fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-        }
-    }
-}
 /// A cheap reference-to-reference conversion. Used to convert a value to a
 /// reference value within generic code.
 ///
@@ -341,22 +322,26 @@ pub trait From<T>: Sized {
 ///
 /// [`TryFrom`]: trait.TryFrom.html
 /// [`Into`]: trait.Into.html
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 pub trait TryInto<T>: Sized {
     /// The type returned in the event of a conversion error.
+    #[stable(feature = "try_from", since = "1.26.0")]
     type Error;
 
     /// Performs the conversion.
+    #[stable(feature = "try_from", since = "1.26.0")]
     fn try_into(self) -> Result<T, Self::Error>;
 }
 
 /// Attempt to construct `Self` via a conversion.
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 pub trait TryFrom<T>: Sized {
     /// The type returned in the event of a conversion error.
+    #[stable(feature = "try_from", since = "1.26.0")]
     type Error;
 
     /// Performs the conversion.
+    #[stable(feature = "try_from", since = "1.26.0")]
     fn try_from(value: T) -> Result<Self, Self::Error>;
 }
 
@@ -382,7 +367,7 @@ impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U>
     }
 }
 
-// FIXME (#23442): replace the above impls for &/&mut with the following more general one:
+// FIXME (#45742): replace the above impls for &/&mut with the following more general one:
 // // As lifts over Deref
 // impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> {
 //     fn as_ref(&self) -> &U {
@@ -399,7 +384,7 @@ impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U>
     }
 }
 
-// FIXME (#23442): replace the above impl for &mut with the following more general one:
+// FIXME (#45742): replace the above impl for &mut with the following more general one:
 // // AsMut lifts over DerefMut
 // impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> {
 //     fn as_mut(&mut self) -> &mut U {
@@ -424,7 +409,7 @@ impl<T> From<T> for T {
 
 
 // TryFrom implies TryInto
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl<T, U> TryInto<U> for T where U: TryFrom<T>
 {
     type Error = U::Error;
@@ -436,9 +421,9 @@ impl<T, U> TryInto<U> for T where U: TryFrom<T>
 
 // Infallible conversions are semantically equivalent to fallible conversions
 // with an uninhabited error type.
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl<T, U> TryFrom<U> for T where T: From<U> {
-    type Error = Infallible;
+    type Error = !;
 
     fn try_from(value: U) -> Result<Self, Self::Error> {
         Ok(T::from(value))
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 67126b496e211..62994ed15cc6d 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -333,7 +333,7 @@ impl<'a> ArgumentV1<'a> {
 
 // flags available in the v1 format of format_args
 #[derive(Copy, Clone)]
-enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, }
+enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, DebugLowerHex, DebugUpperHex }
 
 impl<'a> Arguments<'a> {
     /// When using the format_args!() macro, this function is used to generate the
@@ -406,6 +406,18 @@ impl<'a> Arguments<'a> {
 /// macro validates the format string at compile-time so usage of the [`write`]
 /// and [`format`] functions can be safely performed.
 ///
+/// You can use the `Arguments<'a>` that [`format_args!`] returns in `Debug`
+/// and `Display` contexts as seen below. The example also shows that `Debug`
+/// and `Display` format to the same thing: the interpolated format string
+/// in `format_args!`.
+///
+/// ```rust
+/// let display = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
+/// let debug = format!("{}", format_args!("{} foo {:?}", 1, 2));
+/// assert_eq!("1 foo 2", display);
+/// assert_eq!(display, debug);
+/// ```
+///
 /// [`format_args!`]: ../../std/macro.format_args.html
 /// [`format`]: ../../std/fmt/fn.format.html
 /// [`write`]: ../../std/fmt/fn.write.html
@@ -1537,6 +1549,12 @@ impl<'a> Formatter<'a> {
         self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0
     }
 
+    // FIXME: Decide what public API we want for these two flags.
+    // https://github.com/rust-lang/rust/issues/48584
+    fn debug_lower_hex(&self) -> bool { self.flags & (1 << FlagV1::DebugLowerHex as u32) != 0 }
+
+    fn debug_upper_hex(&self) -> bool { self.flags & (1 << FlagV1::DebugUpperHex as u32) != 0 }
+
     /// Creates a [`DebugStruct`] builder designed to assist with creation of
     /// [`fmt::Debug`] implementations for structs.
     ///
@@ -1547,10 +1565,12 @@ impl<'a> Formatter<'a> {
     ///
     /// ```rust
     /// use std::fmt;
+    /// use std::net::Ipv4Addr;
     ///
     /// struct Foo {
     ///     bar: i32,
     ///     baz: String,
+    ///     addr: Ipv4Addr,
     /// }
     ///
     /// impl fmt::Debug for Foo {
@@ -1558,12 +1578,19 @@ impl<'a> Formatter<'a> {
     ///         fmt.debug_struct("Foo")
     ///             .field("bar", &self.bar)
     ///             .field("baz", &self.baz)
+    ///             .field("addr", &format_args!("{}", self.addr))
     ///             .finish()
     ///     }
     /// }
     ///
-    /// // prints "Foo { bar: 10, baz: "Hello World" }"
-    /// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() });
+    /// assert_eq!(
+    ///     "Foo { bar: 10, baz: \"Hello World\", addr: 127.0.0.1 }",
+    ///     format!("{:?}", Foo {
+    ///         bar: 10,
+    ///         baz: "Hello World".to_string(),
+    ///         addr: Ipv4Addr::new(127, 0, 0, 1),
+    ///     })
+    /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
     pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> {
@@ -1577,20 +1604,24 @@ impl<'a> Formatter<'a> {
     ///
     /// ```rust
     /// use std::fmt;
+    /// use std::marker::PhantomData;
     ///
-    /// struct Foo(i32, String);
+    /// struct Foo<T>(i32, String, PhantomData<T>);
     ///
-    /// impl fmt::Debug for Foo {
+    /// impl<T> fmt::Debug for Foo<T> {
     ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     ///         fmt.debug_tuple("Foo")
     ///             .field(&self.0)
     ///             .field(&self.1)
+    ///             .field(&format_args!("_"))
     ///             .finish()
     ///     }
     /// }
     ///
-    /// // prints "Foo(10, "Hello World")"
-    /// println!("{:?}", Foo(10, "Hello World".to_string()));
+    /// assert_eq!(
+    ///     "Foo(10, \"Hello\", _)",
+    ///     format!("{:?}", Foo(10, "Hello".to_string(), PhantomData::<u8>))
+    /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
     pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> {
@@ -1640,6 +1671,41 @@ impl<'a> Formatter<'a> {
     /// // prints "{10, 11}"
     /// println!("{:?}", Foo(vec![10, 11]));
     /// ```
+    ///
+    /// [`format_args!`]: ../../std/macro.format_args.html
+    ///
+    /// In this more complex example, we use [`format_args!`] and `.debug_set()`
+    /// to build a list of match arms:
+    ///
+    /// ```rust
+    /// use std::fmt;
+    ///
+    /// struct Arm<'a, L: 'a, R: 'a>(&'a (L, R));
+    /// struct Table<'a, K: 'a, V: 'a>(&'a [(K, V)], V);
+    ///
+    /// impl<'a, L, R> fmt::Debug for Arm<'a, L, R>
+    /// where
+    ///     L: 'a + fmt::Debug, R: 'a + fmt::Debug
+    /// {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    ///         L::fmt(&(self.0).0, fmt)?;
+    ///         fmt.write_str(" => ")?;
+    ///         R::fmt(&(self.0).1, fmt)
+    ///     }
+    /// }
+    ///
+    /// impl<'a, K, V> fmt::Debug for Table<'a, K, V>
+    /// where
+    ///     K: 'a + fmt::Debug, V: 'a + fmt::Debug
+    /// {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    ///         fmt.debug_set()
+    ///         .entries(self.0.iter().map(Arm))
+    ///         .entry(&Arm(&(format_args!("_"), &self.1)))
+    ///         .finish()
+    ///     }
+    /// }
+    /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
     pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> {
         builders::debug_set_new(self)
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index 2992e7cf8db34..4451ab445cc5c 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -49,15 +49,13 @@ doit! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
 #[doc(hidden)]
 trait GenericRadix {
     /// The number of digits.
-    fn base(&self) -> u8;
+    const BASE: u8;
 
     /// A radix-specific prefix string.
-    fn prefix(&self) -> &'static str {
-        ""
-    }
+    const PREFIX: &'static str;
 
     /// Converts an integer to corresponding radix digit.
-    fn digit(&self, x: u8) -> u8;
+    fn digit(x: u8) -> u8;
 
     /// Format an integer using the radix using a formatter.
     fn fmt_int<T: Int>(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result {
@@ -65,16 +63,16 @@ trait GenericRadix {
         // characters for a base 2 number.
         let zero = T::zero();
         let is_nonnegative = x >= zero;
-        let mut buf = [0; 128];
+        let mut buf: [u8; 128] = unsafe { mem::uninitialized() };
         let mut curr = buf.len();
-        let base = T::from_u8(self.base());
+        let base = T::from_u8(Self::BASE);
         if is_nonnegative {
             // Accumulate each digit of the number from the least significant
             // to the most significant figure.
             for byte in buf.iter_mut().rev() {
-                let n = x % base;              // Get the current place value.
-                x = x / base;                  // Deaccumulate the number.
-                *byte = self.digit(n.to_u8()); // Store the digit in the buffer.
+                let n = x % base;               // Get the current place value.
+                x = x / base;                   // Deaccumulate the number.
+                *byte = Self::digit(n.to_u8()); // Store the digit in the buffer.
                 curr -= 1;
                 if x == zero {
                     // No more digits left to accumulate.
@@ -84,9 +82,9 @@ trait GenericRadix {
         } else {
             // Do the same as above, but accounting for two's complement.
             for byte in buf.iter_mut().rev() {
-                let n = zero - (x % base);     // Get the current place value.
-                x = x / base;                  // Deaccumulate the number.
-                *byte = self.digit(n.to_u8()); // Store the digit in the buffer.
+                let n = zero - (x % base);      // Get the current place value.
+                x = x / base;                   // Deaccumulate the number.
+                *byte = Self::digit(n.to_u8()); // Store the digit in the buffer.
                 curr -= 1;
                 if x == zero {
                     // No more digits left to accumulate.
@@ -95,7 +93,7 @@ trait GenericRadix {
             }
         }
         let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) };
-        f.pad_integral(is_nonnegative, self.prefix(), buf)
+        f.pad_integral(is_nonnegative, Self::PREFIX, buf)
     }
 }
 
@@ -107,10 +105,6 @@ struct Binary;
 #[derive(Clone, PartialEq)]
 struct Octal;
 
-/// A decimal (base 10) radix
-#[derive(Clone, PartialEq)]
-struct Decimal;
-
 /// A hexadecimal (base 16) radix, formatted with lower-case characters
 #[derive(Clone, PartialEq)]
 struct LowerHex;
@@ -122,12 +116,12 @@ struct UpperHex;
 macro_rules! radix {
     ($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => {
         impl GenericRadix for $T {
-            fn base(&self) -> u8 { $base }
-            fn prefix(&self) -> &'static str { $prefix }
-            fn digit(&self, x: u8) -> u8 {
+            const BASE: u8 = $base;
+            const PREFIX: &'static str = $prefix;
+            fn digit(x: u8) -> u8 {
                 match x {
                     $($x => $conv,)+
-                    x => panic!("number not in the range 0..{}: {}", self.base() - 1, x),
+                    x => panic!("number not in the range 0..{}: {}", Self::BASE - 1, x),
                 }
             }
         }
@@ -136,7 +130,6 @@ macro_rules! radix {
 
 radix! { Binary,    2, "0b", x @  0 ...  1 => b'0' + x }
 radix! { Octal,     8, "0o", x @  0 ...  7 => b'0' + x }
-radix! { Decimal,  10, "",   x @  0 ...  9 => b'0' + x }
 radix! { LowerHex, 16, "0x", x @  0 ...  9 => b'0' + x,
                              x @ 10 ... 15 => b'a' + (x - 10) }
 radix! { UpperHex, 16, "0x", x @  0 ...  9 => b'0' + x,
@@ -159,7 +152,13 @@ macro_rules! debug {
         impl fmt::Debug for $T {
             #[inline]
             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-                fmt::Display::fmt(self, f)
+                if f.debug_lower_hex() {
+                    fmt::LowerHex::fmt(self, f)
+                } else if f.debug_upper_hex() {
+                    fmt::UpperHex::fmt(self, f)
+                } else {
+                    fmt::Display::fmt(self, f)
+                }
             }
         }
     }
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index 15545a04b64de..3e1f21cafe412 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -99,9 +99,10 @@ use mem;
 #[allow(deprecated)]
 pub use self::sip::SipHasher;
 
-#[unstable(feature = "sip_hash_13", issue = "34767")]
+#[unstable(feature = "hashmap_internals", issue = "0")]
 #[allow(deprecated)]
-pub use self::sip::{SipHasher13, SipHasher24};
+#[doc(hidden)]
+pub use self::sip::SipHasher13;
 
 mod sip;
 
@@ -307,7 +308,7 @@ pub trait Hasher {
     }
     /// Writes a single `u128` into this hasher.
     #[inline]
-    #[unstable(feature = "i128", issue = "35118")]
+    #[stable(feature = "i128", since = "1.26.0")]
     fn write_u128(&mut self, i: u128) {
         self.write(&unsafe { mem::transmute::<_, [u8; 16]>(i) })
     }
@@ -347,7 +348,7 @@ pub trait Hasher {
     }
     /// Writes a single `i128` into this hasher.
     #[inline]
-    #[unstable(feature = "i128", issue = "35118")]
+    #[stable(feature = "i128", since = "1.26.0")]
     fn write_i128(&mut self, i: i128) {
         self.write_u128(i as u128)
     }
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index 4e4d9b3f1e2f0..e3bdecdc4b1fd 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -23,10 +23,11 @@ use mem;
 /// (eg. `collections::HashMap` uses it by default).
 ///
 /// See: <https://131002.net/siphash>
-#[unstable(feature = "sip_hash_13", issue = "34767")]
+#[unstable(feature = "hashmap_internals", issue = "0")]
 #[rustc_deprecated(since = "1.13.0",
                    reason = "use `std::collections::hash_map::DefaultHasher` instead")]
 #[derive(Debug, Clone, Default)]
+#[doc(hidden)]
 pub struct SipHasher13 {
     hasher: Hasher<Sip13Rounds>,
 }
@@ -34,11 +35,11 @@ pub struct SipHasher13 {
 /// An implementation of SipHash 2-4.
 ///
 /// See: <https://131002.net/siphash/>
-#[unstable(feature = "sip_hash_13", issue = "34767")]
+#[unstable(feature = "hashmap_internals", issue = "0")]
 #[rustc_deprecated(since = "1.13.0",
                    reason = "use `std::collections::hash_map::DefaultHasher` instead")]
 #[derive(Debug, Clone, Default)]
-pub struct SipHasher24 {
+struct SipHasher24 {
     hasher: Hasher<Sip24Rounds>,
 }
 
@@ -156,14 +157,16 @@ impl SipHasher {
     #[rustc_deprecated(since = "1.13.0",
                        reason = "use `std::collections::hash_map::DefaultHasher` instead")]
     pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
-        SipHasher(SipHasher24::new_with_keys(key0, key1))
+        SipHasher(SipHasher24 {
+            hasher: Hasher::new_with_keys(key0, key1)
+        })
     }
 }
 
 impl SipHasher13 {
     /// Creates a new `SipHasher13` with the two initial keys set to 0.
     #[inline]
-    #[unstable(feature = "sip_hash_13", issue = "34767")]
+    #[unstable(feature = "hashmap_internals", issue = "0")]
     #[rustc_deprecated(since = "1.13.0",
                        reason = "use `std::collections::hash_map::DefaultHasher` instead")]
     pub fn new() -> SipHasher13 {
@@ -172,7 +175,7 @@ impl SipHasher13 {
 
     /// Creates a `SipHasher13` that is keyed off the provided keys.
     #[inline]
-    #[unstable(feature = "sip_hash_13", issue = "34767")]
+    #[unstable(feature = "hashmap_internals", issue = "0")]
     #[rustc_deprecated(since = "1.13.0",
                        reason = "use `std::collections::hash_map::DefaultHasher` instead")]
     pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
@@ -182,28 +185,6 @@ impl SipHasher13 {
     }
 }
 
-impl SipHasher24 {
-    /// Creates a new `SipHasher24` with the two initial keys set to 0.
-    #[inline]
-    #[unstable(feature = "sip_hash_13", issue = "34767")]
-    #[rustc_deprecated(since = "1.13.0",
-                       reason = "use `std::collections::hash_map::DefaultHasher` instead")]
-    pub fn new() -> SipHasher24 {
-        SipHasher24::new_with_keys(0, 0)
-    }
-
-    /// Creates a `SipHasher24` that is keyed off the provided keys.
-    #[inline]
-    #[unstable(feature = "sip_hash_13", issue = "34767")]
-    #[rustc_deprecated(since = "1.13.0",
-                       reason = "use `std::collections::hash_map::DefaultHasher` instead")]
-    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher24 {
-        SipHasher24 {
-            hasher: Hasher::new_with_keys(key0, key1)
-        }
-    }
-}
-
 impl<S: Sip> Hasher<S> {
     #[inline]
     fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {
@@ -271,16 +252,16 @@ impl<S: Sip> Hasher<S> {
 impl super::Hasher for SipHasher {
     #[inline]
     fn write(&mut self, msg: &[u8]) {
-        self.0.write(msg)
+        self.0.hasher.write(msg)
     }
 
     #[inline]
     fn finish(&self) -> u64 {
-        self.0.finish()
+        self.0.hasher.finish()
     }
 }
 
-#[unstable(feature = "sip_hash_13", issue = "34767")]
+#[unstable(feature = "hashmap_internals", issue = "0")]
 impl super::Hasher for SipHasher13 {
     #[inline]
     fn write(&mut self, msg: &[u8]) {
@@ -293,19 +274,6 @@ impl super::Hasher for SipHasher13 {
     }
 }
 
-#[unstable(feature = "sip_hash_13", issue = "34767")]
-impl super::Hasher for SipHasher24 {
-    #[inline]
-    fn write(&mut self, msg: &[u8]) {
-        self.hasher.write(msg)
-    }
-
-    #[inline]
-    fn finish(&self) -> u64 {
-        self.hasher.finish()
-    }
-}
-
 impl<S: Sip> super::Hasher for Hasher<S> {
     // see short_write comment for explanation
     #[inline]
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 830ebad065427..3b740adc46832 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1314,6 +1314,11 @@ extern "rust-intrinsic" {
     /// [`std::u32::overflowing_mul`](../../std/primitive.u32.html#method.overflowing_mul)
     pub fn mul_with_overflow<T>(x: T, y: T) -> (T, bool);
 
+    /// Performs an exact division, resulting in undefined behavior where
+    /// `x % y != 0` or `y == 0` or `x == T::min_value() && y == -1`
+    #[cfg(not(stage0))]
+    pub fn exact_div<T>(x: T, y: T) -> T;
+
     /// Performs an unchecked division, resulting in undefined behavior
     /// where y = 0 or x = `T::min_value()` and y = -1
     pub fn unchecked_div<T>(x: T, y: T) -> T;
@@ -1396,3 +1401,8 @@ extern "rust-intrinsic" {
     /// Probably will never become stable.
     pub fn nontemporal_store<T>(ptr: *mut T, val: T);
 }
+
+#[cfg(stage0)]
+pub unsafe fn exact_div<T>(a: T, b: T) -> T {
+    unchecked_div(a, b)
+}
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 2cfbc09229342..31f77f92435d8 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -974,13 +974,13 @@ pub trait Iterator {
     ///     // each iteration, we'll multiply the state by the element
     ///     *state = *state * x;
     ///
-    ///     // the value passed on to the next iteration
-    ///     Some(*state)
+    ///     // then, we'll yield the negation of the state
+    ///     Some(-*state)
     /// });
     ///
-    /// assert_eq!(iter.next(), Some(1));
-    /// assert_eq!(iter.next(), Some(2));
-    /// assert_eq!(iter.next(), Some(6));
+    /// assert_eq!(iter.next(), Some(-1));
+    /// assert_eq!(iter.next(), Some(-2));
+    /// assert_eq!(iter.next(), Some(-6));
     /// assert_eq!(iter.next(), None);
     /// ```
     #[inline]
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index b1b783b47c72b..1e8476d3880c8 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -1872,7 +1872,7 @@ impl<I: Iterator> Iterator for Peekable<I> {
 
     #[inline]
     fn nth(&mut self, n: usize) -> Option<I::Item> {
-        // FIXME(#6393): merge these when borrow-checking gets better.
+        // FIXME(#43234): merge these when borrow-checking gets better.
         if n == 0 {
             match self.peeked.take() {
                 Some(v) => v,
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index 8d1080bb876ef..72b48b565719c 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -91,7 +91,7 @@ macro_rules! step_impl_unsigned {
             #[inline]
             #[allow(unreachable_patterns)]
             fn add_usize(&self, n: usize) -> Option<Self> {
-                match <$t>::try_from(n) {
+                match <$t>::private_try_from(n) {
                     Ok(n_as_t) => self.checked_add(n_as_t),
                     Err(_) => None,
                 }
@@ -123,7 +123,7 @@ macro_rules! step_impl_signed {
             #[inline]
             #[allow(unreachable_patterns)]
             fn add_usize(&self, n: usize) -> Option<Self> {
-                match <$unsigned>::try_from(n) {
+                match <$unsigned>::private_try_from(n) {
                     Ok(n_as_unsigned) => {
                         // Wrapping in unsigned space handles cases like
                         // `-120_i8.add_usize(200) == Some(80_i8)`,
@@ -461,3 +461,73 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
 
 #[stable(feature = "fused", since = "1.26.0")]
 impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}
+
+/// Compensate removal of some impls per
+/// https://github.com/rust-lang/rust/pull/49305#issuecomment-376293243
+trait PrivateTryFromUsize: Sized {
+    fn private_try_from(n: usize) -> Result<Self, ()>;
+}
+
+impl<T> PrivateTryFromUsize for T where T: TryFrom<usize> {
+    #[inline]
+    fn private_try_from(n: usize) -> Result<Self, ()> {
+        T::try_from(n).map_err(|_| ())
+    }
+}
+
+// no possible bounds violation
+macro_rules! try_from_unbounded {
+    ($($target:ty),*) => {$(
+        impl PrivateTryFromUsize for $target {
+            #[inline]
+            fn private_try_from(value: usize) -> Result<Self, ()> {
+                Ok(value as $target)
+            }
+        }
+    )*}
+}
+
+// unsigned to signed (only positive bound)
+macro_rules! try_from_upper_bounded {
+    ($($target:ty),*) => {$(
+        impl PrivateTryFromUsize for $target {
+            #[inline]
+            fn private_try_from(u: usize) -> Result<$target, ()> {
+                if u > (<$target>::max_value() as usize) {
+                    Err(())
+                } else {
+                    Ok(u as $target)
+                }
+            }
+        }
+    )*}
+}
+
+
+#[cfg(target_pointer_width = "16")]
+mod ptr_try_from_impls {
+    use super::PrivateTryFromUsize;
+
+    try_from_unbounded!(u16, u32, u64, u128);
+    try_from_unbounded!(i32, i64, i128);
+}
+
+#[cfg(target_pointer_width = "32")]
+mod ptr_try_from_impls {
+    use super::PrivateTryFromUsize;
+
+    try_from_upper_bounded!(u16);
+    try_from_unbounded!(u32, u64, u128);
+    try_from_upper_bounded!(i32);
+    try_from_unbounded!(i64, i128);
+}
+
+#[cfg(target_pointer_width = "64")]
+mod ptr_try_from_impls {
+    use super::PrivateTryFromUsize;
+
+    try_from_upper_bounded!(u16, u32);
+    try_from_unbounded!(u64, u128);
+    try_from_upper_bounded!(i32, i64);
+    try_from_unbounded!(i128);
+}
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 9aebe2e4ee4b4..ffaf7058c7a2a 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -78,7 +78,7 @@
 #![feature(doc_spotlight)]
 #![feature(fn_must_use)]
 #![feature(fundamental)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![cfg_attr(stage0, feature(inclusive_range_syntax))]
 #![feature(intrinsics)]
 #![feature(iterator_flatten)]
@@ -86,6 +86,7 @@
 #![feature(lang_items)]
 #![feature(link_llvm_intrinsics)]
 #![feature(exhaustive_patterns)]
+#![feature(macro_at_most_once_rep)]
 #![feature(no_core)]
 #![feature(on_unimplemented)]
 #![feature(optin_builtin_traits)]
@@ -151,7 +152,6 @@ pub mod prelude;
 
 pub mod intrinsics;
 pub mod mem;
-pub mod nonzero;
 pub mod ptr;
 
 /* Core language traits */
@@ -188,6 +188,7 @@ pub mod time;
 // note: does not need to be public
 mod char_private;
 mod iter_private;
+mod nonzero;
 mod tuple;
 mod unit;
 
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 53b1d1cd12de3..7d0174a178abf 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -166,6 +166,11 @@ pub trait Unsize<T: ?Sized> {
 /// are allowed to access `x` after the assignment. Under the hood, both a copy and a move
 /// can result in bits being copied in memory, although this is sometimes optimized away.
 ///
+/// ## Closures
+///
+/// Closure types automatically implement `Copy` if they capture no value from the environment
+/// or if all such captured values implement `Copy` themselves.
+///
 /// ## How can I implement `Copy`?
 ///
 /// There are two ways to implement `Copy` on your type. The simplest is to use `derive`:
@@ -578,3 +583,13 @@ unsafe impl<T: ?Sized> Freeze for *const T {}
 unsafe impl<T: ?Sized> Freeze for *mut T {}
 unsafe impl<'a, T: ?Sized> Freeze for &'a T {}
 unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
+
+/// Types which can be moved out of a `Pin`.
+///
+/// The `Unpin` trait is used to control the behavior of the [`Pin`] type. If a
+/// type implements `Unpin`, it is safe to move a value of that type out of the
+/// `Pin` pointer.
+///
+/// This trait is automatically implemented for almost every type.
+#[unstable(feature = "pin", issue = "49150")]
+pub unsafe auto trait Unpin {}
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index 21a0beccbf64d..b2467c948b4b1 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -20,9 +20,9 @@ use cmp;
 use fmt;
 use hash;
 use intrinsics;
-use marker::{Copy, PhantomData, Sized};
+use marker::{Copy, PhantomData, Sized, Unpin, Unsize};
 use ptr;
-use ops::{Deref, DerefMut};
+use ops::{Deref, DerefMut, CoerceUnsized};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use intrinsics::transmute;
@@ -1105,3 +1105,111 @@ impl<T: ::hash::Hash> ::hash::Hash for ManuallyDrop<T> {
 pub unsafe fn unreachable() -> ! {
     intrinsics::unreachable()
 }
+
+/// A pinned reference.
+///
+/// A pinned reference is a lot like a mutable reference, except that it is not
+/// safe to move a value out of a pinned reference unless the type of that
+/// value implements the `Unpin` trait.
+#[unstable(feature = "pin", issue = "49150")]
+#[fundamental]
+pub struct Pin<'a, T: ?Sized + 'a> {
+    inner: &'a mut T,
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized + Unpin> Pin<'a, T> {
+    /// Construct a new `Pin` around a reference to some data of a type that
+    /// implements `Unpin`.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub fn new(reference: &'a mut T) -> Pin<'a, T> {
+        Pin { inner: reference }
+    }
+}
+
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized> Pin<'a, T> {
+    /// Construct a new `Pin` around a reference to some data of a type that
+    /// may or may not implement `Unpin`.
+    ///
+    /// This constructor is unsafe because we do not know what will happen with
+    /// that data after the reference ends. If you cannot guarantee that the
+    /// data will never move again, calling this constructor is invalid.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub unsafe fn new_unchecked(reference: &'a mut T) -> Pin<'a, T> {
+        Pin { inner: reference }
+    }
+
+    /// Borrow a Pin for a shorter lifetime than it already has.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub fn borrow<'b>(this: &'b mut Pin<'a, T>) -> Pin<'b, T> {
+        Pin { inner: this.inner }
+    }
+
+    /// Get a mutable reference to the data inside of this `Pin`.
+    ///
+    /// This function is unsafe. You must guarantee that you will never move
+    /// the data out of the mutable reference you receive when you call this
+    /// function.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub unsafe fn get_mut<'b>(this: &'b mut Pin<'a, T>) -> &'b mut T {
+        this.inner
+    }
+
+    /// Construct a new pin by mapping the interior value.
+    ///
+    /// For example, if you  wanted to get a `Pin` of a field of something, you
+    /// could use this to get access to that field in one line of code.
+    ///
+    /// This function is unsafe. You must guarantee that the data you return
+    /// will not move so long as the argument value does not move (for example,
+    /// because it is one of the fields of that value), and also that you do
+    /// not move out of the argument you receive to the interior function.
+    #[unstable(feature = "pin", issue = "49150")]
+    pub unsafe fn map<'b, U, F>(this: &'b mut Pin<'a, T>, f: F) -> Pin<'b, U> where
+        F: FnOnce(&mut T) -> &mut U
+    {
+        Pin { inner: f(this.inner) }
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized> Deref for Pin<'a, T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &*self.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized + Unpin> DerefMut for Pin<'a, T> {
+    fn deref_mut(&mut self) -> &mut T {
+        self.inner
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: fmt::Debug + ?Sized> fmt::Debug for Pin<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&**self, f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: fmt::Display + ?Sized> fmt::Display for Pin<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&**self, f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized> fmt::Pointer for Pin<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Pointer::fmt(&(&*self.inner as *const T), f)
+    }
+}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Pin<'a, U>> for Pin<'a, T> {}
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index 19836d98844e2..ee5230cef8dd9 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -9,103 +9,13 @@
 // except according to those terms.
 
 //! Exposes the NonZero lang item which provides optimization hints.
-#![unstable(feature = "nonzero", reason = "deprecated", issue = "49137")]
-#![rustc_deprecated(reason = "use `std::ptr::NonNull` or `std::num::NonZero*` instead",
-                    since = "1.26.0")]
-#![allow(deprecated)]
 
 use ops::CoerceUnsized;
 
-/// Unsafe trait to indicate what types are usable with the NonZero struct
-pub unsafe trait Zeroable {
-    /// Whether this value is zero
-    fn is_zero(&self) -> bool;
-}
-
-macro_rules! impl_zeroable_for_pointer_types {
-    ( $( $Ptr: ty )+ ) => {
-        $(
-            /// For fat pointers to be considered "zero", only the "data" part needs to be null.
-            unsafe impl<T: ?Sized> Zeroable for $Ptr {
-                #[inline]
-                fn is_zero(&self) -> bool {
-                    (*self).is_null()
-                }
-            }
-        )+
-    }
-}
-
-macro_rules! impl_zeroable_for_integer_types {
-    ( $( $Int: ty )+ ) => {
-        $(
-            unsafe impl Zeroable for $Int {
-                #[inline]
-                fn is_zero(&self) -> bool {
-                    *self == 0
-                }
-            }
-        )+
-    }
-}
-
-impl_zeroable_for_pointer_types! {
-    *const T
-    *mut T
-}
-
-impl_zeroable_for_integer_types! {
-    usize u8 u16 u32 u64 u128
-    isize i8 i16 i32 i64 i128
-}
-
 /// A wrapper type for raw pointers and integers that will never be
 /// NULL or 0 that might allow certain optimizations.
 #[lang = "non_zero"]
-#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
-pub struct NonZero<T: Zeroable>(pub(crate) T);
-
-impl<T: Zeroable> NonZero<T> {
-    /// Creates an instance of NonZero with the provided value.
-    /// You must indeed ensure that the value is actually "non-zero".
-    #[inline]
-    pub const unsafe fn new_unchecked(inner: T) -> Self {
-        NonZero(inner)
-    }
-
-    /// Creates an instance of NonZero with the provided value.
-    #[inline]
-    pub fn new(inner: T) -> Option<Self> {
-        if inner.is_zero() {
-            None
-        } else {
-            Some(NonZero(inner))
-        }
-    }
-
-    /// Gets the inner value.
-    pub fn get(self) -> T {
-        self.0
-    }
-}
-
-impl<T: Zeroable+CoerceUnsized<U>, U: Zeroable> CoerceUnsized<NonZero<U>> for NonZero<T> {}
-
-impl<'a, T: ?Sized> From<&'a mut T> for NonZero<*mut T> {
-    fn from(reference: &'a mut T) -> Self {
-        NonZero(reference)
-    }
-}
-
-impl<'a, T: ?Sized> From<&'a mut T> for NonZero<*const T> {
-    fn from(reference: &'a mut T) -> Self {
-        let ptr: *mut T = reference;
-        NonZero(ptr)
-    }
-}
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+pub(crate) struct NonZero<T>(pub(crate) T);
 
-impl<'a, T: ?Sized> From<&'a T> for NonZero<*const T> {
-    fn from(reference: &'a T) -> Self {
-        NonZero(reference)
-    }
-}
+impl<T: CoerceUnsized<U>, U> CoerceUnsized<NonZero<U>> for NonZero<T> {}
diff --git a/src/libcore/num/i128.rs b/src/libcore/num/i128.rs
index 04354e2e33f96..989376d1ac2d2 100644
--- a/src/libcore/num/i128.rs
+++ b/src/libcore/num/i128.rs
@@ -12,6 +12,6 @@
 //!
 //! *[See also the `i128` primitive type](../../std/primitive.i128.html).*
 
-#![unstable(feature = "i128", issue="35118")]
+#![stable(feature = "i128", since = "1.26.0")]
 
-int_module! { i128, #[unstable(feature = "i128", issue="35118")] }
+int_module! { i128, #[stable(feature = "i128", since="1.26.0")] }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 2ffcb9e95e2d9..0ab760de690bf 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -12,10 +12,10 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use convert::{Infallible, TryFrom};
+use convert::TryFrom;
 use fmt;
 use intrinsics;
-#[allow(deprecated)] use nonzero::NonZero;
+use nonzero::NonZero;
 use ops;
 use str::FromStr;
 
@@ -46,11 +46,9 @@ macro_rules! nonzero_integers {
             /// assert_eq!(size_of::<Option<std::num::NonZeroU32>>(), size_of::<u32>());
             /// ```
             #[$stability]
-            #[allow(deprecated)]
             #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
             pub struct $Ty(NonZero<$Int>);
 
-            #[allow(deprecated)]
             impl $Ty {
                 /// Create a non-zero without checking the value.
                 ///
@@ -93,18 +91,12 @@ macro_rules! nonzero_integers {
 
 nonzero_integers! {
     #[unstable(feature = "nonzero", issue = "49137")]
-    NonZeroU8(u8); NonZeroI8(i8);
-    NonZeroU16(u16); NonZeroI16(i16);
-    NonZeroU32(u32); NonZeroI32(i32);
-    NonZeroU64(u64); NonZeroI64(i64);
-    NonZeroUsize(usize); NonZeroIsize(isize);
-}
-
-nonzero_integers! {
-    // Change this to `#[unstable(feature = "i128", issue = "35118")]`
-    // if other NonZero* integer types are stabilizied before 128-bit integers
-    #[unstable(feature = "nonzero", issue = "49137")]
-    NonZeroU128(u128); NonZeroI128(i128);
+    NonZeroU8(u8);
+    NonZeroU16(u16);
+    NonZeroU32(u32);
+    NonZeroU64(u64);
+    NonZeroU128(u128);
+    NonZeroUsize(usize);
 }
 
 /// Provides intentionally-wrapped arithmetic on `T`.
@@ -1635,11 +1627,7 @@ impl i64 {
 #[lang = "i128"]
 impl i128 {
     int_impl! { i128, i128, u128, 128, -170141183460469231731687303715884105728,
-        170141183460469231731687303715884105727, "#![feature(i128_type)]
-#![feature(i128)]
-# fn main() {
-", "
-# }" }
+        170141183460469231731687303715884105727, "", "" }
 }
 
 #[cfg(target_pointer_width = "16")]
@@ -3493,12 +3481,7 @@ impl u64 {
 
 #[lang = "u128"]
 impl u128 {
-    uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, "#![feature(i128_type)]
-#![feature(i128)]
-
-# fn main() {
-", "
-# }" }
+    uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, "", "" }
 }
 
 #[cfg(target_pointer_width = "16")]
@@ -3662,7 +3645,7 @@ macro_rules! from_str_radix_int_impl {
 from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
 
 /// The error type returned when a checked integral type conversion fails.
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 #[derive(Debug, Copy, Clone)]
 pub struct TryFromIntError(());
 
@@ -3677,40 +3660,24 @@ impl TryFromIntError {
     }
 }
 
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl fmt::Display for TryFromIntError {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         self.__description().fmt(fmt)
     }
 }
 
-#[unstable(feature = "try_from", issue = "33417")]
-impl From<Infallible> for TryFromIntError {
-    fn from(infallible: Infallible) -> TryFromIntError {
-        match infallible {
-        }
+#[stable(feature = "try_from", since = "1.26.0")]
+impl From<!> for TryFromIntError {
+    fn from(never: !) -> TryFromIntError {
+        never
     }
 }
 
-// no possible bounds violation
-macro_rules! try_from_unbounded {
-    ($source:ty, $($target:ty),*) => {$(
-        #[unstable(feature = "try_from", issue = "33417")]
-        impl TryFrom<$source> for $target {
-            type Error = Infallible;
-
-            #[inline]
-            fn try_from(value: $source) -> Result<Self, Self::Error> {
-                Ok(value as $target)
-            }
-        }
-    )*}
-}
-
 // only negative bounds
 macro_rules! try_from_lower_bounded {
     ($source:ty, $($target:ty),*) => {$(
-        #[unstable(feature = "try_from", issue = "33417")]
+        #[stable(feature = "try_from", since = "1.26.0")]
         impl TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
@@ -3729,7 +3696,7 @@ macro_rules! try_from_lower_bounded {
 // unsigned to signed (only positive bound)
 macro_rules! try_from_upper_bounded {
     ($source:ty, $($target:ty),*) => {$(
-        #[unstable(feature = "try_from", issue = "33417")]
+        #[stable(feature = "try_from", since = "1.26.0")]
         impl TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
@@ -3748,7 +3715,7 @@ macro_rules! try_from_upper_bounded {
 // all other cases
 macro_rules! try_from_both_bounded {
     ($source:ty, $($target:ty),*) => {$(
-        #[unstable(feature = "try_from", issue = "33417")]
+        #[stable(feature = "try_from", since = "1.26.0")]
         impl TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
@@ -3805,82 +3772,44 @@ try_from_both_bounded!(i128, u64, u32, u16, u8);
 try_from_upper_bounded!(usize, isize);
 try_from_lower_bounded!(isize, usize);
 
+try_from_upper_bounded!(usize, u8);
+try_from_upper_bounded!(usize, i8, i16);
+try_from_both_bounded!(isize, u8);
+try_from_both_bounded!(isize, i8);
+
 #[cfg(target_pointer_width = "16")]
 mod ptr_try_from_impls {
     use super::TryFromIntError;
-    use convert::{Infallible, TryFrom};
-
-    try_from_upper_bounded!(usize, u8);
-    try_from_unbounded!(usize, u16, u32, u64, u128);
-    try_from_upper_bounded!(usize, i8, i16);
-    try_from_unbounded!(usize, i32, i64, i128);
+    use convert::TryFrom;
 
-    try_from_both_bounded!(isize, u8);
+    // Fallible across platfoms, only implementation differs
     try_from_lower_bounded!(isize, u16, u32, u64, u128);
-    try_from_both_bounded!(isize, i8);
-    try_from_unbounded!(isize, i16, i32, i64, i128);
-
-    rev!(try_from_unbounded, usize, u16);
-    rev!(try_from_upper_bounded, usize, u32, u64, u128);
     rev!(try_from_lower_bounded, usize, i8, i16);
     rev!(try_from_both_bounded, usize, i32, i64, i128);
-
-    rev!(try_from_unbounded, isize, u8);
-    rev!(try_from_upper_bounded, isize, u16, u32, u64, u128);
-    rev!(try_from_unbounded, isize, i16);
-    rev!(try_from_both_bounded, isize, i32, i64, i128);
 }
 
 #[cfg(target_pointer_width = "32")]
 mod ptr_try_from_impls {
     use super::TryFromIntError;
-    use convert::{Infallible, TryFrom};
+    use convert::TryFrom;
 
-    try_from_upper_bounded!(usize, u8, u16);
-    try_from_unbounded!(usize, u32, u64, u128);
-    try_from_upper_bounded!(usize, i8, i16, i32);
-    try_from_unbounded!(usize, i64, i128);
-
-    try_from_both_bounded!(isize, u8, u16);
+    // Fallible across platfoms, only implementation differs
+    try_from_both_bounded!(isize, u16);
     try_from_lower_bounded!(isize, u32, u64, u128);
-    try_from_both_bounded!(isize, i8, i16);
-    try_from_unbounded!(isize, i32, i64, i128);
-
-    rev!(try_from_unbounded, usize, u16, u32);
-    rev!(try_from_upper_bounded, usize, u64, u128);
     rev!(try_from_lower_bounded, usize, i8, i16, i32);
     rev!(try_from_both_bounded, usize, i64, i128);
-
-    rev!(try_from_unbounded, isize, u8, u16);
-    rev!(try_from_upper_bounded, isize, u32, u64, u128);
-    rev!(try_from_unbounded, isize, i16, i32);
-    rev!(try_from_both_bounded, isize, i64, i128);
 }
 
 #[cfg(target_pointer_width = "64")]
 mod ptr_try_from_impls {
     use super::TryFromIntError;
-    use convert::{Infallible, TryFrom};
+    use convert::TryFrom;
 
-    try_from_upper_bounded!(usize, u8, u16, u32);
-    try_from_unbounded!(usize, u64, u128);
-    try_from_upper_bounded!(usize, i8, i16, i32, i64);
-    try_from_unbounded!(usize, i128);
-
-    try_from_both_bounded!(isize, u8, u16, u32);
+    // Fallible across platfoms, only implementation differs
+    try_from_both_bounded!(isize, u16, u32);
     try_from_lower_bounded!(isize, u64, u128);
-    try_from_both_bounded!(isize, i8, i16, i32);
-    try_from_unbounded!(isize, i64, i128);
-
-    rev!(try_from_unbounded, usize, u16, u32, u64);
-    rev!(try_from_upper_bounded, usize, u128);
     rev!(try_from_lower_bounded, usize, i8, i16, i32, i64);
     rev!(try_from_both_bounded, usize, i128);
-
-    rev!(try_from_unbounded, isize, u8, u16, u32);
-    rev!(try_from_upper_bounded, isize, u64, u128);
-    rev!(try_from_unbounded, isize, i16, i32, i64);
-    rev!(try_from_both_bounded, isize, i128);
 }
 
 #[doc(hidden)]
@@ -4056,39 +3985,53 @@ macro_rules! impl_from {
 impl_from! { u8, u16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u8, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u8, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u8, u128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u8, u128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { u8, usize, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u16, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u16, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u16, u128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u16, u128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { u32, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u32, u128, #[unstable(feature = "i128", issue = "35118")] }
-impl_from! { u64, u128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u32, u128, #[stable(feature = "i128", since = "1.26.0")] }
+impl_from! { u64, u128, #[stable(feature = "i128", since = "1.26.0")] }
 
 // Signed -> Signed
 impl_from! { i8, i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { i8, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { i8, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { i8, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { i8, i128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { i8, isize, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { i16, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { i16, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { i16, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { i16, i128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { i32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { i32, i128, #[unstable(feature = "i128", issue = "35118")] }
-impl_from! { i64, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { i32, i128, #[stable(feature = "i128", since = "1.26.0")] }
+impl_from! { i64, i128, #[stable(feature = "i128", since = "1.26.0")] }
 
 // Unsigned -> Signed
 impl_from! { u8, i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u8, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u8, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u8, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u8, i128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { u16, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u16, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u16, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u16, i128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { u32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u32, i128, #[unstable(feature = "i128", issue = "35118")] }
-impl_from! { u64, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u32, i128, #[stable(feature = "i128", since = "1.26.0")] }
+impl_from! { u64, i128, #[stable(feature = "i128", since = "1.26.0")] }
+
+// The C99 standard defines bounds on INTPTR_MIN, INTPTR_MAX, and UINTPTR_MAX
+// which imply that pointer-sized integers must be at least 16 bits:
+// https://port70.net/~nsz/c/c99/n1256.html#7.18.2.4
+impl_from! { u16, usize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] }
+impl_from! { u8, isize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] }
+impl_from! { i16, isize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] }
+
+// RISC-V defines the possibility of a 128-bit address space (RV128).
+
+// CHERI proposes 256-bit “capabilities”. Unclear if this would be relevant to usize/isize.
+// https://www.cl.cam.ac.uk/research/security/ctsrd/pdfs/20171017a-cheri-poster.pdf
+// http://www.csl.sri.com/users/neumann/2012resolve-cheri.pdf
+
 
 // Note: integers can only be represented with full precision in a float if
 // they fit in the significand, which is 24 bits in f32 and 53 bits in f64.
diff --git a/src/libcore/num/u128.rs b/src/libcore/num/u128.rs
index 987ac3e000732..e8c783a1bb542 100644
--- a/src/libcore/num/u128.rs
+++ b/src/libcore/num/u128.rs
@@ -12,5 +12,5 @@
 //!
 //! *[See also the `u128` primitive type](../../std/primitive.u128.html).*
 
-#![unstable(feature = "i128", issue="35118")]
-uint_module! { u128, #[unstable(feature = "i128", issue="35118")] }
+#![stable(feature = "i128", since = "1.26.0")]
+uint_module! { u128, #[stable(feature = "i128", since="1.26.0")] }
diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs
index ae1b0b3ce11b2..826883fdc3f01 100644
--- a/src/libcore/num/wrapping.rs
+++ b/src/libcore/num/wrapping.rs
@@ -317,11 +317,320 @@ macro_rules! wrapping_impl {
         }
         forward_ref_unop! { impl Neg, neg for Wrapping<$t>,
                 #[stable(feature = "wrapping_ref", since = "1.14.0")] }
+
     )*)
 }
 
 wrapping_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
+macro_rules! wrapping_int_impl {
+    ($($t:ty)*) => ($(
+        impl Wrapping<$t> {
+            /// Returns the number of ones in the binary representation of
+            /// `self`.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i8> = Wrapping(-0b1000_0000);
+            ///
+            /// assert_eq!(n.count_ones(), 1);
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn count_ones(self) -> u32 {
+                self.0.count_ones()
+            }
+
+            /// Returns the number of zeros in the binary representation of
+            /// `self`.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i8> = Wrapping(-0b1000_0000);
+            ///
+            /// assert_eq!(n.count_zeros(), 7);
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn count_zeros(self) -> u32 {
+                self.0.count_zeros()
+            }
+
+            /// Returns the number of leading zeros in the binary representation
+            /// of `self`.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i16> = Wrapping(-1);
+            ///
+            /// assert_eq!(n.leading_zeros(), 0);
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn leading_zeros(self) -> u32 {
+                self.0.leading_zeros()
+            }
+
+            /// Returns the number of trailing zeros in the binary representation
+            /// of `self`.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i8> = Wrapping(-4);
+            ///
+            /// assert_eq!(n.trailing_zeros(), 2);
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn trailing_zeros(self) -> u32 {
+                self.0.trailing_zeros()
+            }
+
+            /// Shifts the bits to the left by a specified amount, `n`,
+            /// wrapping the truncated bits to the end of the resulting
+            /// integer.
+            ///
+            /// Please note this isn't the same operation as `>>`!
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i64> = Wrapping(0x0123456789ABCDEF);
+            /// let m: Wrapping<i64> = Wrapping(-0x76543210FEDCBA99);
+            ///
+            /// assert_eq!(n.rotate_left(32), m);
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn rotate_left(self, n: u32) -> Self {
+                Wrapping(self.0.rotate_left(n))
+            }
+
+            /// Shifts the bits to the right by a specified amount, `n`,
+            /// wrapping the truncated bits to the beginning of the resulting
+            /// integer.
+            ///
+            /// Please note this isn't the same operation as `<<`!
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i64> = Wrapping(0x0123456789ABCDEF);
+            /// let m: Wrapping<i64> = Wrapping(-0xFEDCBA987654322);
+            ///
+            /// assert_eq!(n.rotate_right(4), m);
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn rotate_right(self, n: u32) -> Self {
+                Wrapping(self.0.rotate_right(n))
+            }
+
+            /// Reverses the byte order of the integer.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i16> = Wrapping(0b0000000_01010101);
+            /// assert_eq!(n, Wrapping(85));
+            ///
+            /// let m = n.swap_bytes();
+            ///
+            /// assert_eq!(m, Wrapping(0b01010101_00000000));
+            /// assert_eq!(m, Wrapping(21760));
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn swap_bytes(self) -> Self {
+                Wrapping(self.0.swap_bytes())
+            }
+
+            /// Converts an integer from big endian to the target's endianness.
+            ///
+            /// On big endian this is a no-op. On little endian the bytes are
+            /// swapped.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i64> = Wrapping(0x0123456789ABCDEF);
+            ///
+            /// if cfg!(target_endian = "big") {
+            ///     assert_eq!(Wrapping::<i64>::from_be(n), n);
+            /// } else {
+            ///     assert_eq!(Wrapping::<i64>::from_be(n), n.swap_bytes());
+            /// }
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn from_be(x: Self) -> Self {
+                Wrapping(<$t>::from_be(x.0))
+            }
+
+            /// Converts an integer from little endian to the target's endianness.
+            ///
+            /// On little endian this is a no-op. On big endian the bytes are
+            /// swapped.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i64> = Wrapping(0x0123456789ABCDEF);
+            ///
+            /// if cfg!(target_endian = "little") {
+            ///     assert_eq!(Wrapping::<i64>::from_le(n), n);
+            /// } else {
+            ///     assert_eq!(Wrapping::<i64>::from_le(n), n.swap_bytes());
+            /// }
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn from_le(x: Self) -> Self {
+                Wrapping(<$t>::from_le(x.0))
+            }
+
+            /// Converts `self` to big endian from the target's endianness.
+            ///
+            /// On big endian this is a no-op. On little endian the bytes are
+            /// swapped.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i64> = Wrapping(0x0123456789ABCDEF);
+            ///
+            /// if cfg!(target_endian = "big") {
+            ///     assert_eq!(n.to_be(), n);
+            /// } else {
+            ///     assert_eq!(n.to_be(), n.swap_bytes());
+            /// }
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn to_be(self) -> Self {
+                Wrapping(self.0.to_be())
+            }
+
+            /// Converts `self` to little endian from the target's endianness.
+            ///
+            /// On little endian this is a no-op. On big endian the bytes are
+            /// swapped.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let n: Wrapping<i64> = Wrapping(0x0123456789ABCDEF);
+            ///
+            /// if cfg!(target_endian = "little") {
+            ///     assert_eq!(n.to_le(), n);
+            /// } else {
+            ///     assert_eq!(n.to_le(), n.swap_bytes());
+            /// }
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn to_le(self) -> Self {
+                Wrapping(self.0.to_le())
+            }
+
+            /// Raises self to the power of `exp`, using exponentiation by
+            /// squaring.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// let x: Wrapping<i32> = Wrapping(2); // or any other integer type
+            ///
+            /// assert_eq!(x.pow(4), Wrapping(16));
+            /// ```
+            ///
+            /// Results that are too large are wrapped:
+            ///
+            /// ```
+            /// #![feature(wrapping_int_impl)]
+            /// use std::num::Wrapping;
+            ///
+            /// // 5 ^ 4 = 625, which is too big for a u8
+            /// let x: Wrapping<u8> = Wrapping(5);
+            ///
+            /// assert_eq!(x.pow(4).0, 113);
+            /// ```
+            #[inline]
+            #[unstable(feature = "wrapping_int_impl", issue = "32463")]
+            pub fn pow(self, exp: u32) -> Self {
+                Wrapping(self.0.wrapping_pow(exp))
+            }
+        }
+    )*)
+}
+
+wrapping_int_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+
 mod shift_max {
     #![allow(non_upper_case_globals)]
 
diff --git a/src/libcore/ops/generator.rs b/src/libcore/ops/generator.rs
index dc7669d195c13..4b70c5398be4f 100644
--- a/src/libcore/ops/generator.rs
+++ b/src/libcore/ops/generator.rs
@@ -56,11 +56,11 @@ pub enum GeneratorState<Y, R> {
 ///         return "foo"
 ///     };
 ///
-///     match generator.resume() {
+///     match unsafe { generator.resume() } {
 ///         GeneratorState::Yielded(1) => {}
 ///         _ => panic!("unexpected return from resume"),
 ///     }
-///     match generator.resume() {
+///     match unsafe { generator.resume() } {
 ///         GeneratorState::Complete("foo") => {}
 ///         _ => panic!("unexpected return from resume"),
 ///     }
@@ -98,6 +98,10 @@ pub trait Generator {
     /// generator will continue executing until it either yields or returns, at
     /// which point this function will return.
     ///
+    /// The function is unsafe because it can be used on an immovable generator.
+    /// After such a call, the immovable generator must not move again, but
+    /// this is not enforced by the compiler.
+    ///
     /// # Return value
     ///
     /// The `GeneratorState` enum returned from this function indicates what
@@ -116,7 +120,7 @@ pub trait Generator {
     /// been returned previously. While generator literals in the language are
     /// guaranteed to panic on resuming after `Complete`, this is not guaranteed
     /// for all implementations of the `Generator` trait.
-    fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>;
+    unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>;
 }
 
 #[unstable(feature = "generator_trait", issue = "43122")]
@@ -125,7 +129,7 @@ impl<'a, T> Generator for &'a mut T
 {
     type Yield = T::Yield;
     type Return = T::Return;
-    fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
+    unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
         (**self).resume()
     }
 }
diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs
index d43496c387cb8..2c8e27abac9c0 100644
--- a/src/libcore/prelude/v1.rs
+++ b/src/libcore/prelude/v1.rs
@@ -39,6 +39,9 @@ pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
 pub use convert::{AsRef, AsMut, Into, From};
+#[stable(feature = "try_from", since = "1.26.0")]
+#[doc(no_inline)]
+pub use convert::{TryFrom, TryInto};
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
 pub use default::Default;
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index cebd5989e96cd..a3c38e979d39f 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -23,7 +23,7 @@ use fmt;
 use hash;
 use marker::{PhantomData, Unsize};
 use mem;
-#[allow(deprecated)] use nonzero::NonZero;
+use nonzero::NonZero;
 
 use cmp::Ordering::{self, Less, Equal, Greater};
 
@@ -669,7 +669,7 @@ impl<T: ?Sized> *const T {
     /// `mem::size_of::<T>()` then the result of the division is rounded towards
     /// zero.
     ///
-    /// This function returns `None` if `T` is a zero-sized typed.
+    /// This function returns `None` if `T` is a zero-sized type.
     ///
     /// # Examples
     ///
@@ -700,6 +700,124 @@ impl<T: ?Sized> *const T {
         }
     }
 
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// This function is the inverse of [`offset`].
+    ///
+    /// [`offset`]: #method.offset
+    /// [`wrapping_offset_from`]: #method.wrapping_offset_from
+    ///
+    /// # Safety
+    ///
+    /// If any of the following conditions are violated, the result is Undefined
+    /// Behavior:
+    ///
+    /// * Both the starting and other pointer must be either in bounds or one
+    ///   byte past the end of the same allocated object.
+    ///
+    /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
+    ///
+    /// * The distance between the pointers, in bytes, must be an exact multiple
+    ///   of the size of `T`.
+    ///
+    /// * The distance being in bounds cannot rely on "wrapping around" the address space.
+    ///
+    /// The compiler and standard library generally try to ensure allocations
+    /// never reach a size where an offset is a concern. For instance, `Vec`
+    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
+    /// `ptr_into_vec.offset_from(vec.as_ptr())` is always safe.
+    ///
+    /// Most platforms fundamentally can't even construct such an allocation.
+    /// For instance, no known 64-bit platform can ever serve a request
+    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
+    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
+    /// more than `isize::MAX` bytes with things like Physical Address
+    /// Extension. As such, memory acquired directly from allocators or memory
+    /// mapped files *may* be too large to handle with this function.
+    ///
+    /// Consider using [`wrapping_offset_from`] instead if these constraints are
+    /// difficult to satisfy. The only advantage of this method is that it
+    /// enables more aggressive compiler optimizations.
+    ///
+    /// # Panics
+    ///
+    /// This function panics if `T` is a Zero-Sized Type ("ZST").
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(ptr_offset_from)]
+    ///
+    /// let a = [0; 5];
+    /// let ptr1: *const i32 = &a[1];
+    /// let ptr2: *const i32 = &a[3];
+    /// unsafe {
+    ///     assert_eq!(ptr2.offset_from(ptr1), 2);
+    ///     assert_eq!(ptr1.offset_from(ptr2), -2);
+    ///     assert_eq!(ptr1.offset(2), ptr2);
+    ///     assert_eq!(ptr2.offset(-2), ptr1);
+    /// }
+    /// ```
+    #[unstable(feature = "ptr_offset_from", issue = "41079")]
+    #[inline]
+    pub unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized {
+        let pointee_size = mem::size_of::<T>();
+        assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);
+
+        // This is the same sequence that Clang emits for pointer subtraction.
+        // It can be neither `nsw` nor `nuw` because the input is treated as
+        // unsigned but then the output is treated as signed, so neither works.
+        let d = isize::wrapping_sub(self as _, origin as _);
+        intrinsics::exact_div(d, pointee_size as _)
+    }
+
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// If the address different between the two pointers is not a multiple of
+    /// `mem::size_of::<T>()` then the result of the division is rounded towards
+    /// zero.
+    ///
+    /// Though this method is safe for any two pointers, note that its result
+    /// will be mostly useless if the two pointers aren't into the same allocated
+    /// object, for example if they point to two different local variables.
+    ///
+    /// # Panics
+    ///
+    /// This function panics if `T` is a zero-sized type.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(ptr_wrapping_offset_from)]
+    ///
+    /// let a = [0; 5];
+    /// let ptr1: *const i32 = &a[1];
+    /// let ptr2: *const i32 = &a[3];
+    /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+    /// assert_eq!(ptr1.wrapping_offset_from(ptr2), -2);
+    /// assert_eq!(ptr1.wrapping_offset(2), ptr2);
+    /// assert_eq!(ptr2.wrapping_offset(-2), ptr1);
+    ///
+    /// let ptr1: *const i32 = 3 as _;
+    /// let ptr2: *const i32 = 13 as _;
+    /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+    /// ```
+    #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
+    #[inline]
+    pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized {
+        let pointee_size = mem::size_of::<T>();
+        assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);
+
+        let d = isize::wrapping_sub(self as _, origin as _);
+        d.wrapping_div(pointee_size as _)
+    }
+
     /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
     ///
     /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
@@ -1316,7 +1434,7 @@ impl<T: ?Sized> *mut T {
     /// `mem::size_of::<T>()` then the result of the division is rounded towards
     /// zero.
     ///
-    /// This function returns `None` if `T` is a zero-sized typed.
+    /// This function returns `None` if `T` is a zero-sized type.
     ///
     /// # Examples
     ///
@@ -1347,6 +1465,113 @@ impl<T: ?Sized> *mut T {
         }
     }
 
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// This function is the inverse of [`offset`].
+    ///
+    /// [`offset`]: #method.offset-1
+    /// [`wrapping_offset_from`]: #method.wrapping_offset_from-1
+    ///
+    /// # Safety
+    ///
+    /// If any of the following conditions are violated, the result is Undefined
+    /// Behavior:
+    ///
+    /// * Both the starting and other pointer must be either in bounds or one
+    ///   byte past the end of the same allocated object.
+    ///
+    /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
+    ///
+    /// * The distance between the pointers, in bytes, must be an exact multiple
+    ///   of the size of `T`.
+    ///
+    /// * The distance being in bounds cannot rely on "wrapping around" the address space.
+    ///
+    /// The compiler and standard library generally try to ensure allocations
+    /// never reach a size where an offset is a concern. For instance, `Vec`
+    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
+    /// `ptr_into_vec.offset_from(vec.as_ptr())` is always safe.
+    ///
+    /// Most platforms fundamentally can't even construct such an allocation.
+    /// For instance, no known 64-bit platform can ever serve a request
+    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
+    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
+    /// more than `isize::MAX` bytes with things like Physical Address
+    /// Extension. As such, memory acquired directly from allocators or memory
+    /// mapped files *may* be too large to handle with this function.
+    ///
+    /// Consider using [`wrapping_offset_from`] instead if these constraints are
+    /// difficult to satisfy. The only advantage of this method is that it
+    /// enables more aggressive compiler optimizations.
+    ///
+    /// # Panics
+    ///
+    /// This function panics if `T` is a Zero-Sized Type ("ZST").
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(ptr_offset_from)]
+    ///
+    /// let mut a = [0; 5];
+    /// let ptr1: *mut i32 = &mut a[1];
+    /// let ptr2: *mut i32 = &mut a[3];
+    /// unsafe {
+    ///     assert_eq!(ptr2.offset_from(ptr1), 2);
+    ///     assert_eq!(ptr1.offset_from(ptr2), -2);
+    ///     assert_eq!(ptr1.offset(2), ptr2);
+    ///     assert_eq!(ptr2.offset(-2), ptr1);
+    /// }
+    /// ```
+    #[unstable(feature = "ptr_offset_from", issue = "41079")]
+    #[inline]
+    pub unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized {
+        (self as *const T).offset_from(origin)
+    }
+
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// If the address different between the two pointers is not a multiple of
+    /// `mem::size_of::<T>()` then the result of the division is rounded towards
+    /// zero.
+    ///
+    /// Though this method is safe for any two pointers, note that its result
+    /// will be mostly useless if the two pointers aren't into the same allocated
+    /// object, for example if they point to two different local variables.
+    ///
+    /// # Panics
+    ///
+    /// This function panics if `T` is a zero-sized type.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(ptr_wrapping_offset_from)]
+    ///
+    /// let mut a = [0; 5];
+    /// let ptr1: *mut i32 = &mut a[1];
+    /// let ptr2: *mut i32 = &mut a[3];
+    /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+    /// assert_eq!(ptr1.wrapping_offset_from(ptr2), -2);
+    /// assert_eq!(ptr1.wrapping_offset(2), ptr2);
+    /// assert_eq!(ptr2.wrapping_offset(-2), ptr1);
+    ///
+    /// let ptr1: *mut i32 = 3 as _;
+    /// let ptr2: *mut i32 = 13 as _;
+    /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+    /// ```
+    #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
+    #[inline]
+    pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized {
+        (self as *const T).wrapping_offset_from(origin)
+    }
+
     /// Computes the byte offset that needs to be applied in order to
     /// make the pointer aligned to `align`.
     /// If it is not possible to align the pointer, the implementation returns
@@ -2285,7 +2510,6 @@ impl<T: ?Sized> PartialOrd for *mut T {
 #[unstable(feature = "ptr_internals", issue = "0",
            reason = "use NonNull instead and consider PhantomData<T> \
                      (if you also use #[may_dangle]), Send, and/or Sync")]
-#[allow(deprecated)]
 pub struct Unique<T: ?Sized> {
     pointer: NonZero<*const T>,
     // NOTE: this marker has no consequences for variance, but is necessary
@@ -2333,7 +2557,6 @@ impl<T: Sized> Unique<T> {
 }
 
 #[unstable(feature = "ptr_internals", issue = "0")]
-#[allow(deprecated)]
 impl<T: ?Sized> Unique<T> {
     /// Creates a new `Unique`.
     ///
@@ -2398,7 +2621,6 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
 }
 
 #[unstable(feature = "ptr_internals", issue = "0")]
-#[allow(deprecated)]
 impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
     fn from(reference: &'a mut T) -> Self {
         Unique { pointer: NonZero(reference as _), _marker: PhantomData }
@@ -2406,7 +2628,6 @@ impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
 }
 
 #[unstable(feature = "ptr_internals", issue = "0")]
-#[allow(deprecated)]
 impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
     fn from(reference: &'a T) -> Self {
         Unique { pointer: NonZero(reference as _), _marker: PhantomData }
@@ -2439,7 +2660,7 @@ impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
 /// provide a public API that follows the normal shared XOR mutable rules of Rust.
 #[stable(feature = "nonnull", since = "1.25.0")]
 pub struct NonNull<T: ?Sized> {
-    #[allow(deprecated)] pointer: NonZero<*const T>,
+    pointer: NonZero<*const T>,
 }
 
 /// `NonNull` pointers are not `Send` because the data they reference may be aliased.
@@ -2466,7 +2687,6 @@ impl<T: Sized> NonNull<T> {
     }
 }
 
-#[allow(deprecated)]
 impl<T: ?Sized> NonNull<T> {
     /// Creates a new `NonNull`.
     ///
@@ -2589,7 +2809,6 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
 }
 
 #[stable(feature = "nonnull", since = "1.25.0")]
-#[allow(deprecated)]
 impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
     fn from(reference: &'a mut T) -> Self {
         NonNull { pointer: NonZero(reference as _) }
@@ -2597,7 +2816,6 @@ impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
 }
 
 #[stable(feature = "nonnull", since = "1.25.0")]
-#[allow(deprecated)]
 impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
     fn from(reference: &'a T) -> Self {
         NonNull { pointer: NonZero(reference as _) }
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 9cf862bd93625..1185b7acaae1f 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -165,6 +165,37 @@ Section: Creating a string
 ///
 /// [`String`]: ../../std/string/struct.String.html#method.from_utf8
 /// [`&str`]: ../../std/str/fn.from_utf8.html
+///
+/// # Examples
+///
+/// This error type’s methods can be used to create functionality
+/// similar to `String::from_utf8_lossy` without allocating heap memory:
+///
+/// ```
+/// fn from_utf8_lossy<F>(mut input: &[u8], mut push: F) where F: FnMut(&str) {
+///     loop {
+///         match ::std::str::from_utf8(input) {
+///             Ok(valid) => {
+///                 push(valid);
+///                 break
+///             }
+///             Err(error) => {
+///                 let (valid, after_valid) = input.split_at(error.valid_up_to());
+///                 unsafe {
+///                     push(::std::str::from_utf8_unchecked(valid))
+///                 }
+///                 push("\u{FFFD}");
+///
+///                 if let Some(invalid_sequence_length) = error.error_len() {
+///                     input = &after_valid[invalid_sequence_length..]
+///                 } else {
+///                     break
+///                 }
+///             }
+///         }
+///     }
+/// }
+/// ```
 #[derive(Copy, Eq, PartialEq, Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Utf8Error {
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 25827edee7d93..d934706be67d9 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -205,8 +205,11 @@ pub enum Ordering {
     /// [`Release`]: http://llvm.org/docs/Atomics.html#release
     #[stable(feature = "rust1", since = "1.0.0")]
     Acquire,
-    /// When coupled with a load, uses [`Acquire`] ordering, and with a store
-    /// [`Release`] ordering.
+    /// Has the effects of both [`Acquire`] and [`Release`] together.
+    ///
+    /// This ordering is only applicable for operations that combine both loads and stores.
+    ///
+    /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering.
     ///
     /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire
     /// [`Release`]: http://llvm.org/docs/Atomics.html#release
@@ -948,6 +951,7 @@ macro_rules! atomic_int {
      $stable_from:meta,
      $stable_nand:meta,
      $s_int_type:expr, $int_ref:expr,
+     $extra_feature:expr,
      $int_type:ident $atomic_type:ident $atomic_init:ident) => {
         /// An integer type which can be safely shared between threads.
         ///
@@ -959,12 +963,7 @@ macro_rules! atomic_int {
         /// ). For more about the differences between atomic types and
         /// non-atomic types, please see the [module-level documentation].
         ///
-        /// Please note that examples are shared between atomic variants of
-        /// primitive integer types, so it's normal that they are all
-        /// demonstrating [`AtomicIsize`].
-        ///
         /// [module-level documentation]: index.html
-        /// [`AtomicIsize`]: struct.AtomicIsize.html
         #[$stable]
         pub struct $atomic_type {
             v: UnsafeCell<$int_type>,
@@ -1001,395 +1000,426 @@ macro_rules! atomic_int {
         unsafe impl Sync for $atomic_type {}
 
         impl $atomic_type {
-            /// Creates a new atomic integer.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::AtomicIsize;
-            ///
-            /// let atomic_forty_two  = AtomicIsize::new(42);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub const fn new(v: $int_type) -> Self {
-                $atomic_type {v: UnsafeCell::new(v)}
+            doc_comment! {
+                concat!("Creates a new atomic integer.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";
+
+let atomic_forty_two = ", stringify!($atomic_type), "::new(42);
+```"),
+                #[inline]
+                #[$stable]
+                pub const fn new(v: $int_type) -> Self {
+                    $atomic_type {v: UnsafeCell::new(v)}
+                }
             }
 
-            /// Returns a mutable reference to the underlying integer.
-            ///
-            /// This is safe because the mutable reference guarantees that no other threads are
-            /// concurrently accessing the atomic data.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let mut some_isize = AtomicIsize::new(10);
-            /// assert_eq!(*some_isize.get_mut(), 10);
-            /// *some_isize.get_mut() = 5;
-            /// assert_eq!(some_isize.load(Ordering::SeqCst), 5);
-            /// ```
-            #[inline]
-            #[$stable_access]
-            pub fn get_mut(&mut self) -> &mut $int_type {
-                unsafe { &mut *self.v.get() }
+            doc_comment! {
+                concat!("Returns a mutable reference to the underlying integer.
+
+This is safe because the mutable reference guarantees that no other threads are
+concurrently accessing the atomic data.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let mut some_var = ", stringify!($atomic_type), "::new(10);
+assert_eq!(*some_var.get_mut(), 10);
+*some_var.get_mut() = 5;
+assert_eq!(some_var.load(Ordering::SeqCst), 5);
+```"),
+                #[inline]
+                #[$stable_access]
+                pub fn get_mut(&mut self) -> &mut $int_type {
+                    unsafe { &mut *self.v.get() }
+                }
             }
 
-            /// Consumes the atomic and returns the contained value.
-            ///
-            /// This is safe because passing `self` by value guarantees that no other threads are
-            /// concurrently accessing the atomic data.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::AtomicIsize;
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            /// assert_eq!(some_isize.into_inner(), 5);
-            /// ```
-            #[inline]
-            #[$stable_access]
-            pub fn into_inner(self) -> $int_type {
-                self.v.into_inner()
+            doc_comment! {
+                concat!("Consumes the atomic and returns the contained value.
+
+This is safe because passing `self` by value guarantees that no other threads are
+concurrently accessing the atomic data.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+assert_eq!(some_var.into_inner(), 5);
+```"),
+                #[inline]
+                #[$stable_access]
+                pub fn into_inner(self) -> $int_type {
+                    self.v.into_inner()
+                }
             }
 
-            /// Loads a value from the atomic integer.
-            ///
-            /// `load` takes an [`Ordering`] argument which describes the memory ordering of this
-            /// operation.
-            ///
-            /// # Panics
-            ///
-            /// Panics if `order` is [`Release`] or [`AcqRel`].
-            ///
-            /// [`Ordering`]: enum.Ordering.html
-            /// [`Release`]: enum.Ordering.html#variant.Release
-            /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            ///
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 5);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub fn load(&self, order: Ordering) -> $int_type {
-                unsafe { atomic_load(self.v.get(), order) }
+            doc_comment! {
+                concat!("Loads a value from the atomic integer.
+
+`load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
+
+# Panics
+
+Panics if `order` is [`Release`] or [`AcqRel`].
+
+[`Ordering`]: enum.Ordering.html
+[`Release`]: enum.Ordering.html#variant.Release
+[`AcqRel`]: enum.Ordering.html#variant.AcqRel
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+
+assert_eq!(some_var.load(Ordering::Relaxed), 5);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn load(&self, order: Ordering) -> $int_type {
+                    unsafe { atomic_load(self.v.get(), order) }
+                }
             }
 
-            /// Stores a value into the atomic integer.
-            ///
-            /// `store` takes an [`Ordering`] argument which describes the memory ordering of this
-            /// operation.
-            ///
-            /// [`Ordering`]: enum.Ordering.html
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            ///
-            /// some_isize.store(10, Ordering::Relaxed);
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
-            /// ```
-            ///
-            /// # Panics
-            ///
-            /// Panics if `order` is [`Acquire`] or [`AcqRel`].
-            ///
-            /// [`Acquire`]: enum.Ordering.html#variant.Acquire
-            /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
-            #[inline]
-            #[$stable]
-            pub fn store(&self, val: $int_type, order: Ordering) {
-                unsafe { atomic_store(self.v.get(), val, order); }
+            doc_comment! {
+                concat!("Stores a value into the atomic integer.
+
+`store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
+
+[`Ordering`]: enum.Ordering.html
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+
+some_var.store(10, Ordering::Relaxed);
+assert_eq!(some_var.load(Ordering::Relaxed), 10);
+```
+
+# Panics
+
+Panics if `order` is [`Acquire`] or [`AcqRel`].
+
+[`Acquire`]: enum.Ordering.html#variant.Acquire
+[`AcqRel`]: enum.Ordering.html#variant.AcqRel"),
+                #[inline]
+                #[$stable]
+                pub fn store(&self, val: $int_type, order: Ordering) {
+                    unsafe { atomic_store(self.v.get(), val, order); }
+                }
             }
 
-            /// Stores a value into the atomic integer, returning the previous value.
-            ///
-            /// `swap` takes an [`Ordering`] argument which describes the memory ordering of this
-            /// operation.
-            ///
-            /// [`Ordering`]: enum.Ordering.html
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            ///
-            /// assert_eq!(some_isize.swap(10, Ordering::Relaxed), 5);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_swap(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Stores a value into the atomic integer, returning the previous value.
+
+`swap` takes an [`Ordering`] argument which describes the memory ordering of this operation.
+
+[`Ordering`]: enum.Ordering.html
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+
+assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_swap(self.v.get(), val, order) }
+                }
             }
 
-            /// Stores a value into the atomic integer if the current value is the same as the
-            /// `current` value.
-            ///
-            /// The return value is always the previous value. If it is equal to `current`, then the
-            /// value was updated.
-            ///
-            /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
-            /// ordering of this operation.
-            ///
-            /// [`Ordering`]: enum.Ordering.html
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            ///
-            /// assert_eq!(some_isize.compare_and_swap(5, 10, Ordering::Relaxed), 5);
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
-            ///
-            /// assert_eq!(some_isize.compare_and_swap(6, 12, Ordering::Relaxed), 10);
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub fn compare_and_swap(&self,
-                                    current: $int_type,
-                                    new: $int_type,
-                                    order: Ordering) -> $int_type {
-                match self.compare_exchange(current,
-                                            new,
-                                            order,
-                                            strongest_failure_ordering(order)) {
-                    Ok(x) => x,
-                    Err(x) => x,
+            doc_comment! {
+                concat!("Stores a value into the atomic integer if the current value is the same as
+the `current` value.
+
+The return value is always the previous value. If it is equal to `current`, then the
+value was updated.
+
+`compare_and_swap` also takes an [`Ordering`] argument which describes the memory
+ordering of this operation.
+
+[`Ordering`]: enum.Ordering.html
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+
+assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
+assert_eq!(some_var.load(Ordering::Relaxed), 10);
+
+assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
+assert_eq!(some_var.load(Ordering::Relaxed), 10);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn compare_and_swap(&self,
+                                        current: $int_type,
+                                        new: $int_type,
+                                        order: Ordering) -> $int_type {
+                    match self.compare_exchange(current,
+                                                new,
+                                                order,
+                                                strongest_failure_ordering(order)) {
+                        Ok(x) => x,
+                        Err(x) => x,
+                    }
                 }
             }
 
-            /// Stores a value into the atomic integer if the current value is the same as the
-            /// `current` value.
-            ///
-            /// The return value is a result indicating whether the new value was written and
-            /// containing the previous value. On success this value is guaranteed to be equal to
-            /// `current`.
-            ///
-            /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
-            /// ordering of this operation. The first describes the required ordering if
-            /// the operation succeeds while the second describes the required ordering when
-            /// the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and
-            /// must be equivalent or weaker than the success ordering.
-            ///
-            /// [`Ordering`]: enum.Ordering.html
-            /// [`Release`]: enum.Ordering.html#variant.Release
-            /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            ///
-            /// assert_eq!(some_isize.compare_exchange(5, 10,
-            ///                                        Ordering::Acquire,
-            ///                                        Ordering::Relaxed),
-            ///            Ok(5));
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
-            ///
-            /// assert_eq!(some_isize.compare_exchange(6, 12,
-            ///                                        Ordering::SeqCst,
-            ///                                        Ordering::Acquire),
-            ///            Err(10));
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
-            /// ```
-            #[inline]
-            #[$stable_cxchg]
-            pub fn compare_exchange(&self,
-                                    current: $int_type,
-                                    new: $int_type,
-                                    success: Ordering,
-                                    failure: Ordering) -> Result<$int_type, $int_type> {
-                unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
+            doc_comment! {
+                concat!("Stores a value into the atomic integer if the current value is the same as
+the `current` value.
+
+The return value is a result indicating whether the new value was written and
+containing the previous value. On success this value is guaranteed to be equal to
+`current`.
+
+`compare_exchange` takes two [`Ordering`] arguments to describe the memory
+ordering of this operation. The first describes the required ordering if
+the operation succeeds while the second describes the required ordering when
+the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and
+must be equivalent or weaker than the success ordering.
+
+[`Ordering`]: enum.Ordering.html
+[`Release`]: enum.Ordering.html#variant.Release
+[`AcqRel`]: enum.Ordering.html#variant.AcqRel
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+
+assert_eq!(some_var.compare_exchange(5, 10,
+                                     Ordering::Acquire,
+                                     Ordering::Relaxed),
+           Ok(5));
+assert_eq!(some_var.load(Ordering::Relaxed), 10);
+
+assert_eq!(some_var.compare_exchange(6, 12,
+                                     Ordering::SeqCst,
+                                     Ordering::Acquire),
+           Err(10));
+assert_eq!(some_var.load(Ordering::Relaxed), 10);
+```"),
+                #[inline]
+                #[$stable_cxchg]
+                pub fn compare_exchange(&self,
+                                        current: $int_type,
+                                        new: $int_type,
+                                        success: Ordering,
+                                        failure: Ordering) -> Result<$int_type, $int_type> {
+                    unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
+                }
             }
 
-            /// Stores a value into the atomic integer if the current value is the same as the
-            /// `current` value.
-            ///
-            /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even
-            /// when the comparison succeeds, which can result in more efficient code on some
-            /// platforms. The return value is a result indicating whether the new value was
-            /// written and containing the previous value.
-            ///
-            /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
-            /// ordering of this operation. The first describes the required ordering if the
-            /// operation succeeds while the second describes the required ordering when the
-            /// operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and
-            /// must be equivalent or weaker than the success ordering.
-            ///
-            /// [`compare_exchange`]: #method.compare_exchange
-            /// [`Ordering`]: enum.Ordering.html
-            /// [`Release`]: enum.Ordering.html#variant.Release
-            /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let val = AtomicIsize::new(4);
-            ///
-            /// let mut old = val.load(Ordering::Relaxed);
-            /// loop {
-            ///     let new = old * 2;
-            ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
-            ///         Ok(_) => break,
-            ///         Err(x) => old = x,
-            ///     }
-            /// }
-            /// ```
-            #[inline]
-            #[$stable_cxchg]
-            pub fn compare_exchange_weak(&self,
-                                         current: $int_type,
-                                         new: $int_type,
-                                         success: Ordering,
-                                         failure: Ordering) -> Result<$int_type, $int_type> {
-                unsafe {
-                    atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
+            doc_comment! {
+                concat!("Stores a value into the atomic integer if the current value is the same as
+the `current` value.
+
+Unlike [`compare_exchange`], this function is allowed to spuriously fail even
+when the comparison succeeds, which can result in more efficient code on some
+platforms. The return value is a result indicating whether the new value was
+written and containing the previous value.
+
+`compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
+ordering of this operation. The first describes the required ordering if the
+operation succeeds while the second describes the required ordering when the
+operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and
+must be equivalent or weaker than the success ordering.
+
+[`compare_exchange`]: #method.compare_exchange
+[`Ordering`]: enum.Ordering.html
+[`Release`]: enum.Ordering.html#variant.Release
+[`AcqRel`]: enum.Ordering.html#variant.AcqRel
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let val = ", stringify!($atomic_type), "::new(4);
+
+let mut old = val.load(Ordering::Relaxed);
+loop {
+    let new = old * 2;
+    match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
+        Ok(_) => break,
+        Err(x) => old = x,
+    }
+}
+```"),
+                #[inline]
+                #[$stable_cxchg]
+                pub fn compare_exchange_weak(&self,
+                                             current: $int_type,
+                                             new: $int_type,
+                                             success: Ordering,
+                                             failure: Ordering) -> Result<$int_type, $int_type> {
+                    unsafe {
+                        atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
+                    }
                 }
             }
 
-            /// Adds to the current value, returning the previous value.
-            ///
-            /// This operation wraps around on overflow.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0);
-            /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
-            /// assert_eq!(foo.load(Ordering::SeqCst), 10);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_add(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Adds to the current value, returning the previous value.
+
+This operation wraps around on overflow.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(0);
+assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
+assert_eq!(foo.load(Ordering::SeqCst), 10);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_add(self.v.get(), val, order) }
+                }
             }
 
-            /// Subtracts from the current value, returning the previous value.
-            ///
-            /// This operation wraps around on overflow.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0);
-            /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 0);
-            /// assert_eq!(foo.load(Ordering::SeqCst), -10);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_sub(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Subtracts from the current value, returning the previous value.
+
+This operation wraps around on overflow.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(20);
+assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
+assert_eq!(foo.load(Ordering::SeqCst), 10);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_sub(self.v.get(), val, order) }
+                }
             }
 
-            /// Bitwise "and" with the current value.
-            ///
-            /// Performs a bitwise "and" operation on the current value and the argument `val`, and
-            /// sets the new value to the result.
-            ///
-            /// Returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0b101101);
-            /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
-            /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
-            #[inline]
-            #[$stable]
-            pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_and(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Bitwise \"and\" with the current value.
+
+Performs a bitwise \"and\" operation on the current value and the argument `val`, and
+sets the new value to the result.
+
+Returns the previous value.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(0b101101);
+assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
+assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_and(self.v.get(), val, order) }
+                }
             }
 
-            /// Bitwise "nand" with the current value.
-            ///
-            /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
-            /// sets the new value to the result.
-            ///
-            /// Returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// #![feature(atomic_nand)]
-            ///
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0xf731);
-            /// assert_eq!(foo.fetch_nand(0x137f, Ordering::SeqCst), 0xf731);
-            /// assert_eq!(foo.load(Ordering::SeqCst), !(0xf731 & 0x137f));
-            #[inline]
-            #[$stable_nand]
-            pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_nand(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Bitwise \"nand\" with the current value.
+
+Performs a bitwise \"nand\" operation on the current value and the argument `val`, and
+sets the new value to the result.
+
+Returns the previous value.
+
+# Examples
+
+```
+", $extra_feature, "#![feature(atomic_nand)]
+
+use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(0x13);
+assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
+assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
+```"),
+                #[inline]
+                #[$stable_nand]
+                pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_nand(self.v.get(), val, order) }
+                }
             }
 
-            /// Bitwise "or" with the current value.
-            ///
-            /// Performs a bitwise "or" operation on the current value and the argument `val`, and
-            /// sets the new value to the result.
-            ///
-            /// Returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0b101101);
-            /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
-            /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
-            #[inline]
-            #[$stable]
-            pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_or(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Bitwise \"or\" with the current value.
+
+Performs a bitwise \"or\" operation on the current value and the argument `val`, and
+sets the new value to the result.
+
+Returns the previous value.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(0b101101);
+assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
+assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_or(self.v.get(), val, order) }
+                }
             }
 
-            /// Bitwise "xor" with the current value.
-            ///
-            /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
-            /// sets the new value to the result.
-            ///
-            /// Returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0b101101);
-            /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
-            /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
-            #[inline]
-            #[$stable]
-            pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_xor(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Bitwise \"xor\" with the current value.
+
+Performs a bitwise \"xor\" operation on the current value and the argument `val`, and
+sets the new value to the result.
+
+Returns the previous value.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(0b101101);
+assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
+assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_xor(self.v.get(), val, order) }
+                }
             }
         }
     }
@@ -1404,6 +1434,7 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "i8", "../../../std/primitive.i8.html",
+    "#![feature(integer_atomics)]\n\n",
     i8 AtomicI8 ATOMIC_I8_INIT
 }
 #[cfg(target_has_atomic = "8")]
@@ -1415,6 +1446,7 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "u8", "../../../std/primitive.u8.html",
+    "#![feature(integer_atomics)]\n\n",
     u8 AtomicU8 ATOMIC_U8_INIT
 }
 #[cfg(target_has_atomic = "16")]
@@ -1426,6 +1458,7 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "i16", "../../../std/primitive.i16.html",
+    "#![feature(integer_atomics)]\n\n",
     i16 AtomicI16 ATOMIC_I16_INIT
 }
 #[cfg(target_has_atomic = "16")]
@@ -1437,6 +1470,7 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "u16", "../../../std/primitive.u16.html",
+    "#![feature(integer_atomics)]\n\n",
     u16 AtomicU16 ATOMIC_U16_INIT
 }
 #[cfg(target_has_atomic = "32")]
@@ -1448,6 +1482,7 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "i32", "../../../std/primitive.i32.html",
+    "#![feature(integer_atomics)]\n\n",
     i32 AtomicI32 ATOMIC_I32_INIT
 }
 #[cfg(target_has_atomic = "32")]
@@ -1459,6 +1494,7 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "u32", "../../../std/primitive.u32.html",
+    "#![feature(integer_atomics)]\n\n",
     u32 AtomicU32 ATOMIC_U32_INIT
 }
 #[cfg(target_has_atomic = "64")]
@@ -1470,6 +1506,7 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "i64", "../../../std/primitive.i64.html",
+    "#![feature(integer_atomics)]\n\n",
     i64 AtomicI64 ATOMIC_I64_INIT
 }
 #[cfg(target_has_atomic = "64")]
@@ -1481,6 +1518,7 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "u64", "../../../std/primitive.u64.html",
+    "#![feature(integer_atomics)]\n\n",
     u64 AtomicU64 ATOMIC_U64_INIT
 }
 #[cfg(target_has_atomic = "ptr")]
@@ -1492,6 +1530,7 @@ atomic_int!{
     stable(feature = "atomic_from", since = "1.23.0"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "isize", "../../../std/primitive.isize.html",
+    "",
     isize AtomicIsize ATOMIC_ISIZE_INIT
 }
 #[cfg(target_has_atomic = "ptr")]
@@ -1503,6 +1542,7 @@ atomic_int!{
     stable(feature = "atomic_from", since = "1.23.0"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "usize", "../../../std/primitive.usize.html",
+    "",
     usize AtomicUsize ATOMIC_USIZE_INIT
 }
 
diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs
index 4d43067ad2cf3..950222dbcfa3f 100644
--- a/src/libcore/tests/ascii.rs
+++ b/src/libcore/tests/ascii.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use core::char::from_u32;
-use std::ascii::AsciiExt;
 
 #[test]
 fn test_is_ascii() {
@@ -143,8 +142,6 @@ macro_rules! assert_all {
                            stringify!($what), b);
                 }
             }
-            assert!($str.$what());
-            assert!($str.as_bytes().$what());
         )+
     }};
     ($what:ident, $($str:tt),+,) => (assert_all!($what,$($str),+))
diff --git a/src/libcore/tests/fmt/num.rs b/src/libcore/tests/fmt/num.rs
index 4ddedd9100486..bc205ec0582ea 100644
--- a/src/libcore/tests/fmt/num.rs
+++ b/src/libcore/tests/fmt/num.rs
@@ -150,3 +150,9 @@ fn test_format_int_twos_complement() {
     assert!(format!("{}", i32::MIN) == "-2147483648");
     assert!(format!("{}", i64::MIN) == "-9223372036854775808");
 }
+
+#[test]
+fn test_format_debug_hex() {
+    assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]");
+    assert!(format!("{:02X?}", b"Foo\0") == "[46, 6F, 6F, 00]");
+}
diff --git a/src/libcore/tests/hash/sip.rs b/src/libcore/tests/hash/sip.rs
index c6dd41798f2a7..bad858011e960 100644
--- a/src/libcore/tests/hash/sip.rs
+++ b/src/libcore/tests/hash/sip.rs
@@ -11,7 +11,7 @@
 #![allow(deprecated)]
 
 use core::hash::{Hash, Hasher};
-use core::hash::{SipHasher, SipHasher13, SipHasher24};
+use core::hash::{SipHasher, SipHasher13};
 use core::{slice, mem};
 
 // Hash just the bytes of the slice, without length prefix
@@ -224,14 +224,14 @@ fn test_siphash_2_4() {
     let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
     let mut buf = Vec::new();
     let mut t = 0;
-    let mut state_inc = SipHasher24::new_with_keys(k0, k1);
+    let mut state_inc = SipHasher::new_with_keys(k0, k1);
 
     while t < 64 {
         let vec = u8to64_le!(vecs[t], 0);
-        let out = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));
+        let out = hash_with(SipHasher::new_with_keys(k0, k1), &Bytes(&buf));
         assert_eq!(vec, out);
 
-        let full = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));
+        let full = hash_with(SipHasher::new_with_keys(k0, k1), &Bytes(&buf));
         let i = state_inc.finish();
 
         assert_eq!(full, i);
@@ -322,13 +322,13 @@ fn test_hash_no_concat_alias() {
 #[test]
 fn test_write_short_works() {
     let test_usize = 0xd0c0b0a0usize;
-    let mut h1 = SipHasher24::new();
+    let mut h1 = SipHasher::new();
     h1.write_usize(test_usize);
     h1.write(b"bytes");
     h1.write(b"string");
     h1.write_u8(0xFFu8);
     h1.write_u8(0x01u8);
-    let mut h2 = SipHasher24::new();
+    let mut h2 = SipHasher::new();
     h2.write(unsafe {
         slice::from_raw_parts(&test_usize as *const _ as *const u8,
                               mem::size_of::<usize>())
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index e53964b5769bd..1a68f04532d20 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -21,12 +21,13 @@
 #![feature(fixed_size_array)]
 #![feature(flt2dec)]
 #![feature(fmt_internals)]
+#![feature(hashmap_internals)]
 #![feature(iterator_step_by)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![cfg_attr(stage0, feature(inclusive_range_syntax))]
 #![feature(iterator_try_fold)]
 #![feature(iterator_flatten)]
-#![feature(conservative_impl_trait)]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
 #![feature(iter_rfind)]
 #![feature(iter_rfold)]
 #![feature(iterator_repeat_with)]
@@ -35,14 +36,13 @@
 #![feature(range_is_empty)]
 #![feature(raw)]
 #![feature(refcell_replace_swap)]
-#![feature(sip_hash_13)]
 #![feature(slice_patterns)]
+#![feature(slice_rotate)]
 #![feature(sort_internals)]
 #![feature(specialization)]
 #![feature(step_trait)]
 #![feature(test)]
 #![feature(trusted_len)]
-#![feature(try_from)]
 #![feature(try_trait)]
 #![feature(exact_chunks)]
 #![feature(atomic_nand)]
diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs
index 587dcbe6d6784..c7edb55b378c3 100644
--- a/src/libcore/tests/num/mod.rs
+++ b/src/libcore/tests/num/mod.rs
@@ -37,15 +37,6 @@ mod flt2dec;
 mod dec2flt;
 mod bignum;
 
-
-/// Adds the attribute to all items in the block.
-macro_rules! cfg_block {
-    ($(#[$attr:meta]{$($it:item)*})*) => {$($(
-        #[$attr]
-        $it
-    )*)*}
-}
-
 /// Groups items that assume the pointer width is either 16/32/64, and has to be altered if
 /// support for larger/smaller pointer widths are added in the future.
 macro_rules! assume_usize_width {
@@ -318,42 +309,6 @@ assume_usize_width! {
 
     test_impl_try_from_always_ok! { test_try_u16usize, u16, usize }
     test_impl_try_from_always_ok! { test_try_i16isize, i16, isize }
-
-    test_impl_try_from_always_ok! { test_try_usizeu64, usize, u64 }
-    test_impl_try_from_always_ok! { test_try_usizeu128, usize, u128 }
-    test_impl_try_from_always_ok! { test_try_usizei128, usize, i128 }
-
-    test_impl_try_from_always_ok! { test_try_isizei64, isize, i64 }
-    test_impl_try_from_always_ok! { test_try_isizei128, isize, i128 }
-
-    cfg_block!(
-        #[cfg(target_pointer_width = "16")] {
-            test_impl_try_from_always_ok! { test_try_usizeu16, usize, u16 }
-            test_impl_try_from_always_ok! { test_try_isizei16, isize, i16 }
-            test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
-            test_impl_try_from_always_ok! { test_try_usizei32, usize, i32 }
-            test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
-            test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 }
-        }
-
-        #[cfg(target_pointer_width = "32")] {
-            test_impl_try_from_always_ok! { test_try_u16isize, u16, isize }
-            test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
-            test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
-            test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
-            test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
-            test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 }
-        }
-
-        #[cfg(target_pointer_width = "64")] {
-            test_impl_try_from_always_ok! { test_try_u16isize, u16, isize }
-            test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
-            test_impl_try_from_always_ok! { test_try_u32isize, u32, isize }
-            test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
-            test_impl_try_from_always_ok! { test_try_u64usize, u64, usize }
-            test_impl_try_from_always_ok! { test_try_i64isize, i64, isize }
-        }
-    );
 }
 
 /// Conversions where max of $source can be represented as $target,
@@ -402,24 +357,6 @@ assume_usize_width! {
     test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu64, isize, u64 }
     test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu128, isize, u128 }
     test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeusize, isize, usize }
-
-    cfg_block!(
-        #[cfg(target_pointer_width = "16")] {
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu16, isize, u16 }
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
-        }
-
-        #[cfg(target_pointer_width = "32")] {
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
-
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
-        }
-
-        #[cfg(target_pointer_width = "64")] {
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64usize, i64, usize }
-        }
-    );
 }
 
 /// Conversions where max of $source can not be represented as $target,
@@ -461,29 +398,9 @@ test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i64, u128, i64 }
 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i128, u128, i128 }
 
 assume_usize_width! {
-    test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64isize, u64, isize }
-    test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128isize, u128, isize }
-
     test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei8, usize, i8 }
     test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei16, usize, i16 }
     test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizeisize, usize, isize }
-
-    cfg_block!(
-        #[cfg(target_pointer_width = "16")] {
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16isize, u16, isize }
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
-        }
-
-        #[cfg(target_pointer_width = "32")] {
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
-        }
-
-        #[cfg(target_pointer_width = "64")] {
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei64, usize, i64 }
-        }
-    );
 }
 
 /// Conversions where min/max of $source can not be represented as $target.
@@ -543,34 +460,6 @@ test_impl_try_from_same_sign_err! { test_try_i128i64, i128, i64 }
 
 assume_usize_width! {
     test_impl_try_from_same_sign_err! { test_try_usizeu8, usize, u8 }
-    test_impl_try_from_same_sign_err! { test_try_u128usize, u128, usize }
-    test_impl_try_from_same_sign_err! { test_try_i128isize, i128, isize }
-
-    cfg_block!(
-        #[cfg(target_pointer_width = "16")] {
-            test_impl_try_from_same_sign_err! { test_try_u32usize, u32, usize }
-            test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
-
-            test_impl_try_from_same_sign_err! { test_try_i32isize, i32, isize }
-            test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
-        }
-
-        #[cfg(target_pointer_width = "32")] {
-            test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
-            test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
-
-            test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
-            test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
-        }
-
-        #[cfg(target_pointer_width = "64")] {
-            test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
-            test_impl_try_from_same_sign_err! { test_try_usizeu32, usize, u32 }
-
-            test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
-            test_impl_try_from_same_sign_err! { test_try_isizei32, isize, i32 }
-        }
-    );
 }
 
 /// Conversions where neither the min nor the max of $source can be represented by
@@ -615,22 +504,6 @@ test_impl_try_from_signed_to_unsigned_err! { test_try_i128u64, i128, u64 }
 assume_usize_width! {
     test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu8, isize, u8 }
     test_impl_try_from_signed_to_unsigned_err! { test_try_i128usize, i128, usize }
-
-    cfg_block! {
-        #[cfg(target_pointer_width = "16")] {
-            test_impl_try_from_signed_to_unsigned_err! { test_try_i32usize, i32, usize }
-            test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
-        }
-        #[cfg(target_pointer_width = "32")] {
-            test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
-
-            test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
-        }
-        #[cfg(target_pointer_width = "64")] {
-            test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
-            test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu32, isize, u32 }
-        }
-    }
 }
 
 macro_rules! test_float {
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 71519ab21fef9..0f45f965104ca 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -108,6 +108,10 @@ pub enum Flag {
     /// For numbers, this means that the number will be padded with zeroes,
     /// and the sign (`+` or `-`) will precede them.
     FlagSignAwareZeroPad,
+    /// For Debug / `?`, format integers in lower-case hexadecimal.
+    FlagDebugLowerHex,
+    /// For Debug / `?`, format integers in upper-case hexadecimal.
+    FlagDebugUpperHex,
 }
 
 /// A count is used for the precision and width parameters of an integer, and
@@ -377,8 +381,22 @@ impl<'a> Parser<'a> {
                 spec.precision = self.count();
             }
         }
-        // Finally the actual format specifier
-        if self.consume('?') {
+        // Optional radix followed by the actual format specifier
+        if self.consume('x') {
+            if self.consume('?') {
+                spec.flags |= 1 << (FlagDebugLowerHex as u32);
+                spec.ty = "?";
+            } else {
+                spec.ty = "x";
+            }
+        } else if self.consume('X') {
+            if self.consume('?') {
+                spec.flags |= 1 << (FlagDebugUpperHex as u32);
+                spec.ty = "?";
+            } else {
+                spec.ty = "X";
+            }
+        } else if self.consume('?') {
             spec.ty = "?";
         } else {
             spec.ty = self.word();
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
deleted file mode 100644
index 81fa0374f549e..0000000000000
--- a/src/libgetopts/lib.rs
+++ /dev/null
@@ -1,1622 +0,0 @@
-// Copyright 2012-2014 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.
-
-//! Simple getopt alternative.
-//!
-//! Construct a vector of options, either by using `reqopt`, `optopt`, and `optflag`
-//! or by building them from components yourself, and pass them to `getopts`,
-//! along with a vector of actual arguments (not including `argv[0]`). You'll
-//! either get a failure code back, or a match. You'll have to verify whether
-//! the amount of 'free' arguments in the match is what you expect. Use `opt_*`
-//! accessors to get argument values out of the matches object.
-//!
-//! Single-character options are expected to appear on the command line with a
-//! single preceding dash; multiple-character options are expected to be
-//! proceeded by two dashes. Options that expect an argument accept their
-//! argument following either a space or an equals sign. Single-character
-//! options don't require the space.
-//!
-//! # Example
-//!
-//! The following example shows simple command line parsing for an application
-//! that requires an input file to be specified, accepts an optional output
-//! file name following `-o`, and accepts both `-h` and `--help` as optional flags.
-//!
-//! ```{.rust}
-//! #![feature(rustc_private)]
-//!
-//! extern crate getopts;
-//! use getopts::{optopt,optflag,getopts,OptGroup,usage};
-//! use std::env;
-//!
-//! fn do_work(inp: &str, out: Option<String>) {
-//!     println!("{}", inp);
-//!     match out {
-//!         Some(x) => println!("{}", x),
-//!         None => println!("No Output"),
-//!     }
-//! }
-//!
-//! fn print_usage(program: &str, opts: &[OptGroup]) {
-//!     let brief = format!("Usage: {} [options]", program);
-//!     print!("{}", usage(&brief, opts));
-//! }
-//!
-//! fn main() {
-//!     let args: Vec<String> = env::args().collect();
-//!
-//!     let program = args[0].clone();
-//!
-//!     let opts = &[
-//!         optopt("o", "", "set output file name", "NAME"),
-//!         optflag("h", "help", "print this help menu")
-//!     ];
-//!     let matches = match getopts(&args[1..], opts) {
-//!         Ok(m) => { m }
-//!         Err(f) => { panic!(f.to_string()) }
-//!     };
-//!     if matches.opt_present("h") {
-//!         print_usage(&program, opts);
-//!         return;
-//!     }
-//!     let output = matches.opt_str("o");
-//!     let input = if !matches.free.is_empty() {
-//!         matches.free[0].clone()
-//!     } else {
-//!         print_usage(&program, opts);
-//!         return;
-//!     };
-//!     do_work(&input, output);
-//! }
-//! ```
-
-#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
-       html_root_url = "https://doc.rust-lang.org/nightly/",
-       html_playground_url = "https://play.rust-lang.org/",
-       test(attr(deny(warnings))))]
-
-#![deny(missing_docs)]
-#![deny(warnings)]
-
-use self::Name::*;
-use self::HasArg::*;
-use self::Occur::*;
-use self::Fail::*;
-use self::Optval::*;
-use self::SplitWithinState::*;
-use self::Whitespace::*;
-use self::LengthLimit::*;
-
-use std::fmt;
-use std::iter::repeat;
-use std::result;
-
-/// Name of an option. Either a string or a single char.
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub enum Name {
-    /// A string representing the long name of an option.
-    /// For example: "help"
-    Long(String),
-    /// A char representing the short name of an option.
-    /// For example: 'h'
-    Short(char),
-}
-
-/// Describes whether an option has an argument.
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub enum HasArg {
-    /// The option requires an argument.
-    Yes,
-    /// The option takes no argument.
-    No,
-    /// The option argument is optional.
-    Maybe,
-}
-
-/// Describes how often an option may occur.
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub enum Occur {
-    /// The option occurs once.
-    Req,
-    /// The option occurs at most once.
-    Optional,
-    /// The option occurs zero or more times.
-    Multi,
-}
-
-/// A description of a possible option.
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct Opt {
-    /// Name of the option
-    pub name: Name,
-    /// Whether it has an argument
-    pub hasarg: HasArg,
-    /// How often it can occur
-    pub occur: Occur,
-    /// Which options it aliases
-    pub aliases: Vec<Opt>,
-}
-
-/// One group of options, e.g., both `-h` and `--help`, along with
-/// their shared description and properties.
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct OptGroup {
-    /// Short name of the option, e.g. `h` for a `-h` option
-    pub short_name: String,
-    /// Long name of the option, e.g. `help` for a `--help` option
-    pub long_name: String,
-    /// Hint for argument, e.g. `FILE` for a `-o FILE` option
-    pub hint: String,
-    /// Description for usage help text
-    pub desc: String,
-    /// Whether option has an argument
-    pub hasarg: HasArg,
-    /// How often it can occur
-    pub occur: Occur,
-}
-
-/// Describes whether an option is given at all or has a value.
-#[derive(Clone, PartialEq, Eq, Debug)]
-enum Optval {
-    Val(String),
-    Given,
-}
-
-/// The result of checking command line arguments. Contains a vector
-/// of matches and a vector of free strings.
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct Matches {
-    /// Options that matched
-    opts: Vec<Opt>,
-    /// Values of the Options that matched
-    vals: Vec<Vec<Optval>>,
-    /// Free string fragments
-    pub free: Vec<String>,
-}
-
-/// The type returned when the command line does not conform to the
-/// expected format. Use the `Debug` implementation to output detailed
-/// information.
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub enum Fail {
-    /// The option requires an argument but none was passed.
-    ArgumentMissing(String),
-    /// The passed option is not declared among the possible options.
-    UnrecognizedOption(String),
-    /// A required option is not present.
-    OptionMissing(String),
-    /// A single occurrence option is being used multiple times.
-    OptionDuplicated(String),
-    /// There's an argument being passed to a non-argument option.
-    UnexpectedArgument(String),
-}
-
-/// The type of failure that occurred.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-#[allow(missing_docs)]
-pub enum FailType {
-    ArgumentMissing_,
-    UnrecognizedOption_,
-    OptionMissing_,
-    OptionDuplicated_,
-    UnexpectedArgument_,
-}
-
-/// The result of parsing a command line with a set of options.
-pub type Result = result::Result<Matches, Fail>;
-
-impl Name {
-    fn from_str(nm: &str) -> Name {
-        if nm.len() == 1 {
-            Short(nm.chars().next().unwrap())
-        } else {
-            Long(nm.to_owned())
-        }
-    }
-
-    fn to_string(&self) -> String {
-        match *self {
-            Short(ch) => ch.to_string(),
-            Long(ref s) => s.to_owned(),
-        }
-    }
-}
-
-impl OptGroup {
-    /// Translate OptGroup into Opt.
-    /// (Both short and long names correspond to different Opts).
-    pub fn long_to_short(&self) -> Opt {
-        let OptGroup {
-            short_name,
-            long_name,
-            hasarg,
-            occur,
-            ..
-        } = (*self).clone();
-
-        match (short_name.len(), long_name.len()) {
-            (0, 0) => panic!("this long-format option was given no name"),
-            (0, _) => {
-                Opt {
-                    name: Long((long_name)),
-                    hasarg,
-                    occur,
-                    aliases: Vec::new(),
-                }
-            }
-            (1, 0) => {
-                Opt {
-                    name: Short(short_name.chars().next().unwrap()),
-                    hasarg,
-                    occur,
-                    aliases: Vec::new(),
-                }
-            }
-            (1, _) => {
-                Opt {
-                    name: Long((long_name)),
-                    hasarg,
-                    occur,
-                    aliases: vec![Opt {
-                                      name: Short(short_name.chars().next().unwrap()),
-                                      hasarg,
-                                      occur,
-                                      aliases: Vec::new(),
-                                  }],
-                }
-            }
-            _ => panic!("something is wrong with the long-form opt"),
-        }
-    }
-}
-
-impl Matches {
-    fn opt_vals(&self, nm: &str) -> Vec<Optval> {
-        match find_opt(&self.opts[..], Name::from_str(nm)) {
-            Some(id) => self.vals[id].clone(),
-            None => panic!("No option '{}' defined", nm),
-        }
-    }
-
-    fn opt_val(&self, nm: &str) -> Option<Optval> {
-        let vals = self.opt_vals(nm);
-        if vals.is_empty() {
-            None
-        } else {
-            Some(vals[0].clone())
-        }
-    }
-
-    /// Returns true if an option was matched.
-    pub fn opt_present(&self, nm: &str) -> bool {
-        !self.opt_vals(nm).is_empty()
-    }
-
-    /// Returns the number of times an option was matched.
-    pub fn opt_count(&self, nm: &str) -> usize {
-        self.opt_vals(nm).len()
-    }
-
-    /// Returns true if any of several options were matched.
-    pub fn opts_present(&self, names: &[String]) -> bool {
-        for nm in names {
-            match find_opt(&self.opts, Name::from_str(&**nm)) {
-                Some(id) if !self.vals[id].is_empty() => return true,
-                _ => (),
-            };
-        }
-        false
-    }
-
-    /// Returns the string argument supplied to one of several matching options or `None`.
-    pub fn opts_str(&self, names: &[String]) -> Option<String> {
-        for nm in names {
-            if let Some(Val(ref s)) = self.opt_val(&nm[..]) {
-                  return Some(s.clone())
-            }
-        }
-        None
-    }
-
-    /// Returns a vector of the arguments provided to all matches of the given
-    /// option.
-    ///
-    /// Used when an option accepts multiple values.
-    pub fn opt_strs(&self, nm: &str) -> Vec<String> {
-        let mut acc: Vec<String> = Vec::new();
-        let r = self.opt_vals(nm);
-        for v in &r {
-            match *v {
-                Val(ref s) => acc.push((*s).clone()),
-                _ => (),
-            }
-        }
-        acc
-    }
-
-    /// Returns the string argument supplied to a matching option or `None`.
-    pub fn opt_str(&self, nm: &str) -> Option<String> {
-        let vals = self.opt_vals(nm);
-        if vals.is_empty() {
-            return None::<String>;
-        }
-        match vals[0] {
-            Val(ref s) => Some((*s).clone()),
-            _ => None,
-        }
-    }
-
-
-    /// Returns the matching string, a default, or none.
-    ///
-    /// Returns none if the option was not present, `def` if the option was
-    /// present but no argument was provided, and the argument if the option was
-    /// present and an argument was provided.
-    pub fn opt_default(&self, nm: &str, def: &str) -> Option<String> {
-        let vals = self.opt_vals(nm);
-        if vals.is_empty() {
-            None
-        } else {
-            match vals[0] {
-                Val(ref s) => Some((*s).clone()),
-                _ => Some(def.to_owned()),
-            }
-        }
-    }
-}
-
-fn is_arg(arg: &str) -> bool {
-    arg.len() > 1 && arg.as_bytes()[0] == b'-'
-}
-
-fn find_opt(opts: &[Opt], nm: Name) -> Option<usize> {
-    // Search main options.
-    let pos = opts.iter().position(|opt| opt.name == nm);
-    if pos.is_some() {
-        return pos;
-    }
-
-    // Search in aliases.
-    for candidate in opts {
-        if candidate.aliases.iter().position(|opt| opt.name == nm).is_some() {
-            return opts.iter().position(|opt| opt.name == candidate.name);
-        }
-    }
-
-    None
-}
-
-/// Create a long option that is required and takes an argument.
-///
-/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
-/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
-/// * `desc` - Description for usage help
-/// * `hint` - Hint that is used in place of the argument in the usage help,
-///   e.g. `"FILE"` for a `-o FILE` option
-pub fn reqopt(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptGroup {
-    let len = short_name.len();
-    assert!(len == 1 || len == 0);
-    OptGroup {
-        short_name: short_name.to_owned(),
-        long_name: long_name.to_owned(),
-        hint: hint.to_owned(),
-        desc: desc.to_owned(),
-        hasarg: Yes,
-        occur: Req,
-    }
-}
-
-/// Create a long option that is optional and takes an argument.
-///
-/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
-/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
-/// * `desc` - Description for usage help
-/// * `hint` - Hint that is used in place of the argument in the usage help,
-///   e.g. `"FILE"` for a `-o FILE` option
-pub fn optopt(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptGroup {
-    let len = short_name.len();
-    assert!(len == 1 || len == 0);
-    OptGroup {
-        short_name: short_name.to_owned(),
-        long_name: long_name.to_owned(),
-        hint: hint.to_owned(),
-        desc: desc.to_owned(),
-        hasarg: Yes,
-        occur: Optional,
-    }
-}
-
-/// Create a long option that is optional and does not take an argument.
-///
-/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
-/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
-/// * `desc` - Description for usage help
-pub fn optflag(short_name: &str, long_name: &str, desc: &str) -> OptGroup {
-    let len = short_name.len();
-    assert!(len == 1 || len == 0);
-    OptGroup {
-        short_name: short_name.to_owned(),
-        long_name: long_name.to_owned(),
-        hint: "".to_owned(),
-        desc: desc.to_owned(),
-        hasarg: No,
-        occur: Optional,
-    }
-}
-
-/// Create a long option that can occur more than once and does not
-/// take an argument.
-///
-/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
-/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
-/// * `desc` - Description for usage help
-pub fn optflagmulti(short_name: &str, long_name: &str, desc: &str) -> OptGroup {
-    let len = short_name.len();
-    assert!(len == 1 || len == 0);
-    OptGroup {
-        short_name: short_name.to_owned(),
-        long_name: long_name.to_owned(),
-        hint: "".to_owned(),
-        desc: desc.to_owned(),
-        hasarg: No,
-        occur: Multi,
-    }
-}
-
-/// Create a long option that is optional and takes an optional argument.
-///
-/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
-/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
-/// * `desc` - Description for usage help
-/// * `hint` - Hint that is used in place of the argument in the usage help,
-///   e.g. `"FILE"` for a `-o FILE` option
-pub fn optflagopt(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptGroup {
-    let len = short_name.len();
-    assert!(len == 1 || len == 0);
-    OptGroup {
-        short_name: short_name.to_owned(),
-        long_name: long_name.to_owned(),
-        hint: hint.to_owned(),
-        desc: desc.to_owned(),
-        hasarg: Maybe,
-        occur: Optional,
-    }
-}
-
-/// Create a long option that is optional, takes an argument, and may occur
-/// multiple times.
-///
-/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
-/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
-/// * `desc` - Description for usage help
-/// * `hint` - Hint that is used in place of the argument in the usage help,
-///   e.g. `"FILE"` for a `-o FILE` option
-pub fn optmulti(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptGroup {
-    let len = short_name.len();
-    assert!(len == 1 || len == 0);
-    OptGroup {
-        short_name: short_name.to_owned(),
-        long_name: long_name.to_owned(),
-        hint: hint.to_owned(),
-        desc: desc.to_owned(),
-        hasarg: Yes,
-        occur: Multi,
-    }
-}
-
-/// Create a generic option group, stating all parameters explicitly
-pub fn opt(short_name: &str,
-           long_name: &str,
-           desc: &str,
-           hint: &str,
-           hasarg: HasArg,
-           occur: Occur)
-           -> OptGroup {
-    let len = short_name.len();
-    assert!(len == 1 || len == 0);
-    OptGroup {
-        short_name: short_name.to_owned(),
-        long_name: long_name.to_owned(),
-        hint: hint.to_owned(),
-        desc: desc.to_owned(),
-        hasarg,
-        occur,
-    }
-}
-
-impl fmt::Display for Fail {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            ArgumentMissing(ref nm) => write!(f, "Argument to option '{}' missing.", *nm),
-            UnrecognizedOption(ref nm) => write!(f, "Unrecognized option: '{}'.", *nm),
-            OptionMissing(ref nm) => write!(f, "Required option '{}' missing.", *nm),
-            OptionDuplicated(ref nm) => write!(f, "Option '{}' given more than once.", *nm),
-            UnexpectedArgument(ref nm) => write!(f, "Option '{}' does not take an argument.", *nm),
-        }
-    }
-}
-
-/// Parse command line arguments according to the provided options.
-///
-/// On success returns `Ok(Matches)`. Use methods such as `opt_present`
-/// `opt_str`, etc. to interrogate results.
-/// # Panics
-///
-/// Returns `Err(Fail)` on failure: use the `Debug` implementation of `Fail` to display
-/// information about it.
-pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
-    let opts: Vec<Opt> = optgrps.iter().map(|x| x.long_to_short()).collect();
-    let n_opts = opts.len();
-
-    fn f(_x: usize) -> Vec<Optval> {
-        Vec::new()
-    }
-
-    let mut vals: Vec<_> = (0..n_opts).map(f).collect();
-    let mut free: Vec<String> = Vec::new();
-    let l = args.len();
-    let mut i = 0;
-    while i < l {
-        let cur = args[i].clone();
-        let curlen = cur.len();
-        if !is_arg(&cur[..]) {
-            free.push(cur);
-        } else if cur == "--" {
-            let mut j = i + 1;
-            while j < l {
-                free.push(args[j].clone());
-                j += 1;
-            }
-            break;
-        } else {
-            let mut names;
-            let mut i_arg = None;
-            if cur.as_bytes()[1] == b'-' {
-                let tail = &cur[2..curlen];
-                let tail_eq: Vec<&str> = tail.splitn(2, '=').collect();
-                if tail_eq.len() <= 1 {
-                    names = vec![Long(tail.to_owned())];
-                } else {
-                    names = vec![Long(tail_eq[0].to_owned())];
-                    i_arg = Some(tail_eq[1].to_owned());
-                }
-            } else {
-                let mut j = 1;
-                names = Vec::new();
-                while j < curlen {
-                    let ch = cur[j..].chars().next().unwrap();
-                    let opt = Short(ch);
-
-                    // In a series of potential options (eg. -aheJ), if we
-                    // see one which takes an argument, we assume all
-                    // subsequent characters make up the argument. This
-                    // allows options such as -L/usr/local/lib/foo to be
-                    // interpreted correctly
-
-                    let opt_id = match find_opt(&opts, opt.clone()) {
-                        Some(id) => id,
-                        None => return Err(UnrecognizedOption(opt.to_string())),
-                    };
-
-                    names.push(opt);
-
-                    let arg_follows = match opts[opt_id].hasarg {
-                        Yes | Maybe => true,
-                        No => false,
-                    };
-
-                    let next = j + ch.len_utf8();
-                    if arg_follows && next < curlen {
-                        i_arg = Some((&cur[next..curlen]).to_owned());
-                        break;
-                    }
-
-                    j = next;
-                }
-            }
-            let mut name_pos = 0;
-            for nm in &names {
-                name_pos += 1;
-                let optid = match find_opt(&opts, (*nm).clone()) {
-                    Some(id) => id,
-                    None => return Err(UnrecognizedOption(nm.to_string())),
-                };
-                match opts[optid].hasarg {
-                    No => {
-                        if name_pos == names.len() && !i_arg.is_none() {
-                            return Err(UnexpectedArgument(nm.to_string()));
-                        }
-                        let v = &mut vals[optid];
-                        v.push(Given);
-                    }
-                    Maybe => {
-                        if !i_arg.is_none() {
-                            let v = &mut vals[optid];
-                            v.push(Val((i_arg.clone()).unwrap()));
-                        } else if name_pos < names.len() || i + 1 == l || is_arg(&args[i + 1][..]) {
-                            let v = &mut vals[optid];
-                            v.push(Given);
-                        } else {
-                            i += 1;
-                            let v = &mut vals[optid];
-                            v.push(Val(args[i].clone()));
-                        }
-                    }
-                    Yes => {
-                        if !i_arg.is_none() {
-                            let v = &mut vals[optid];
-                            v.push(Val(i_arg.clone().unwrap()));
-                        } else if i + 1 == l {
-                            return Err(ArgumentMissing(nm.to_string()));
-                        } else {
-                            i += 1;
-                            let v = &mut vals[optid];
-                            v.push(Val(args[i].clone()));
-                        }
-                    }
-                }
-            }
-        }
-        i += 1;
-    }
-    for i in 0..n_opts {
-        let n = vals[i].len();
-        let occ = opts[i].occur;
-        if occ == Req && n == 0 {
-            return Err(OptionMissing(opts[i].name.to_string()));
-        }
-        if occ != Multi && n > 1 {
-            return Err(OptionDuplicated(opts[i].name.to_string()));
-        }
-    }
-    Ok(Matches {
-        opts,
-        vals,
-        free,
-    })
-}
-
-/// Derive a usage message from a set of long options.
-pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
-
-    let desc_sep = format!("\n{}", repeat(" ").take(24).collect::<String>());
-
-    let rows = opts.iter().map(|optref| {
-        let OptGroup{short_name,
-                     long_name,
-                     hint,
-                     desc,
-                     hasarg,
-                     ..} = (*optref).clone();
-
-        let mut row = repeat(" ").take(4).collect::<String>();
-
-        // short option
-        match short_name.len() {
-            0 => {}
-            1 => {
-                row.push('-');
-                row.push_str(&short_name[..]);
-                row.push(' ');
-            }
-            _ => panic!("the short name should only be 1 ascii char long"),
-        }
-
-        // long option
-        match long_name.len() {
-            0 => {}
-            _ => {
-                row.push_str("--");
-                row.push_str(&long_name[..]);
-                row.push(' ');
-            }
-        }
-
-        // arg
-        match hasarg {
-            No => {}
-            Yes => row.push_str(&hint[..]),
-            Maybe => {
-                row.push('[');
-                row.push_str(&hint[..]);
-                row.push(']');
-            }
-        }
-
-        // FIXME(https://github.com/rust-lang-nursery/getopts/issues/7)
-        // should be graphemes not codepoints
-        //
-        // here we just need to indent the start of the description
-        let rowlen = row.chars().count();
-        if rowlen < 24 {
-            for _ in 0..24 - rowlen {
-                row.push(' ');
-            }
-        } else {
-            row.push_str(&desc_sep[..]);
-        }
-
-        // Normalize desc to contain words separated by one space character
-        let mut desc_normalized_whitespace = String::new();
-        for word in desc.split_whitespace() {
-            desc_normalized_whitespace.push_str(word);
-            desc_normalized_whitespace.push(' ');
-        }
-
-        // FIXME(https://github.com/rust-lang-nursery/getopts/issues/7)
-        // should be graphemes not codepoints
-        let mut desc_rows = Vec::new();
-        each_split_within(&desc_normalized_whitespace[..], 54, |substr| {
-            desc_rows.push(substr.to_owned());
-            true
-        });
-
-        // FIXME(https://github.com/rust-lang-nursery/getopts/issues/7)
-        // should be graphemes not codepoints
-        //
-        // wrapped description
-        row.push_str(&desc_rows.join(&desc_sep[..]));
-
-        row
-    });
-
-    format!("{}\n\nOptions:\n{}\n",
-            brief,
-            rows.collect::<Vec<String>>().join("\n"))
-}
-
-fn format_option(opt: &OptGroup) -> String {
-    let mut line = String::new();
-
-    if opt.occur != Req {
-        line.push('[');
-    }
-
-    // Use short_name is possible, but fallback to long_name.
-    if !opt.short_name.is_empty() {
-        line.push('-');
-        line.push_str(&opt.short_name[..]);
-    } else {
-        line.push_str("--");
-        line.push_str(&opt.long_name[..]);
-    }
-
-    if opt.hasarg != No {
-        line.push(' ');
-        if opt.hasarg == Maybe {
-            line.push('[');
-        }
-        line.push_str(&opt.hint[..]);
-        if opt.hasarg == Maybe {
-            line.push(']');
-        }
-    }
-
-    if opt.occur != Req {
-        line.push(']');
-    }
-    if opt.occur == Multi {
-        line.push_str("..");
-    }
-
-    line
-}
-
-/// Derive a short one-line usage summary from a set of long options.
-pub fn short_usage(program_name: &str, opts: &[OptGroup]) -> String {
-    let mut line = format!("Usage: {} ", program_name);
-    line.push_str(&opts.iter()
-                       .map(format_option)
-                       .collect::<Vec<String>>()
-                       .join(" ")[..]);
-    line
-}
-
-#[derive(Copy, Clone)]
-enum SplitWithinState {
-    A, // leading whitespace, initial state
-    B, // words
-    C, // internal and trailing whitespace
-}
-#[derive(Copy, Clone)]
-enum Whitespace {
-    Ws, // current char is whitespace
-    Cr, // current char is not whitespace
-}
-#[derive(Copy, Clone)]
-enum LengthLimit {
-    UnderLim, // current char makes current substring still fit in limit
-    OverLim, // current char makes current substring no longer fit in limit
-}
-
-
-/// Splits a string into substrings with possibly internal whitespace,
-/// each of them at most `lim` bytes long. The substrings have leading and trailing
-/// whitespace removed, and are only cut at whitespace boundaries.
-///
-/// Note: Function was moved here from `std::str` because this module is the only place that
-/// uses it, and because it was too specific for a general string function.
-///
-/// # Panics
-///
-/// Panics during iteration if the string contains a non-whitespace
-/// sequence longer than the limit.
-fn each_split_within<F>(ss: &str, lim: usize, mut it: F) -> bool
-    where F: FnMut(&str) -> bool
-{
-    // Just for fun, let's write this as a state machine:
-
-    let mut slice_start = 0;
-    let mut last_start = 0;
-    let mut last_end = 0;
-    let mut state = A;
-    let mut fake_i = ss.len();
-    let mut lim = lim;
-
-    let mut cont = true;
-
-    // if the limit is larger than the string, lower it to save cycles
-    if lim >= fake_i {
-        lim = fake_i;
-    }
-
-    let mut machine = |cont: &mut bool, (i, c): (usize, char)| -> bool {
-        let whitespace = if c.is_whitespace() {
-            Ws
-        } else {
-            Cr
-        };
-        let limit = if (i - slice_start + 1) <= lim {
-            UnderLim
-        } else {
-            OverLim
-        };
-
-        state = match (state, whitespace, limit) {
-            (A, Ws, _) => A,
-            (A, Cr, _) => {
-                slice_start = i;
-                last_start = i;
-                B
-            }
-
-            (B, Cr, UnderLim) => B,
-            (B, Cr, OverLim) if (i - last_start + 1) > lim => {
-                panic!("word starting with {} longer than limit!",
-                       &ss[last_start..i + 1])
-            }
-            (B, Cr, OverLim) => {
-                *cont = it(&ss[slice_start..last_end]);
-                slice_start = last_start;
-                B
-            }
-            (B, Ws, UnderLim) => {
-                last_end = i;
-                C
-            }
-            (B, Ws, OverLim) => {
-                last_end = i;
-                *cont = it(&ss[slice_start..last_end]);
-                A
-            }
-
-            (C, Cr, UnderLim) => {
-                last_start = i;
-                B
-            }
-            (C, Cr, OverLim) => {
-                *cont = it(&ss[slice_start..last_end]);
-                slice_start = i;
-                last_start = i;
-                last_end = i;
-                B
-            }
-            (C, Ws, OverLim) => {
-                *cont = it(&ss[slice_start..last_end]);
-                A
-            }
-            (C, Ws, UnderLim) => C,
-        };
-
-        *cont
-    };
-
-    ss.char_indices().all(|x| machine(&mut cont, x));
-
-    // Let the automaton 'run out' by supplying trailing whitespace
-    while cont &&
-          match state {
-        B | C => true,
-        A => false,
-    } {
-        machine(&mut cont, (fake_i, ' '));
-        fake_i += 1;
-    }
-    cont
-}
-
-#[test]
-fn test_split_within() {
-    fn t(s: &str, i: usize, u: &[String]) {
-        let mut v = Vec::new();
-        each_split_within(s, i, |s| {
-            v.push(s.to_string());
-            true
-        });
-        assert!(v.iter().zip(u).all(|(a, b)| a == b));
-    }
-    t("", 0, &[]);
-    t("", 15, &[]);
-    t("hello", 15, &["hello".to_string()]);
-    t("\nMary had a little lamb\nLittle lamb\n",
-      15,
-      &["Mary had a".to_string(), "little lamb".to_string(), "Little lamb".to_string()]);
-    t("\nMary had a little lamb\nLittle lamb\n",
-      ::std::usize::MAX,
-      &["Mary had a little lamb\nLittle lamb".to_string()]);
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    use std::result::Result::{Err, Ok};
-    use std::result;
-
-    // Tests for reqopt
-    #[test]
-    fn test_reqopt() {
-        let long_args = vec!["--test=20".to_string()];
-        let opts = vec![reqopt("t", "test", "testing", "TEST")];
-        let rs = getopts(&long_args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert!(m.opt_present("test"));
-                assert_eq!(m.opt_str("test").unwrap(), "20");
-                assert!(m.opt_present("t"));
-                assert_eq!(m.opt_str("t").unwrap(), "20");
-            }
-            _ => {
-                panic!("test_reqopt failed (long arg)");
-            }
-        }
-        let short_args = vec!["-t".to_string(), "20".to_string()];
-        match getopts(&short_args, &opts) {
-            Ok(ref m) => {
-                assert!((m.opt_present("test")));
-                assert_eq!(m.opt_str("test").unwrap(), "20");
-                assert!((m.opt_present("t")));
-                assert_eq!(m.opt_str("t").unwrap(), "20");
-            }
-            _ => {
-                panic!("test_reqopt failed (short arg)");
-            }
-        }
-    }
-
-    #[test]
-    fn test_reqopt_missing() {
-        let args = vec!["blah".to_string()];
-        let opts = vec![reqopt("t", "test", "testing", "TEST")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Err(OptionMissing(_)) => {}
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_reqopt_no_arg() {
-        let long_args = vec!["--test".to_string()];
-        let opts = vec![reqopt("t", "test", "testing", "TEST")];
-        let rs = getopts(&long_args, &opts);
-        match rs {
-            Err(ArgumentMissing(_)) => {}
-            _ => panic!(),
-        }
-        let short_args = vec!["-t".to_string()];
-        match getopts(&short_args, &opts) {
-            Err(ArgumentMissing(_)) => {}
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_reqopt_multi() {
-        let args = vec!["--test=20".to_string(), "-t".to_string(), "30".to_string()];
-        let opts = vec![reqopt("t", "test", "testing", "TEST")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Err(OptionDuplicated(_)) => {}
-            _ => panic!(),
-        }
-    }
-
-    // Tests for optopt
-    #[test]
-    fn test_optopt() {
-        let long_args = vec!["--test=20".to_string()];
-        let opts = vec![optopt("t", "test", "testing", "TEST")];
-        let rs = getopts(&long_args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert!(m.opt_present("test"));
-                assert_eq!(m.opt_str("test").unwrap(), "20");
-                assert!((m.opt_present("t")));
-                assert_eq!(m.opt_str("t").unwrap(), "20");
-            }
-            _ => panic!(),
-        }
-        let short_args = vec!["-t".to_string(), "20".to_string()];
-        match getopts(&short_args, &opts) {
-            Ok(ref m) => {
-                assert!((m.opt_present("test")));
-                assert_eq!(m.opt_str("test").unwrap(), "20");
-                assert!((m.opt_present("t")));
-                assert_eq!(m.opt_str("t").unwrap(), "20");
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optopt_missing() {
-        let args = vec!["blah".to_string()];
-        let opts = vec![optopt("t", "test", "testing", "TEST")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert!(!m.opt_present("test"));
-                assert!(!m.opt_present("t"));
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optopt_no_arg() {
-        let long_args = vec!["--test".to_string()];
-        let opts = vec![optopt("t", "test", "testing", "TEST")];
-        let rs = getopts(&long_args, &opts);
-        match rs {
-            Err(ArgumentMissing(_)) => {}
-            _ => panic!(),
-        }
-        let short_args = vec!["-t".to_string()];
-        match getopts(&short_args, &opts) {
-            Err(ArgumentMissing(_)) => {}
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optopt_multi() {
-        let args = vec!["--test=20".to_string(), "-t".to_string(), "30".to_string()];
-        let opts = vec![optopt("t", "test", "testing", "TEST")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Err(OptionDuplicated(_)) => {}
-            _ => panic!(),
-        }
-    }
-
-    // Tests for optflag
-    #[test]
-    fn test_optflag() {
-        let long_args = vec!["--test".to_string()];
-        let opts = vec![optflag("t", "test", "testing")];
-        let rs = getopts(&long_args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert!(m.opt_present("test"));
-                assert!(m.opt_present("t"));
-            }
-            _ => panic!(),
-        }
-        let short_args = vec!["-t".to_string()];
-        match getopts(&short_args, &opts) {
-            Ok(ref m) => {
-                assert!(m.opt_present("test"));
-                assert!(m.opt_present("t"));
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optflag_missing() {
-        let args = vec!["blah".to_string()];
-        let opts = vec![optflag("t", "test", "testing")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert!(!m.opt_present("test"));
-                assert!(!m.opt_present("t"));
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optflag_long_arg() {
-        let args = vec!["--test=20".to_string()];
-        let opts = vec![optflag("t", "test", "testing")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Err(UnexpectedArgument(_)) => {}
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optflag_multi() {
-        let args = vec!["--test".to_string(), "-t".to_string()];
-        let opts = vec![optflag("t", "test", "testing")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Err(OptionDuplicated(_)) => {}
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optflag_short_arg() {
-        let args = vec!["-t".to_string(), "20".to_string()];
-        let opts = vec![optflag("t", "test", "testing")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                // The next variable after the flag is just a free argument
-
-                assert!(m.free[0] == "20");
-            }
-            _ => panic!(),
-        }
-    }
-
-    // Tests for optflagmulti
-    #[test]
-    fn test_optflagmulti_short1() {
-        let args = vec!["-v".to_string()];
-        let opts = vec![optflagmulti("v", "verbose", "verbosity")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert_eq!(m.opt_count("v"), 1);
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optflagmulti_short2a() {
-        let args = vec!["-v".to_string(), "-v".to_string()];
-        let opts = vec![optflagmulti("v", "verbose", "verbosity")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert_eq!(m.opt_count("v"), 2);
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optflagmulti_short2b() {
-        let args = vec!["-vv".to_string()];
-        let opts = vec![optflagmulti("v", "verbose", "verbosity")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert_eq!(m.opt_count("v"), 2);
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optflagmulti_long1() {
-        let args = vec!["--verbose".to_string()];
-        let opts = vec![optflagmulti("v", "verbose", "verbosity")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert_eq!(m.opt_count("verbose"), 1);
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optflagmulti_long2() {
-        let args = vec!["--verbose".to_string(), "--verbose".to_string()];
-        let opts = vec![optflagmulti("v", "verbose", "verbosity")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert_eq!(m.opt_count("verbose"), 2);
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optflagmulti_mix() {
-        let args = vec!["--verbose".to_string(),
-                        "-v".to_string(),
-                        "-vv".to_string(),
-                        "verbose".to_string()];
-        let opts = vec![optflagmulti("v", "verbose", "verbosity")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert_eq!(m.opt_count("verbose"), 4);
-                assert_eq!(m.opt_count("v"), 4);
-            }
-            _ => panic!(),
-        }
-    }
-
-    // Tests for optmulti
-    #[test]
-    fn test_optmulti() {
-        let long_args = vec!["--test=20".to_string()];
-        let opts = vec![optmulti("t", "test", "testing", "TEST")];
-        let rs = getopts(&long_args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert!((m.opt_present("test")));
-                assert_eq!(m.opt_str("test").unwrap(), "20");
-                assert!((m.opt_present("t")));
-                assert_eq!(m.opt_str("t").unwrap(), "20");
-            }
-            _ => panic!(),
-        }
-        let short_args = vec!["-t".to_string(), "20".to_string()];
-        match getopts(&short_args, &opts) {
-            Ok(ref m) => {
-                assert!((m.opt_present("test")));
-                assert_eq!(m.opt_str("test").unwrap(), "20");
-                assert!((m.opt_present("t")));
-                assert_eq!(m.opt_str("t").unwrap(), "20");
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optmulti_missing() {
-        let args = vec!["blah".to_string()];
-        let opts = vec![optmulti("t", "test", "testing", "TEST")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert!(!m.opt_present("test"));
-                assert!(!m.opt_present("t"));
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optmulti_no_arg() {
-        let long_args = vec!["--test".to_string()];
-        let opts = vec![optmulti("t", "test", "testing", "TEST")];
-        let rs = getopts(&long_args, &opts);
-        match rs {
-            Err(ArgumentMissing(_)) => {}
-            _ => panic!(),
-        }
-        let short_args = vec!["-t".to_string()];
-        match getopts(&short_args, &opts) {
-            Err(ArgumentMissing(_)) => {}
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_optmulti_multi() {
-        let args = vec!["--test=20".to_string(), "-t".to_string(), "30".to_string()];
-        let opts = vec![optmulti("t", "test", "testing", "TEST")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert!(m.opt_present("test"));
-                assert_eq!(m.opt_str("test").unwrap(), "20");
-                assert!(m.opt_present("t"));
-                assert_eq!(m.opt_str("t").unwrap(), "20");
-                let pair = m.opt_strs("test");
-                assert!(pair[0] == "20");
-                assert!(pair[1] == "30");
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_unrecognized_option() {
-        let long_args = vec!["--untest".to_string()];
-        let opts = vec![optmulti("t", "test", "testing", "TEST")];
-        let rs = getopts(&long_args, &opts);
-        match rs {
-            Err(UnrecognizedOption(_)) => {}
-            _ => panic!(),
-        }
-        let short_args = vec!["-u".to_string()];
-        match getopts(&short_args, &opts) {
-            Err(UnrecognizedOption(_)) => {}
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_combined() {
-        let args = vec!["prog".to_string(),
-                        "free1".to_string(),
-                        "-s".to_string(),
-                        "20".to_string(),
-                        "free2".to_string(),
-                        "--flag".to_string(),
-                        "--long=30".to_string(),
-                        "-f".to_string(),
-                        "-m".to_string(),
-                        "40".to_string(),
-                        "-m".to_string(),
-                        "50".to_string(),
-                        "-n".to_string(),
-                        "-A B".to_string(),
-                        "-n".to_string(),
-                        "-60 70".to_string()];
-        let opts = vec![optopt("s", "something", "something", "SOMETHING"),
-                        optflag("", "flag", "a flag"),
-                        reqopt("", "long", "hi", "LONG"),
-                        optflag("f", "", "another flag"),
-                        optmulti("m", "", "mmmmmm", "YUM"),
-                        optmulti("n", "", "nothing", "NOTHING"),
-                        optopt("", "notpresent", "nothing to see here", "NOPE")];
-        let rs = getopts(&args, &opts);
-        match rs {
-            Ok(ref m) => {
-                assert!(m.free[0] == "prog");
-                assert!(m.free[1] == "free1");
-                assert_eq!(m.opt_str("s").unwrap(), "20");
-                assert!(m.free[2] == "free2");
-                assert!((m.opt_present("flag")));
-                assert_eq!(m.opt_str("long").unwrap(), "30");
-                assert!((m.opt_present("f")));
-                let pair = m.opt_strs("m");
-                assert!(pair[0] == "40");
-                assert!(pair[1] == "50");
-                let pair = m.opt_strs("n");
-                assert!(pair[0] == "-A B");
-                assert!(pair[1] == "-60 70");
-                assert!((!m.opt_present("notpresent")));
-            }
-            _ => panic!(),
-        }
-    }
-
-    #[test]
-    fn test_multi() {
-        let opts = vec![optopt("e", "", "encrypt", "ENCRYPT"),
-                        optopt("", "encrypt", "encrypt", "ENCRYPT"),
-                        optopt("f", "", "flag", "FLAG")];
-
-        let args_single = vec!["-e".to_string(), "foo".to_string()];
-        let matches_single = &match getopts(&args_single, &opts) {
-            result::Result::Ok(m) => m,
-            result::Result::Err(_) => panic!(),
-        };
-        assert!(matches_single.opts_present(&["e".to_string()]));
-        assert!(matches_single.opts_present(&["encrypt".to_string(), "e".to_string()]));
-        assert!(matches_single.opts_present(&["e".to_string(), "encrypt".to_string()]));
-        assert!(!matches_single.opts_present(&["encrypt".to_string()]));
-        assert!(!matches_single.opts_present(&["thing".to_string()]));
-        assert!(!matches_single.opts_present(&[]));
-
-        assert_eq!(matches_single.opts_str(&["e".to_string()]).unwrap(), "foo");
-        assert_eq!(matches_single.opts_str(&["e".to_string(), "encrypt".to_string()]).unwrap(),
-                   "foo");
-        assert_eq!(matches_single.opts_str(&["encrypt".to_string(), "e".to_string()]).unwrap(),
-                   "foo");
-
-        let args_both = vec!["-e".to_string(),
-                             "foo".to_string(),
-                             "--encrypt".to_string(),
-                             "foo".to_string()];
-        let matches_both = &match getopts(&args_both, &opts) {
-            result::Result::Ok(m) => m,
-            result::Result::Err(_) => panic!(),
-        };
-        assert!(matches_both.opts_present(&["e".to_string()]));
-        assert!(matches_both.opts_present(&["encrypt".to_string()]));
-        assert!(matches_both.opts_present(&["encrypt".to_string(), "e".to_string()]));
-        assert!(matches_both.opts_present(&["e".to_string(), "encrypt".to_string()]));
-        assert!(!matches_both.opts_present(&["f".to_string()]));
-        assert!(!matches_both.opts_present(&["thing".to_string()]));
-        assert!(!matches_both.opts_present(&[]));
-
-        assert_eq!(matches_both.opts_str(&["e".to_string()]).unwrap(), "foo");
-        assert_eq!(matches_both.opts_str(&["encrypt".to_string()]).unwrap(),
-                   "foo");
-        assert_eq!(matches_both.opts_str(&["e".to_string(), "encrypt".to_string()]).unwrap(),
-                   "foo");
-        assert_eq!(matches_both.opts_str(&["encrypt".to_string(), "e".to_string()]).unwrap(),
-                   "foo");
-    }
-
-    #[test]
-    fn test_nospace() {
-        let args = vec!["-Lfoo".to_string(), "-M.".to_string()];
-        let opts = vec![optmulti("L", "", "library directory", "LIB"),
-                        optmulti("M", "", "something", "MMMM")];
-        let matches = &match getopts(&args, &opts) {
-            result::Result::Ok(m) => m,
-            result::Result::Err(_) => panic!(),
-        };
-        assert!(matches.opts_present(&["L".to_string()]));
-        assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "foo");
-        assert!(matches.opts_present(&["M".to_string()]));
-        assert_eq!(matches.opts_str(&["M".to_string()]).unwrap(), ".");
-
-    }
-
-    #[test]
-    fn test_nospace_conflict() {
-        let args = vec!["-vvLverbose".to_string(), "-v".to_string()];
-        let opts = vec![optmulti("L", "", "library directory", "LIB"),
-                        optflagmulti("v", "verbose", "Verbose")];
-        let matches = &match getopts(&args, &opts) {
-            result::Result::Ok(m) => m,
-            result::Result::Err(e) => panic!("{}", e),
-        };
-        assert!(matches.opts_present(&["L".to_string()]));
-        assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "verbose");
-        assert!(matches.opts_present(&["v".to_string()]));
-        assert_eq!(3, matches.opt_count("v"));
-    }
-
-    #[test]
-    fn test_long_to_short() {
-        let mut short = Opt {
-            name: Name::Long("banana".to_string()),
-            hasarg: HasArg::Yes,
-            occur: Occur::Req,
-            aliases: Vec::new(),
-        };
-        short.aliases = vec![Opt {
-                                 name: Name::Short('b'),
-                                 hasarg: HasArg::Yes,
-                                 occur: Occur::Req,
-                                 aliases: Vec::new(),
-                             }];
-        let verbose = reqopt("b", "banana", "some bananas", "VAL");
-
-        assert!(verbose.long_to_short() == short);
-    }
-
-    #[test]
-    fn test_aliases_long_and_short() {
-        let opts = vec![optflagmulti("a", "apple", "Desc")];
-
-        let args = vec!["-a".to_string(), "--apple".to_string(), "-a".to_string()];
-
-        let matches = getopts(&args, &opts).unwrap();
-        assert_eq!(3, matches.opt_count("a"));
-        assert_eq!(3, matches.opt_count("apple"));
-    }
-
-    #[test]
-    fn test_usage() {
-        let optgroups = vec![reqopt("b", "banana", "Desc", "VAL"),
-                             optopt("a", "012345678901234567890123456789", "Desc", "VAL"),
-                             optflag("k", "kiwi", "Desc"),
-                             optflagopt("p", "", "Desc", "VAL"),
-                             optmulti("l", "", "Desc", "VAL")];
-
-        let expected =
-"Usage: fruits
-
-Options:
-    -b --banana VAL     Desc
-    -a --012345678901234567890123456789 VAL
-                        Desc
-    -k --kiwi           Desc
-    -p [VAL]            Desc
-    -l VAL              Desc
-";
-
-        let generated_usage = usage("Usage: fruits", &optgroups);
-
-        assert_eq!(generated_usage, expected);
-    }
-
-    #[test]
-    fn test_usage_description_wrapping() {
-        // indentation should be 24 spaces
-        // lines wrap after 78: or rather descriptions wrap after 54
-
-        let optgroups = vec![optflag("k",
-                                     "kiwi",
-                                     // 54
-                                     "This is a long description which won't be wrapped..+.."),
-                             optflag("a",
-                                     "apple",
-                                     "This is a long description which _will_ be wrapped..+..")];
-
-        let expected =
-"Usage: fruits
-
-Options:
-    -k --kiwi           This is a long description which won't be wrapped..+..
-    -a --apple          This is a long description which _will_ be
-                        wrapped..+..
-";
-
-        let usage = usage("Usage: fruits", &optgroups);
-
-        assert!(usage == expected)
-    }
-
-    #[test]
-    fn test_usage_description_multibyte_handling() {
-        let optgroups = vec![optflag("k",
-                                     "k\u{2013}w\u{2013}",
-                                     "The word kiwi is normally spelled with two i's"),
-                             optflag("a",
-                                     "apple",
-                                     "This \u{201C}description\u{201D} has some characters that \
-                                      could confuse the line wrapping; an apple costs 0.51€ in \
-                                      some parts of Europe.")];
-
-        let expected =
-"Usage: fruits
-
-Options:
-    -k --k–w–           The word kiwi is normally spelled with two i's
-    -a --apple          This “description” has some characters that could
-                        confuse the line wrapping; an apple costs 0.51€ in
-                        some parts of Europe.
-";
-
-        let usage = usage("Usage: fruits", &optgroups);
-
-        assert!(usage == expected)
-    }
-
-    #[test]
-    fn test_short_usage() {
-        let optgroups = vec![reqopt("b", "banana", "Desc", "VAL"),
-                             optopt("a", "012345678901234567890123456789", "Desc", "VAL"),
-                             optflag("k", "kiwi", "Desc"),
-                             optflagopt("p", "", "Desc", "VAL"),
-                             optmulti("l", "", "Desc", "VAL")];
-
-        let expected = "Usage: fruits -b VAL [-a VAL] [-k] [-p [VAL]] [-l VAL]..".to_string();
-        let generated_usage = short_usage("fruits", &optgroups);
-
-        assert_eq!(generated_usage, expected);
-    }
-
-    #[test]
-    fn test_args_with_equals() {
-        let args = vec!["--one".to_string(), "A=B".to_string(),
-                        "--two=C=D".to_string()];
-        let opts = vec![optopt("o", "one", "One", "INFO"),
-                        optopt("t", "two", "Two", "INFO")];
-        let matches = &match getopts(&args, &opts) {
-            result::Result::Ok(m) => m,
-            result::Result::Err(e) => panic!("{}", e)
-        };
-        assert_eq!(matches.opts_str(&["o".to_string()]).unwrap(), "A=B");
-        assert_eq!(matches.opts_str(&["t".to_string()]).unwrap(), "C=D");
-    }
-}
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index 1163c1a98d5ac..716a2cc6cbb11 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -34,7 +34,7 @@
        test(no_crate_inject, attr(deny(warnings))),
        test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
 
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(lang_items)]
@@ -680,9 +680,9 @@ impl TokenTree {
             Pound => op!('#'),
             Dollar => op!('$'),
             Question => op!('?'),
-            Underscore => op!('_'),
 
-            Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)),
+            Ident(ident, false) | Lifetime(ident) => TokenNode::Term(Term(ident.name)),
+            Ident(ident, true) => TokenNode::Term(Term(Symbol::intern(&format!("r#{}", ident)))),
             Literal(..) | DocComment(..) => TokenNode::Literal(self::Literal(token)),
 
             Interpolated(_) => {
@@ -714,8 +714,14 @@ impl TokenTree {
             },
             TokenNode::Term(symbol) => {
                 let ident = ast::Ident { name: symbol.0, ctxt: self.span.0.ctxt() };
+                let sym_str = symbol.0.as_str();
                 let token =
-                    if symbol.0.as_str().starts_with("'") { Lifetime(ident) } else { Ident(ident) };
+                    if sym_str.starts_with("'") { Lifetime(ident) }
+                    else if sym_str.starts_with("r#") {
+                        let name = Symbol::intern(&sym_str[2..]);
+                        let ident = ast::Ident { name, ctxt: self.span.0.ctxt() };
+                        Ident(ident, true)
+                    } else { Ident(ident, false) };
                 return TokenTree::Token(self.span.0, token).into();
             }
             TokenNode::Literal(token) => return TokenTree::Token(self.span.0, token.0).into(),
@@ -743,7 +749,6 @@ impl TokenTree {
             '#' => Pound,
             '$' => Dollar,
             '?' => Question,
-            '_' => Underscore,
             _ => panic!("unsupported character {}", op),
         };
 
diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs
index dd88dd933f691..8d6c7d68dfe23 100644
--- a/src/libprofiler_builtins/build.rs
+++ b/src/libprofiler_builtins/build.rs
@@ -27,6 +27,7 @@ fn main() {
                                    "InstrProfilingFile.c",
                                    "InstrProfilingMerge.c",
                                    "InstrProfilingMergeFile.c",
+                                   "InstrProfilingNameVar.c",
                                    "InstrProfilingPlatformDarwin.c",
                                    "InstrProfilingPlatformLinux.c",
                                    "InstrProfilingPlatformOther.c",
@@ -42,6 +43,8 @@ fn main() {
         cfg.define("strdup", Some("_strdup"));
         cfg.define("open", Some("_open"));
         cfg.define("fdopen", Some("_fdopen"));
+        cfg.define("getpid", Some("_getpid"));
+        cfg.define("fileno", Some("_fileno"));
     } else {
         // Turn off various features of gcc and such, mostly copying
         // compiler-rt's build system already
@@ -50,6 +53,7 @@ fn main() {
         cfg.flag("-fomit-frame-pointer");
         cfg.flag("-ffreestanding");
         cfg.define("VISIBILITY_HIDDEN", None);
+        cfg.define("COMPILER_RT_HAS_UNAME", Some("1"));
     }
 
     for src in profile_sources {
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index 7e84a69dd7913..2aae0f24d4849 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -56,3 +56,4 @@ byteorder = { version = "1.1", features = ["i128"]}
 #        later crate stop compiling. If you can remove this and everything
 #        compiles, then please feel free to do so!
 flate2 = "1.0"
+tempdir = "0.3"
diff --git a/src/librustc/benches/lib.rs b/src/librustc/benches/lib.rs
index 24294ec49ceed..278e0f9a26e43 100644
--- a/src/librustc/benches/lib.rs
+++ b/src/librustc/benches/lib.rs
@@ -10,7 +10,6 @@
 
 #![deny(warnings)]
 
-#![feature(slice_patterns)]
 #![feature(test)]
 
 extern crate test;
diff --git a/src/librustc/dep_graph/README.md b/src/librustc/dep_graph/README.md
index c8d0362f17c8e..f1f383d7ad126 100644
--- a/src/librustc/dep_graph/README.md
+++ b/src/librustc/dep_graph/README.md
@@ -1,295 +1,4 @@
-# Dependency graph for incremental compilation
+To learn more about how dependency tracking works in rustc, see the [rustc
+guide].
 
-This module contains the infrastructure for managing the incremental
-compilation dependency graph. This README aims to explain how it ought
-to be used. In this document, we'll first explain the overall
-strategy, and then share some tips for handling specific scenarios.
-
-The high-level idea is that we want to instrument the compiler to
-track which parts of the AST and other IR are read/written by what.
-This way, when we come back later, we can look at this graph and
-determine what work needs to be redone.
-
-### The dependency graph
-
-The nodes of the graph are defined by the enum `DepNode`. They represent
-one of three things:
-
-1. HIR nodes (like `Hir(DefId)`) represent the HIR input itself.
-2. Data nodes (like `TypeOfItem(DefId)`) represent some computed
-   information about a particular item.
-3. Procedure nodes (like `CoherenceCheckTrait(DefId)`) represent some
-   procedure that is executing. Usually this procedure is
-   performing some kind of check for errors. You can think of them as
-   computed values where the value being computed is `()` (and the
-   value may fail to be computed, if an error results).
-
-An edge `N1 -> N2` is added between two nodes if either:
-
-- the value of `N1` is used to compute `N2`;
-- `N1` is read by the procedure `N2`;
-- the procedure `N1` writes the value `N2`.
-
-The latter two conditions are equivalent to the first one if you think
-of procedures as values.
-
-### Basic tracking
-
-There is a very general strategy to ensure that you have a correct, if
-sometimes overconservative, dependency graph. The two main things you have
-to do are (a) identify shared state and (b) identify the current tasks.
-
-### Identifying shared state
-
-Identify "shared state" that will be written by one pass and read by
-another. In particular, we need to identify shared state that will be
-read "across items" -- that is, anything where changes in one item
-could invalidate work done for other items. So, for example:
-
-1. The signature for a function is "shared state".
-2. The computed type of some expression in the body of a function is
-   not shared state, because if it changes it does not itself
-   invalidate other functions (though it may be that it causes new
-   monomorphizations to occur, but that's handled independently).
-
-Put another way: if the HIR for an item changes, we are going to
-recompile that item for sure. But we need the dep tracking map to tell
-us what *else* we have to recompile. Shared state is anything that is
-used to communicate results from one item to another.
-
-### Identifying the current task, tracking reads/writes, etc
-
-FIXME(#42293). This text needs to be rewritten for the new red-green
-system, which doesn't fully exist yet.
-
-#### Dependency tracking map
-
-`DepTrackingMap` is a particularly convenient way to correctly store
-shared state. A `DepTrackingMap` is a special hashmap that will add
-edges automatically when `get` and `insert` are called. The idea is
-that, when you get/insert a value for the key `K`, we will add an edge
-from/to the node `DepNode::Variant(K)` (for some variant specific to
-the map).
-
-Each `DepTrackingMap` is parameterized by a special type `M` that
-implements `DepTrackingMapConfig`; this trait defines the key and value
-types of the map, and also defines a fn for converting from the key to
-a `DepNode` label. You don't usually have to muck about with this by
-hand, there is a macro for creating it. You can see the complete set
-of `DepTrackingMap` definitions in `librustc/middle/ty/maps.rs`.
-
-As an example, let's look at the `adt_defs` map. The `adt_defs` map
-maps from the def-id of a struct/enum to its `AdtDef`. It is defined
-using this macro:
-
-```rust
-dep_map_ty! { AdtDefs: ItemSignature(DefId) -> ty::AdtDefMaster<'tcx> }
-//            ~~~~~~~  ~~~~~~~~~~~~~ ~~~~~     ~~~~~~~~~~~~~~~~~~~~~~
-//               |           |      Key type       Value type
-//               |    DepNode variant
-//      Name of map id type
-```
-
-this indicates that a map id type `AdtDefs` will be created. The key
-of the map will be a `DefId` and value will be
-`ty::AdtDefMaster<'tcx>`. The `DepNode` will be created by
-`DepNode::ItemSignature(K)` for a given key.
-
-Once that is done, you can just use the `DepTrackingMap` like any
-other map:
-
-```rust
-let mut map: DepTrackingMap<M> = DepTrackingMap::new(dep_graph);
-map.insert(key, value); // registers dep_graph.write
-map.get(key; // registers dep_graph.read
-```
-
-#### Memoization
-
-One particularly interesting case is memoization. If you have some
-shared state that you compute in a memoized fashion, the correct thing
-to do is to define a `RefCell<DepTrackingMap>` for it and use the
-`memoize` helper:
-
-```rust
-map.memoize(key, || /* compute value */)
-```
-
-This will create a graph that looks like
-
-    ... -> MapVariant(key) -> CurrentTask
-
-where `MapVariant` is the `DepNode` variant that the map is associated with,
-and `...` are whatever edges the `/* compute value */` closure creates.
-
-In particular, using the memoize helper is much better than writing
-the obvious code yourself:
-
-```rust
-if let Some(result) = map.get(key) {
-    return result;
-}
-let value = /* compute value */;
-map.insert(key, value);
-```
-
-If you write that code manually, the dependency graph you get will
-include artificial edges that are not necessary. For example, imagine that
-two tasks, A and B, both invoke the manual memoization code, but A happens
-to go first. The resulting graph will be:
-
-    ... -> A -> MapVariant(key) -> B
-    ~~~~~~~~~~~~~~~~~~~~~~~~~~~       // caused by A writing to MapVariant(key)
-                ~~~~~~~~~~~~~~~~~~~~  // caused by B reading from MapVariant(key)
-
-This graph is not *wrong*, but it encodes a path from A to B that
-should not exist.  In contrast, using the memoized helper, you get:
-
-    ... -> MapVariant(key) -> A
-                 |
-                 +----------> B
-
-which is much cleaner.
-
-**Be aware though that the closure is executed with `MapVariant(key)`
-pushed onto the stack as the current task!** That means that you must
-add explicit `read` calls for any shared state that it accesses
-implicitly from its environment. See the section on "explicit calls to
-read and write when starting a new subtask" above for more details.
-
-### How to decide where to introduce a new task
-
-Certainly, you need at least one task on the stack: any attempt to
-`read` or `write` shared state will panic if there is no current
-task. But where does it make sense to introduce subtasks? The basic
-rule is that a subtask makes sense for any discrete unit of work you
-may want to skip in the future. Adding a subtask separates out the
-reads/writes from *that particular subtask* versus the larger
-context. An example: you might have a 'meta' task for all of borrow
-checking, and then subtasks for borrow checking individual fns.  (Seen
-in this light, memoized computations are just a special case where we
-may want to avoid redoing the work even within the context of one
-compilation.)
-
-The other case where you might want a subtask is to help with refining
-the reads/writes for some later bit of work that needs to be memoized.
-For example, we create a subtask for type-checking the body of each
-fn.  However, in the initial version of incr. comp. at least, we do
-not expect to actually *SKIP* type-checking -- we only expect to skip
-trans. However, it's still useful to create subtasks for type-checking
-individual items, because, otherwise, if a fn sig changes, we won't
-know which callers are affected -- in fact, because the graph would be
-so coarse, we'd just have to retrans everything, since we can't
-distinguish which fns used which fn sigs.
-
-### Testing the dependency graph
-
-There are various ways to write tests against the dependency graph.
-The simplest mechanism are the
-`#[rustc_if_this_changed]` and `#[rustc_then_this_would_need]`
-annotations. These are used in compile-fail tests to test whether the
-expected set of paths exist in the dependency graph. As an example,
-see `src/test/compile-fail/dep-graph-caller-callee.rs`.
-
-The idea is that you can annotate a test like:
-
-```rust
-#[rustc_if_this_changed]
-fn foo() { }
-
-#[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK
-fn bar() { foo(); }
-
-#[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path
-fn baz() { }
-```
-
-This will check whether there is a path in the dependency graph from
-`Hir(foo)` to `TypeckTables(bar)`. An error is reported for each
-`#[rustc_then_this_would_need]` annotation that indicates whether a
-path exists. `//~ ERROR` annotations can then be used to test if a
-path is found (as demonstrated above).
-
-### Debugging the dependency graph
-
-#### Dumping the graph
-
-The compiler is also capable of dumping the dependency graph for your
-debugging pleasure. To do so, pass the `-Z dump-dep-graph` flag. The
-graph will be dumped to `dep_graph.{txt,dot}` in the current
-directory.  You can override the filename with the `RUST_DEP_GRAPH`
-environment variable.
-
-Frequently, though, the full dep graph is quite overwhelming and not
-particularly helpful. Therefore, the compiler also allows you to filter
-the graph. You can filter in three ways:
-
-1. All edges originating in a particular set of nodes (usually a single node).
-2. All edges reaching a particular set of nodes.
-3. All edges that lie between given start and end nodes.
-
-To filter, use the `RUST_DEP_GRAPH_FILTER` environment variable, which should
-look like one of the following:
-
-```
-source_filter     // nodes originating from source_filter
--> target_filter  // nodes that can reach target_filter
-source_filter -> target_filter // nodes in between source_filter and target_filter
-```
-
-`source_filter` and `target_filter` are a `&`-separated list of strings.
-A node is considered to match a filter if all of those strings appear in its
-label. So, for example:
-
-```
-RUST_DEP_GRAPH_FILTER='-> TypeckTables'
-```
-
-would select the predecessors of all `TypeckTables` nodes. Usually though you
-want the `TypeckTables` node for some particular fn, so you might write:
-
-```
-RUST_DEP_GRAPH_FILTER='-> TypeckTables & bar'
-```
-
-This will select only the `TypeckTables` nodes for fns with `bar` in their name.
-
-Perhaps you are finding that when you change `foo` you need to re-type-check `bar`,
-but you don't think you should have to. In that case, you might do:
-
-```
-RUST_DEP_GRAPH_FILTER='Hir&foo -> TypeckTables & bar'
-```
-
-This will dump out all the nodes that lead from `Hir(foo)` to
-`TypeckTables(bar)`, from which you can (hopefully) see the source
-of the erroneous edge.
-
-#### Tracking down incorrect edges
-
-Sometimes, after you dump the dependency graph, you will find some
-path that should not exist, but you will not be quite sure how it came
-to be. **When the compiler is built with debug assertions,** it can
-help you track that down. Simply set the `RUST_FORBID_DEP_GRAPH_EDGE`
-environment variable to a filter. Every edge created in the dep-graph
-will be tested against that filter -- if it matches, a `bug!` is
-reported, so you can easily see the backtrace (`RUST_BACKTRACE=1`).
-
-The syntax for these filters is the same as described in the previous
-section. However, note that this filter is applied to every **edge**
-and doesn't handle longer paths in the graph, unlike the previous
-section.
-
-Example:
-
-You find that there is a path from the `Hir` of `foo` to the type
-check of `bar` and you don't think there should be. You dump the
-dep-graph as described in the previous section and open `dep-graph.txt`
-to see something like:
-
-    Hir(foo) -> Collect(bar)
-    Collect(bar) -> TypeckTables(bar)
-
-That first edge looks suspicious to you. So you set
-`RUST_FORBID_DEP_GRAPH_EDGE` to `Hir&foo -> Collect&bar`, re-run, and
-then observe the backtrace. Voila, bug fixed!
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/query.html
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 8d7fef90b754e..42cda6a05a1a7 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -579,6 +579,9 @@ define_dep_nodes!( <'tcx>
     [] GetPanicStrategy(CrateNum),
     [] IsNoBuiltins(CrateNum),
     [] ImplDefaultness(DefId),
+    [] CheckItemWellFormed(DefId),
+    [] CheckTraitItemWellFormed(DefId),
+    [] CheckImplItemWellFormed(DefId),
     [] ReachableNonGenerics(CrateNum),
     [] NativeLibraries(CrateNum),
     [] PluginRegistrarFn(CrateNum),
@@ -590,6 +593,7 @@ define_dep_nodes!( <'tcx>
     [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId },
     [] AllTraitImplementations(CrateNum),
 
+    [] DllimportForeignItems(CrateNum),
     [] IsDllimportForeignItem(DefId),
     [] IsStaticallyIncludedForeignItem(DefId),
     [] NativeLibraryKind(DefId),
@@ -613,8 +617,6 @@ define_dep_nodes!( <'tcx>
     [input] MissingExternCrateItem(CrateNum),
     [input] UsedCrateSource(CrateNum),
     [input] PostorderCnums,
-    [] HasCloneClosures(CrateNum),
-    [] HasCopyClosures(CrateNum),
 
     // This query is not expected to have inputs -- as a result, it's
     // not a good candidate for "replay" because it's essentially a
@@ -647,7 +649,13 @@ define_dep_nodes!( <'tcx>
 
     [] GetSymbolExportLevel(DefId),
 
+    [] WasmCustomSections(CrateNum),
+
     [input] Features,
+
+    [] ProgramClausesFor(DefId),
+    [] WasmImportModuleMap(CrateNum),
+    [] ForeignModules(CrateNum),
 );
 
 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 0ad79eacd2b03..d60c22064d3a0 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -476,10 +476,8 @@ impl DepGraph {
             fingerprints.resize(current_dep_graph.nodes.len(), Fingerprint::ZERO);
         }
 
-        let nodes: IndexVec<_, (DepNode, Fingerprint)> =
-            current_dep_graph.nodes.iter_enumerated().map(|(idx, &dep_node)| {
-            (dep_node, fingerprints[idx])
-        }).collect();
+        let fingerprints = fingerprints.clone().convert_index_type();
+        let nodes = current_dep_graph.nodes.clone().convert_index_type();
 
         let total_edge_count: usize = current_dep_graph.edges.iter()
                                                              .map(|v| v.len())
@@ -503,6 +501,7 @@ impl DepGraph {
 
         SerializedDepGraph {
             nodes,
+            fingerprints,
             edge_list_indices,
             edge_list_data,
         }
diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs
index 504b60e763e23..669a99019aa60 100644
--- a/src/librustc/dep_graph/prev.rs
+++ b/src/librustc/dep_graph/prev.rs
@@ -23,7 +23,7 @@ impl PreviousDepGraph {
     pub fn new(data: SerializedDepGraph) -> PreviousDepGraph {
         let index: FxHashMap<_, _> = data.nodes
             .iter_enumerated()
-            .map(|(idx, &(dep_node, _))| (dep_node, idx))
+            .map(|(idx, &dep_node)| (dep_node, idx))
             .collect();
         PreviousDepGraph { data, index }
     }
@@ -41,7 +41,7 @@ impl PreviousDepGraph {
 
     #[inline]
     pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode {
-        self.data.nodes[dep_node_index].0
+        self.data.nodes[dep_node_index]
     }
 
     #[inline]
@@ -58,14 +58,14 @@ impl PreviousDepGraph {
     pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
         self.index
             .get(dep_node)
-            .map(|&node_index| self.data.nodes[node_index].1)
+            .map(|&node_index| self.data.fingerprints[node_index])
     }
 
     #[inline]
     pub fn fingerprint_by_index(&self,
                                 dep_node_index: SerializedDepNodeIndex)
                                 -> Fingerprint {
-        self.data.nodes[dep_node_index].1
+        self.data.fingerprints[dep_node_index]
     }
 
     pub fn node_count(&self) -> usize {
diff --git a/src/librustc/dep_graph/serialized.rs b/src/librustc/dep_graph/serialized.rs
index c96040ab9b6e3..60fc813a25d51 100644
--- a/src/librustc/dep_graph/serialized.rs
+++ b/src/librustc/dep_graph/serialized.rs
@@ -20,7 +20,10 @@ newtype_index!(SerializedDepNodeIndex);
 #[derive(Debug, RustcEncodable, RustcDecodable)]
 pub struct SerializedDepGraph {
     /// The set of all DepNodes in the graph
-    pub nodes: IndexVec<SerializedDepNodeIndex, (DepNode, Fingerprint)>,
+    pub nodes: IndexVec<SerializedDepNodeIndex, DepNode>,
+    /// The set of all Fingerprints in the graph. Each Fingerprint corresponds to
+    /// the DepNode at the same index in the nodes vector.
+    pub fingerprints: IndexVec<SerializedDepNodeIndex, Fingerprint>,
     /// For each DepNode, stores the list of edges originating from that
     /// DepNode. Encoded as a [start, end) pair indexing into edge_list_data,
     /// which holds the actual DepNodeIndices of the target nodes.
@@ -35,6 +38,7 @@ impl SerializedDepGraph {
     pub fn new() -> SerializedDepGraph {
         SerializedDepGraph {
             nodes: IndexVec::new(),
+            fingerprints: IndexVec::new(),
             edge_list_indices: IndexVec::new(),
             edge_list_data: Vec::new(),
         }
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index b3a904f2f5fec..c74ae2343b866 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -887,65 +887,6 @@ foo(3_i8);
 // therefore the type-checker complains with this error code.
 ```
 
-Here is a more subtle instance of the same problem, that can
-arise with for-loops in Rust:
-
-```compile_fail
-let vs: Vec<i32> = vec![1, 2, 3, 4];
-for v in &vs {
-    match v {
-        1 => {},
-        _ => {},
-    }
-}
-```
-
-The above fails because of an analogous type mismatch,
-though may be harder to see. Again, here are some
-explanatory comments for the same example:
-
-```compile_fail
-{
-    let vs = vec![1, 2, 3, 4];
-
-    // `for`-loops use a protocol based on the `Iterator`
-    // trait. Each item yielded in a `for` loop has the
-    // type `Iterator::Item` -- that is, `Item` is the
-    // associated type of the concrete iterator impl.
-    for v in &vs {
-//      ~    ~~~
-//      |     |
-//      |    We borrow `vs`, iterating over a sequence of
-//      |    *references* of type `&Elem` (where `Elem` is
-//      |    vector's element type). Thus, the associated
-//      |    type `Item` must be a reference `&`-type ...
-//      |
-//  ... and `v` has the type `Iterator::Item`, as dictated by
-//  the `for`-loop protocol ...
-
-        match v {
-            1 => {}
-//          ~
-//          |
-// ... but *here*, `v` is forced to have some integral type;
-// only types like `u8`,`i8`,`u16`,`i16`, et cetera can
-// match the pattern `1` ...
-
-            _ => {}
-        }
-
-// ... therefore, the compiler complains, because it sees
-// an attempt to solve the equations
-// `some integral-type` = type-of-`v`
-//                      = `Iterator::Item`
-//                      = `&Elem` (i.e. `some reference type`)
-//
-// which cannot possibly all be true.
-
-    }
-}
-```
-
 To avoid those issues, you have to make the types match correctly.
 So we can fix the previous examples like this:
 
@@ -1764,12 +1705,12 @@ The `main` function was incorrectly declared.
 Erroneous code example:
 
 ```compile_fail,E0580
-fn main() -> i32 { // error: main function has wrong type
-    0
+fn main(x: i32) { // error: main function has wrong type
+    println!("{}", x);
 }
 ```
 
-The `main` function prototype should never take arguments or return type.
+The `main` function prototype should never take arguments.
 Example:
 
 ```
@@ -1789,8 +1730,6 @@ allowed as function return types.
 Erroneous code example:
 
 ```compile_fail,E0562
-#![feature(conservative_impl_trait)]
-
 fn main() {
     let count_to_ten: impl Iterator<Item=usize> = 0..10;
     // error: `impl Trait` not allowed outside of function and inherent method
@@ -1804,8 +1743,6 @@ fn main() {
 Make sure `impl Trait` only appears in return-type position.
 
 ```
-#![feature(conservative_impl_trait)]
-
 fn count_to_n(n: usize) -> impl Iterator<Item=usize> {
     0..n
 }
@@ -2074,6 +2011,54 @@ a (non-transparent) struct containing a single float, while `Grams` is a
 transparent wrapper around a float. This can make a difference for the ABI.
 "##,
 
+E0909: r##"
+The `impl Trait` return type captures lifetime parameters that do not
+appear within the `impl Trait` itself.
+
+Erroneous code example:
+
+```compile-fail,E0909
+use std::cell::Cell;
+
+trait Trait<'a> { }
+
+impl<'a, 'b> Trait<'b> for Cell<&'a u32> { }
+
+fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y>
+where 'x: 'y
+{
+    x
+}
+```
+
+Here, the function `foo` returns a value of type `Cell<&'x u32>`,
+which references the lifetime `'x`. However, the return type is
+declared as `impl Trait<'y>` -- this indicates that `foo` returns
+"some type that implements `Trait<'y>`", but it also indicates that
+the return type **only captures data referencing the lifetime `'y`**.
+In this case, though, we are referencing data with lifetime `'x`, so
+this function is in error.
+
+To fix this, you must reference the lifetime `'x` from the return
+type. For example, changing the return type to `impl Trait<'y> + 'x`
+would work:
+
+```
+use std::cell::Cell;
+
+trait Trait<'a> { }
+
+impl<'a,'b> Trait<'b> for Cell<&'a u32> { }
+
+fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> + 'x
+where 'x: 'y
+{
+    x
+}
+```
+"##,
+
+
 }
 
 
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index d7194e9c2cabb..9b2647ad4db2b 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -25,6 +25,8 @@ enum Target {
     Struct,
     Union,
     Enum,
+    Const,
+    ForeignMod,
     Other,
 }
 
@@ -35,6 +37,8 @@ impl Target {
             hir::ItemStruct(..) => Target::Struct,
             hir::ItemUnion(..) => Target::Union,
             hir::ItemEnum(..) => Target::Enum,
+            hir::ItemConst(..) => Target::Const,
+            hir::ItemForeignMod(..) => Target::ForeignMod,
             _ => Target::Other,
         }
     }
@@ -55,14 +59,42 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
                 .emit();
         }
 
+        let mut has_wasm_import_module = false;
         for attr in &item.attrs {
-            if let Some(name) = attr.name() {
-                if name == "inline" {
-                    self.check_inline(attr, item, target)
+            if attr.check_name("inline") {
+                self.check_inline(attr, item, target)
+            } else if attr.check_name("wasm_import_module") {
+                has_wasm_import_module = true;
+                if attr.value_str().is_none() {
+                    self.tcx.sess.span_err(attr.span, "\
+                        must be of the form #[wasm_import_module = \"...\"]");
+                }
+                if target != Target::ForeignMod {
+                    self.tcx.sess.span_err(attr.span, "\
+                        must only be attached to foreign modules");
+                }
+            } else if attr.check_name("wasm_custom_section") {
+                if target != Target::Const {
+                    self.tcx.sess.span_err(attr.span, "only allowed on consts");
+                }
+
+                if attr.value_str().is_none() {
+                    self.tcx.sess.span_err(attr.span, "must be of the form \
+                        #[wasm_custom_section = \"foo\"]");
                 }
             }
         }
 
+        if target == Target::ForeignMod &&
+            !has_wasm_import_module &&
+            self.tcx.sess.target.target.arch == "wasm32" &&
+            false // FIXME: eventually enable this warning when stable
+        {
+            self.tcx.sess.span_warn(item.span, "\
+                must have a #[wasm_import_module = \"...\"] attribute, this \
+                will become a hard error before too long");
+        }
+
         self.check_repr(item, target);
     }
 
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index b804cf7bf5a34..9f51eb8c35a82 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -420,7 +420,10 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime
         LifetimeName::Name(name) => {
             visitor.visit_name(lifetime.span, name);
         }
-        LifetimeName::Static | LifetimeName::Implicit | LifetimeName::Underscore => {}
+        LifetimeName::Fresh(_) |
+        LifetimeName::Static |
+        LifetimeName::Implicit |
+        LifetimeName::Underscore => {}
     }
 }
 
@@ -444,10 +447,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
     visitor.visit_vis(&item.vis);
     visitor.visit_name(item.span, item.name);
     match item.node {
-        ItemExternCrate(opt_name) => {
+        ItemExternCrate(orig_name) => {
             visitor.visit_id(item.id);
-            if let Some(name) = opt_name {
-                visitor.visit_name(item.span, name);
+            if let Some(orig_name) = orig_name {
+                visitor.visit_name(item.span, orig_name);
             }
         }
         ItemUse(ref path, _) => {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 49611689fc4af..536d682566a72 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -43,8 +43,8 @@
 use dep_graph::DepGraph;
 use hir;
 use hir::HirVec;
-use hir::map::{Definitions, DefKey, DefPathData};
-use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX, DefIndexAddressSpace};
+use hir::map::{DefKey, DefPathData, Definitions};
+use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
 use hir::def::{Def, PathResolution};
 use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
 use middle::cstore::CrateStore;
@@ -63,10 +63,10 @@ use syntax::errors;
 use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::print::pprust;
 use syntax::ptr::P;
-use syntax::codemap::{self, respan, Spanned, CompilerDesugaringKind};
+use syntax::codemap::{self, respan, CompilerDesugaringKind, Spanned};
 use syntax::std_inject;
-use syntax::symbol::{Symbol, keywords};
-use syntax::tokenstream::{TokenStream, TokenTree, Delimited};
+use syntax::symbol::{keywords, Symbol};
+use syntax::tokenstream::{Delimited, TokenStream, TokenTree};
 use syntax::parse::token::Token;
 use syntax::util::small_vector::SmallVector;
 use syntax::visit::{self, Visitor};
@@ -80,13 +80,13 @@ pub struct LoweringContext<'a> {
     // Use to assign ids to hir nodes that do not directly correspond to an ast node
     sess: &'a Session,
 
-    cstore: &'a dyn CrateStore,
+    cstore: &'a CrateStore,
 
     // As we walk the AST we must keep track of the current 'parent' def id (in
     // the form of a DefIndex) so that if we create a new node which introduces
     // a definition, then we can properly create the def id.
     parent_def: Option<DefIndex>,
-    resolver: &'a mut dyn Resolver,
+    resolver: &'a mut Resolver,
     name_map: FxHashMap<Ident, Name>,
 
     /// The items being lowered are collected here.
@@ -107,6 +107,12 @@ pub struct LoweringContext<'a> {
     is_in_loop_condition: bool,
     is_in_trait_impl: bool,
 
+    /// What to do when we encounter either an "anonymous lifetime
+    /// reference". The term "anonymous" is meant to encompass both
+    /// `'_` lifetimes as well as fully elided cases where nothing is
+    /// written at all (e.g., `&T` or `std::cell::Ref<T>`).
+    anonymous_lifetime_mode: AnonymousLifetimeMode,
+
     // This is a list of in-band type definitions being generated by
     // Argument-position `impl Trait`.
     // When traversing a signature such as `fn foo(x: impl Trait)`,
@@ -121,13 +127,15 @@ pub struct LoweringContext<'a> {
     // (i.e. it doesn't appear in the in_scope_lifetimes list), it is added
     // to this list. The results of this list are then added to the list of
     // lifetime definitions in the corresponding impl or function generics.
-    lifetimes_to_define: Vec<(Span, Name)>,
+    lifetimes_to_define: Vec<(Span, hir::LifetimeName)>,
+
     // Whether or not in-band lifetimes are being collected. This is used to
     // indicate whether or not we're in a place where new lifetimes will result
     // in in-band lifetime definitions, such a function or an impl header.
     // This will always be false unless the `in_band_lifetimes` feature is
     // enabled.
     is_collecting_in_band_lifetimes: bool,
+
     // Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
     // When `is_collectin_in_band_lifetimes` is true, each lifetime is checked
     // against this list to see if it is already in-scope, or if a definition
@@ -154,8 +162,13 @@ pub trait Resolver {
 
     /// Given suffix ["b","c","d"], creates a HIR path for `[::crate_root]::b::c::d` and resolves
     /// it based on `is_value`.
-    fn resolve_str_path(&mut self, span: Span, crate_root: Option<&str>,
-                components: &[&str], is_value: bool) -> hir::Path;
+    fn resolve_str_path(
+        &mut self,
+        span: Span,
+        crate_root: Option<&str>,
+        components: &[&str],
+        is_value: bool,
+    ) -> hir::Path;
 }
 
 #[derive(Clone, Copy, Debug)]
@@ -176,12 +189,13 @@ enum ImplTraitContext {
     Disallowed,
 }
 
-pub fn lower_crate(sess: &Session,
-                   cstore: &dyn CrateStore,
-                   dep_graph: &DepGraph,
-                   krate: &Crate,
-                   resolver: &mut dyn Resolver)
-                   -> hir::Crate {
+pub fn lower_crate(
+    sess: &Session,
+    cstore: &CrateStore,
+    dep_graph: &DepGraph,
+    krate: &Crate,
+    resolver: &mut Resolver,
+) -> hir::Crate {
     // We're constructing the HIR here; we don't care what we will
     // read, since we haven't even constructed the *input* to
     // incr. comp. yet.
@@ -204,6 +218,7 @@ pub fn lower_crate(sess: &Session,
         catch_scopes: Vec::new(),
         loop_scopes: Vec::new(),
         is_in_loop_condition: false,
+        anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
         type_def_lifetime_params: DefIdMap(),
         current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)],
         item_local_id_counters: NodeMap(),
@@ -222,7 +237,7 @@ enum ParamMode {
     /// Any path in a type context.
     Explicit,
     /// The `module::Type` in `module::Type::method` in an expression.
-    Optional
+    Optional,
 }
 
 struct LoweredNodeId {
@@ -236,6 +251,51 @@ enum ParenthesizedGenericArgs {
     Err,
 }
 
+/// What to do when we encounter an **anonymous** lifetime
+/// reference. Anonymous lifetime references come in two flavors.  You
+/// have implicit, or fully elided, references to lifetimes, like the
+/// one in `&T` or `Ref<T>`, and you have `'_` lifetimes, like `&'_ T`
+/// or `Ref<'_, T>`.  These often behave the same, but not always:
+///
+/// - certain usages of implicit references are deprecated, like
+///   `Ref<T>`, and we sometimes just give hard errors in those cases
+///   as well.
+/// - for object bounds there is a difference: `Box<dyn Foo>` is not
+///   the same as `Box<dyn Foo + '_>`.
+///
+/// We describe the effects of the various modes in terms of three cases:
+///
+/// - **Modern** -- includes all uses of `'_`, but also the lifetime arg
+///   of a `&` (e.g., the missing lifetime in something like `&T`)
+/// - **Dyn Bound** -- if you have something like `Box<dyn Foo>`,
+///   there is an elided lifetime bound (`Box<dyn Foo + 'X>`). These
+///   elided bounds follow special rules. Note that this only covers
+///   cases where *nothing* is written; the `'_` in `Box<dyn Foo +
+///   '_>` is a case of "modern" elision.
+/// - **Deprecated** -- this coverse cases like `Ref<T>`, where the lifetime
+///   parameter to ref is completely elided. `Ref<'_, T>` would be the modern,
+///   non-deprecated equivalent.
+///
+/// Currently, the handling of lifetime elision is somewhat spread out
+/// between HIR lowering and -- as described below -- the
+/// `resolve_lifetime` module. Often we "fallthrough" to that code by generating
+/// an "elided" or "underscore" lifetime name. In the future, we probably want to move
+/// everything into HIR lowering.
+#[derive(Copy, Clone)]
+enum AnonymousLifetimeMode {
+    /// For **Modern** cases, create a new anonymous region parameter
+    /// and reference that.
+    ///
+    /// For **Dyn Bound** cases, pass responsibility to
+    /// `resolve_lifetime` code.
+    ///
+    /// For **Deprecated** cases, report an error.
+    CreateParameter,
+
+    /// Pass responsibility to `resolve_lifetime` code for all cases.
+    PassThrough,
+}
+
 impl<'a> LoweringContext<'a> {
     fn lower_crate(mut self, c: &Crate) -> hir::Crate {
         /// Full-crate AST visitor that inserts into a fresh
@@ -252,13 +312,15 @@ impl<'a> LoweringContext<'a> {
                 self.lctx.allocate_hir_id_counter(item.id, item);
 
                 match item.node {
-                    ItemKind::Struct(_, ref generics) |
-                    ItemKind::Union(_, ref generics) |
-                    ItemKind::Enum(_, ref generics) |
-                    ItemKind::Ty(_, ref generics) |
-                    ItemKind::Trait(_, _, ref generics, ..) => {
+                    ItemKind::Struct(_, ref generics)
+                    | ItemKind::Union(_, ref generics)
+                    | ItemKind::Enum(_, ref generics)
+                    | ItemKind::Ty(_, ref generics)
+                    | ItemKind::Trait(_, _, ref generics, ..) => {
                         let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
-                        let count = generics.params.iter()
+                        let count = generics
+                            .params
+                            .iter()
                             .filter(|param| param.is_lifetime_param())
                             .count();
                         self.lctx.type_def_lifetime_params.insert(def_id, count);
@@ -285,7 +347,8 @@ impl<'a> LoweringContext<'a> {
 
         impl<'lcx, 'interner> ItemLowerer<'lcx, 'interner> {
             fn with_trait_impl_ref<F>(&mut self, trait_impl_ref: &Option<TraitRef>, f: F)
-                where F: FnOnce(&mut Self)
+            where
+                F: FnOnce(&mut Self),
             {
                 let old = self.lctx.is_in_trait_impl;
                 self.lctx.is_in_trait_impl = if let &None = trait_impl_ref {
@@ -311,22 +374,24 @@ impl<'a> LoweringContext<'a> {
 
                 if item_lowered {
                     let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node {
-                        hir::Item_::ItemImpl(_,_,_,ref generics,..) |
-                        hir::Item_::ItemTrait(_,_,ref generics,..) =>
-                            generics.lifetimes().cloned().collect::<Vec<_>>(),
+                        hir::Item_::ItemImpl(_, _, _, ref generics, ..)
+                        | hir::Item_::ItemTrait(_, _, ref generics, ..) => {
+                            generics.lifetimes().cloned().collect::<Vec<_>>()
+                        }
                         _ => Vec::new(),
                     };
 
-                    self.lctx.with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
-                        let this = &mut ItemLowerer { lctx: this };
-                        if let ItemKind::Impl(_,_,_,_,ref opt_trait_ref,_,_) = item.node {
-                            this.with_trait_impl_ref(opt_trait_ref, |this| {
-                                visit::walk_item(this, item)
-                            });
-                        } else {
-                            visit::walk_item(this, item);
-                        }
-                    });
+                    self.lctx
+                        .with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
+                            let this = &mut ItemLowerer { lctx: this };
+                            if let ItemKind::Impl(_, _, _, _, ref opt_trait_ref, _, _) = item.node {
+                                this.with_trait_impl_ref(opt_trait_ref, |this| {
+                                    visit::walk_item(this, item)
+                                });
+                            } else {
+                                visit::walk_item(this, item);
+                            }
+                        });
                 }
             }
 
@@ -379,27 +444,26 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn allocate_hir_id_counter<T: Debug>(&mut self,
-                                         owner: NodeId,
-                                         debug: &T) {
+    fn allocate_hir_id_counter<T: Debug>(&mut self, owner: NodeId, debug: &T) {
         if self.item_local_id_counters.insert(owner, 0).is_some() {
-            bug!("Tried to allocate item_local_id_counter for {:?} twice", debug);
+            bug!(
+                "Tried to allocate item_local_id_counter for {:?} twice",
+                debug
+            );
         }
         // Always allocate the first HirId for the owner itself
         self.lower_node_id_with_owner(owner, owner);
     }
 
-    fn lower_node_id_generic<F>(&mut self,
-                                ast_node_id: NodeId,
-                                alloc_hir_id: F)
-                                -> LoweredNodeId
-        where F: FnOnce(&mut Self) -> hir::HirId
+    fn lower_node_id_generic<F>(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> LoweredNodeId
+    where
+        F: FnOnce(&mut Self) -> hir::HirId,
     {
         if ast_node_id == DUMMY_NODE_ID {
             return LoweredNodeId {
                 node_id: DUMMY_NODE_ID,
                 hir_id: hir::DUMMY_HIR_ID,
-            }
+            };
         }
 
         let min_size = ast_node_id.as_usize() + 1;
@@ -427,11 +491,12 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn with_hir_id_owner<F>(&mut self, owner: NodeId, f: F)
-        where F: FnOnce(&mut Self)
+    where
+        F: FnOnce(&mut Self),
     {
         let counter = self.item_local_id_counters
-                          .insert(owner, HIR_ID_COUNTER_LOCKED)
-                          .unwrap();
+            .insert(owner, HIR_ID_COUNTER_LOCKED)
+            .unwrap();
         let def_index = self.resolver.definitions().opt_def_index(owner).unwrap();
         self.current_hir_id_owner.push((def_index, counter));
         f(self);
@@ -440,7 +505,9 @@ impl<'a> LoweringContext<'a> {
         debug_assert!(def_index == new_def_index);
         debug_assert!(new_counter >= counter);
 
-        let prev = self.item_local_id_counters.insert(owner, new_counter).unwrap();
+        let prev = self.item_local_id_counters
+            .insert(owner, new_counter)
+            .unwrap();
         debug_assert!(prev == HIR_ID_COUNTER_LOCKED);
     }
 
@@ -452,9 +519,8 @@ impl<'a> LoweringContext<'a> {
     /// properly. Calling the method twice with the same NodeId is fine though.
     fn lower_node_id(&mut self, ast_node_id: NodeId) -> LoweredNodeId {
         self.lower_node_id_generic(ast_node_id, |this| {
-            let &mut (def_index, ref mut local_id_counter) = this.current_hir_id_owner
-                                                                 .last_mut()
-                                                                 .unwrap();
+            let &mut (def_index, ref mut local_id_counter) =
+                this.current_hir_id_owner.last_mut().unwrap();
             let local_id = *local_id_counter;
             *local_id_counter += 1;
             hir::HirId {
@@ -464,14 +530,9 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn lower_node_id_with_owner(&mut self,
-                                ast_node_id: NodeId,
-                                owner: NodeId)
-                                -> LoweredNodeId {
+    fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> LoweredNodeId {
         self.lower_node_id_generic(ast_node_id, |this| {
-            let local_id_counter = this.item_local_id_counters
-                                       .get_mut(&owner)
-                                       .unwrap();
+            let local_id_counter = this.item_local_id_counters.get_mut(&owner).unwrap();
             let local_id = *local_id_counter;
 
             // We want to be sure not to modify the counter in the map while it
@@ -489,8 +550,7 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>)
-                   -> hir::BodyId {
+    fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>) -> hir::BodyId {
         let body = hir::Body {
             arguments: decl.map_or(hir_vec![], |decl| {
                 decl.inputs.iter().map(|x| self.lower_arg(x)).collect()
@@ -524,8 +584,7 @@ impl<'a> LoweringContext<'a> {
         Symbol::gensym(s)
     }
 
-    fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span
-    {
+    fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span {
         let mark = Mark::fresh(Mark::root());
         mark.set_expn_info(codemap::ExpnInfo {
             call_site: span,
@@ -539,73 +598,139 @@ impl<'a> LoweringContext<'a> {
         span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
     }
 
-    // Creates a new hir::GenericParam for every new lifetime and type parameter
-    // encountered while evaluating `f`. Definitions are created with the parent
-    // provided. If no `parent_id` is provided, no definitions will be returned.
+    /// Creates a new hir::GenericParam for every new lifetime and
+    /// type parameter encountered while evaluating `f`. Definitions
+    /// are created with the parent provided. If no `parent_id` is
+    /// provided, no definitions will be returned.
+    ///
+    /// Presuming that in-band lifetimes are enabled, then
+    /// `self.anonymous_lifetime_mode` will be updated to match the
+    /// argument while `f` is running (and restored afterwards).
     fn collect_in_band_defs<T, F>(
         &mut self,
-        parent_id: Option<DefId>,
-        f: F
-    ) -> (Vec<hir::GenericParam>, T) where F: FnOnce(&mut LoweringContext) -> T
+        parent_id: DefId,
+        anonymous_lifetime_mode: AnonymousLifetimeMode,
+        f: F,
+    ) -> (Vec<hir::GenericParam>, T)
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         assert!(!self.is_collecting_in_band_lifetimes);
         assert!(self.lifetimes_to_define.is_empty());
+        let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
+
         self.is_collecting_in_band_lifetimes = self.sess.features_untracked().in_band_lifetimes;
+        if self.is_collecting_in_band_lifetimes {
+            self.anonymous_lifetime_mode = anonymous_lifetime_mode;
+        }
 
         assert!(self.in_band_ty_params.is_empty());
-
         let res = f(self);
 
         self.is_collecting_in_band_lifetimes = false;
+        self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
 
         let in_band_ty_params = self.in_band_ty_params.split_off(0);
         let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
 
-        let mut params = match parent_id {
-            Some(parent_id) => lifetimes_to_define.into_iter().map(|(span, name)| {
-                    let def_node_id = self.next_id().node_id;
-
-                    // Add a definition for the in-band lifetime def
-                    self.resolver.definitions().create_def_with_parent(
-                        parent_id.index,
-                        def_node_id,
-                        DefPathData::LifetimeDef(name.as_str()),
-                        DefIndexAddressSpace::High,
-                        Mark::root(),
-                        span
-                    );
+        let params = lifetimes_to_define
+            .into_iter()
+            .map(|(span, hir_name)| {
+                let def_node_id = self.next_id().node_id;
+
+                // Get the name we'll use to make the def-path. Note
+                // that collisions are ok here and this shouldn't
+                // really show up for end-user.
+                let str_name = match hir_name {
+                    hir::LifetimeName::Name(n) => n.as_str(),
+                    hir::LifetimeName::Fresh(_) => keywords::UnderscoreLifetime.name().as_str(),
+                    hir::LifetimeName::Implicit
+                    | hir::LifetimeName::Underscore
+                    | hir::LifetimeName::Static => {
+                        span_bug!(span, "unexpected in-band lifetime name: {:?}", hir_name)
+                    }
+                };
 
-                    hir::GenericParam::Lifetime(hir::LifetimeDef {
-                        lifetime: hir::Lifetime {
-                            id: def_node_id,
-                            span,
-                            name: hir::LifetimeName::Name(name),
-                        },
-                        bounds: Vec::new().into(),
-                        pure_wrt_drop: false,
-                        in_band: true,
-                    })
-                }).collect(),
-            None => Vec::new(),
-        };
+                // Add a definition for the in-band lifetime def
+                self.resolver.definitions().create_def_with_parent(
+                    parent_id.index,
+                    def_node_id,
+                    DefPathData::LifetimeDef(str_name),
+                    DefIndexAddressSpace::High,
+                    Mark::root(),
+                    span,
+                );
 
-        params.extend(in_band_ty_params.into_iter().map(|tp| hir::GenericParam::Type(tp)));
+                hir::GenericParam::Lifetime(hir::LifetimeDef {
+                    lifetime: hir::Lifetime {
+                        id: def_node_id,
+                        span,
+                        name: hir_name,
+                    },
+                    bounds: Vec::new().into(),
+                    pure_wrt_drop: false,
+                    in_band: true,
+                })
+            })
+            .chain(
+                in_band_ty_params
+                    .into_iter()
+                    .map(|tp| hir::GenericParam::Type(tp)),
+            )
+            .collect();
 
         (params, res)
     }
 
+    /// When there is a reference to some lifetime `'a`, and in-band
+    /// lifetimes are enabled, then we want to push that lifetime into
+    /// the vector of names to define later. In that case, it will get
+    /// added to the appropriate generics.
+    fn maybe_collect_in_band_lifetime(&mut self, span: Span, name: Name) {
+        if !self.is_collecting_in_band_lifetimes {
+            return;
+        }
+
+        if self.in_scope_lifetimes.contains(&name) {
+            return;
+        }
+
+        let hir_name = hir::LifetimeName::Name(name);
+
+        if self.lifetimes_to_define
+            .iter()
+            .any(|(_, lt_name)| *lt_name == hir_name)
+        {
+            return;
+        }
+
+        self.lifetimes_to_define.push((span, hir_name));
+    }
+
+    /// When we have either an elided or `'_` lifetime in an impl
+    /// header, we convert it to
+    fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> hir::LifetimeName {
+        assert!(self.is_collecting_in_band_lifetimes);
+        let index = self.lifetimes_to_define.len();
+        let hir_name = hir::LifetimeName::Fresh(index);
+        self.lifetimes_to_define.push((span, hir_name));
+        hir_name
+    }
+
     // Evaluates `f` with the lifetimes in `lt_defs` in-scope.
     // This is used to track which lifetimes have already been defined, and
     // which are new in-band lifetimes that need to have a definition created
     // for them.
-    fn with_in_scope_lifetime_defs<T, F>(
+    fn with_in_scope_lifetime_defs<'l, T, F>(
         &mut self,
-        lt_defs: &[LifetimeDef],
-        f: F
-    ) -> T where F: FnOnce(&mut LoweringContext) -> T
+        lt_defs: impl Iterator<Item = &'l LifetimeDef>,
+        f: F,
+    ) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
-        let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.ident.name);
+        let lt_def_names = lt_defs.map(|lt_def| lt_def.lifetime.ident.name);
         self.in_scope_lifetimes.extend(lt_def_names);
 
         let res = f(self);
@@ -619,11 +744,9 @@ impl<'a> LoweringContext<'a> {
     // This should only be used with generics that have already had their
     // in-band lifetimes added. In practice, this means that this function is
     // only used when lowering a child item of a trait or impl.
-    fn with_parent_impl_lifetime_defs<T, F>(
-        &mut self,
-        lt_defs: &[hir::LifetimeDef],
-        f: F
-    ) -> T where F: FnOnce(&mut LoweringContext) -> T
+    fn with_parent_impl_lifetime_defs<T, F>(&mut self, lt_defs: &[hir::LifetimeDef], f: F) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
         let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.name.name());
@@ -635,47 +758,57 @@ impl<'a> LoweringContext<'a> {
         res
     }
 
-    // Appends in-band lifetime defs and argument-position `impl Trait` defs
-    // to the existing set of generics.
+    /// Appends in-band lifetime defs and argument-position `impl
+    /// Trait` defs to the existing set of generics.
+    ///
+    /// Presuming that in-band lifetimes are enabled, then
+    /// `self.anonymous_lifetime_mode` will be updated to match the
+    /// argument while `f` is running (and restored afterwards).
     fn add_in_band_defs<F, T>(
         &mut self,
         generics: &Generics,
-        parent_id: Option<DefId>,
-        f: F
+        parent_id: DefId,
+        anonymous_lifetime_mode: AnonymousLifetimeMode,
+        f: F,
     ) -> (hir::Generics, T)
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
-        let (in_band_defs, (mut lowered_generics, res)) =
-            self.with_in_scope_lifetime_defs(
-                &generics.params
-                    .iter()
-                    .filter_map(|p| match *p {
-                        GenericParam::Lifetime(ref ld) => Some(ld.clone()),
-                        _ => None,
-                    })
-                    .collect::<Vec<_>>(),
-                |this| {
-                    this.collect_in_band_defs(parent_id, |this| {
-                        (this.lower_generics(generics), f(this))
-                    })
-                }
-            );
+        let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
+            generics.params.iter().filter_map(|p| match p {
+                GenericParam::Lifetime(ld) => Some(ld),
+                _ => None,
+            }),
+            |this| {
+                this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| {
+                    (this.lower_generics(generics), f(this))
+                })
+            },
+        );
 
-        lowered_generics.params =
-            lowered_generics.params.iter().cloned().chain(in_band_defs).collect();
+        lowered_generics.params = lowered_generics
+            .params
+            .iter()
+            .cloned()
+            .chain(in_band_defs)
+            .collect();
 
         (lowered_generics, res)
     }
 
     fn with_catch_scope<T, F>(&mut self, catch_id: NodeId, f: F) -> T
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let len = self.catch_scopes.len();
         self.catch_scopes.push(catch_id);
 
         let result = f(self);
-        assert_eq!(len + 1, self.catch_scopes.len(),
-            "catch scopes should be added and removed in stack order");
+        assert_eq!(
+            len + 1,
+            self.catch_scopes.len(),
+            "catch scopes should be added and removed in stack order"
+        );
 
         self.catch_scopes.pop().unwrap();
 
@@ -683,17 +816,19 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn lower_body<F>(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId
-        where F: FnOnce(&mut LoweringContext) -> hir::Expr
+    where
+        F: FnOnce(&mut LoweringContext) -> hir::Expr,
     {
         let prev = mem::replace(&mut self.is_generator, false);
         let result = f(self);
         let r = self.record_body(result, decl);
         self.is_generator = prev;
-        return r
+        return r;
     }
 
     fn with_loop_scope<T, F>(&mut self, loop_id: NodeId, f: F) -> T
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         // We're no longer in the base loop's condition; we're in another loop.
         let was_in_loop_condition = self.is_in_loop_condition;
@@ -703,8 +838,11 @@ impl<'a> LoweringContext<'a> {
         self.loop_scopes.push(loop_id);
 
         let result = f(self);
-        assert_eq!(len + 1, self.loop_scopes.len(),
-            "Loop scopes should be added and removed in stack order");
+        assert_eq!(
+            len + 1,
+            self.loop_scopes.len(),
+            "Loop scopes should be added and removed in stack order"
+        );
 
         self.loop_scopes.pop().unwrap();
 
@@ -714,7 +852,8 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn with_loop_condition_scope<T, F>(&mut self, f: F) -> T
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = true;
@@ -727,7 +866,8 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn with_new_scopes<T, F>(&mut self, f: F) -> T
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = false;
@@ -744,7 +884,8 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn with_parent_def<T, F>(&mut self, parent_id: NodeId, f: F) -> T
-        where F: FnOnce(&mut LoweringContext) -> T
+    where
+        F: FnOnce(&mut LoweringContext) -> T,
     {
         let old_def = self.parent_def;
         self.parent_def = {
@@ -771,16 +912,19 @@ impl<'a> LoweringContext<'a> {
         if ident.ctxt == SyntaxContext::empty() {
             return ident.name;
         }
-        *self.name_map.entry(ident).or_insert_with(|| Symbol::from_ident(ident))
+        *self.name_map
+            .entry(ident)
+            .or_insert_with(|| Symbol::from_ident(ident))
     }
 
     fn lower_label(&mut self, label: Option<Label>) -> Option<hir::Label> {
-        label.map(|label| hir::Label { name: label.ident.name, span: label.span })
+        label.map(|label| hir::Label {
+            name: label.ident.name,
+            span: label.span,
+        })
     }
 
-    fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>)
-        -> hir::Destination
-    {
+    fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
         match destination {
             Some((id, label)) => {
                 let target = if let Def::Label(loop_id) = self.expect_full_def(id) {
@@ -792,25 +936,31 @@ impl<'a> LoweringContext<'a> {
                     label: self.lower_label(Some(label)),
                     target_id: hir::ScopeTarget::Loop(target),
                 }
-            },
+            }
             None => {
                 let loop_id = self.loop_scopes
-                                  .last()
-                                  .map(|innermost_loop_id| *innermost_loop_id);
+                    .last()
+                    .map(|innermost_loop_id| *innermost_loop_id);
 
                 hir::Destination {
                     label: None,
                     target_id: hir::ScopeTarget::Loop(
-                        loop_id.map(|id| Ok(self.lower_node_id(id).node_id))
-                               .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
-                               .into())
+                        loop_id
+                            .map(|id| Ok(self.lower_node_id(id).node_id))
+                            .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
+                            .into(),
+                    ),
                 }
             }
         }
     }
 
-    fn lower_attrs(&mut self, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
-        attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into()
+    fn lower_attrs(&mut self, attrs: &[Attribute]) -> hir::HirVec<Attribute> {
+        attrs
+            .iter()
+            .map(|a| self.lower_attr(a))
+            .collect::<Vec<_>>()
+            .into()
     }
 
     fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
@@ -825,22 +975,22 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn lower_token_stream(&mut self, tokens: TokenStream) -> TokenStream {
-        tokens.into_trees()
+        tokens
+            .into_trees()
             .flat_map(|tree| self.lower_token_tree(tree).into_trees())
             .collect()
     }
 
     fn lower_token_tree(&mut self, tree: TokenTree) -> TokenStream {
         match tree {
-            TokenTree::Token(span, token) => {
-                self.lower_token(token, span)
-            }
-            TokenTree::Delimited(span, delimited) => {
-                TokenTree::Delimited(span, Delimited {
+            TokenTree::Token(span, token) => self.lower_token(token, span),
+            TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
+                span,
+                Delimited {
                     delim: delimited.delim,
                     tts: self.lower_token_stream(delimited.tts.into()).into(),
-                }).into()
-            }
+                },
+            ).into(),
         }
     }
 
@@ -879,30 +1029,28 @@ impl<'a> LoweringContext<'a> {
             TyKind::Slice(ref ty) => hir::TySlice(self.lower_ty(ty, itctx)),
             TyKind::Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt, itctx)),
             TyKind::Rptr(ref region, ref mt) => {
-                let span = t.span.with_hi(t.span.lo());
+                let span = t.span.shrink_to_lo();
                 let lifetime = match *region {
                     Some(ref lt) => self.lower_lifetime(lt),
-                    None => self.elided_lifetime(span)
+                    None => self.elided_ref_lifetime(span),
                 };
                 hir::TyRptr(lifetime, self.lower_mt(mt, itctx))
             }
-            TyKind::BareFn(ref f) => {
-                self.with_in_scope_lifetime_defs(
-                    &f.generic_params
-                        .iter()
-                        .filter_map(|p| match *p {
-                            GenericParam::Lifetime(ref ld) => Some(ld.clone()),
-                            _ => None,
-                        })
-                        .collect::<Vec<_>>(),
-                    |this| hir::TyBareFn(P(hir::BareFnTy {
+            TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(
+                f.generic_params.iter().filter_map(|p| match p {
+                    GenericParam::Lifetime(ld) => Some(ld),
+                    _ => None,
+                }),
+                |this| {
+                    hir::TyBareFn(P(hir::BareFnTy {
                         generic_params: this.lower_generic_params(&f.generic_params, &NodeMap()),
                         unsafety: this.lower_unsafety(f.unsafety),
                         abi: f.abi,
                         decl: this.lower_fn_decl(&f.decl, None, false),
                         arg_names: this.lower_fn_args_to_names(&f.decl),
-                    })))
-            }
+                    }))
+                },
+            ),
             TyKind::Never => hir::TyNever,
             TyKind::Tup(ref tys) => {
                 hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty, itctx)).collect())
@@ -919,15 +1067,14 @@ impl<'a> LoweringContext<'a> {
                 }
                 return ty;
             }
-            TyKind::ImplicitSelf => {
-                hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
+            TyKind::ImplicitSelf => hir::TyPath(hir::QPath::Resolved(
+                None,
+                P(hir::Path {
                     def: self.expect_full_def(t.id),
-                    segments: hir_vec![
-                        hir::PathSegment::from_name(keywords::SelfType.name())
-                    ],
+                    segments: hir_vec![hir::PathSegment::from_name(keywords::SelfType.name())],
                     span: t.span,
-                })))
-            }
+                }),
+            )),
             TyKind::Array(ref ty, ref length) => {
                 let length = self.lower_body(None, |this| this.lower_expr(length));
                 hir::TyArray(self.lower_ty(ty, itctx), length)
@@ -938,8 +1085,9 @@ impl<'a> LoweringContext<'a> {
             }
             TyKind::TraitObject(ref bounds, kind) => {
                 let mut lifetime_bound = None;
-                let bounds = bounds.iter().filter_map(|bound| {
-                    match *bound {
+                let bounds = bounds
+                    .iter()
+                    .filter_map(|bound| match *bound {
                         TraitTyParamBound(ref ty, TraitBoundModifier::None) => {
                             Some(self.lower_poly_trait_ref(ty, itctx))
                         }
@@ -950,52 +1098,40 @@ impl<'a> LoweringContext<'a> {
                             }
                             None
                         }
-                    }
-                }).collect();
-                let lifetime_bound = lifetime_bound.unwrap_or_else(|| {
-                    self.elided_lifetime(t.span)
-                });
+                    })
+                    .collect();
+                let lifetime_bound =
+                    lifetime_bound.unwrap_or_else(|| self.elided_dyn_bound(t.span));
                 if kind != TraitObjectSyntax::Dyn {
                     self.maybe_lint_bare_trait(t.span, t.id, false);
                 }
                 hir::TyTraitObject(bounds, lifetime_bound)
             }
             TyKind::ImplTrait(ref bounds) => {
-                use syntax::feature_gate::{emit_feature_err, GateIssue};
                 let span = t.span;
                 match itctx {
                     ImplTraitContext::Existential => {
-                        let has_feature = self.sess.features_untracked().conservative_impl_trait;
-                        if !t.span.allows_unstable() && !has_feature {
-                            emit_feature_err(&self.sess.parse_sess, "conservative_impl_trait",
-                                             t.span, GateIssue::Language,
-                                             "`impl Trait` in return position is experimental");
-                        }
                         let def_index = self.resolver.definitions().opt_def_index(t.id).unwrap();
                         let hir_bounds = self.lower_bounds(bounds, itctx);
                         let (lifetimes, lifetime_defs) =
                             self.lifetimes_from_impl_trait_bounds(def_index, &hir_bounds);
 
-                        hir::TyImplTraitExistential(hir::ExistTy {
-                            generics: hir::Generics {
-                                params: lifetime_defs,
-                                where_clause: hir::WhereClause {
-                                    id: self.next_id().node_id,
-                                    predicates: Vec::new().into(),
+                        hir::TyImplTraitExistential(
+                            hir::ExistTy {
+                                generics: hir::Generics {
+                                    params: lifetime_defs,
+                                    where_clause: hir::WhereClause {
+                                        id: self.next_id().node_id,
+                                        predicates: Vec::new().into(),
+                                    },
+                                    span,
                                 },
-                                span,
+                                bounds: hir_bounds,
                             },
-                            bounds: hir_bounds,
-                        }, lifetimes)
-                    },
+                            lifetimes,
+                        )
+                    }
                     ImplTraitContext::Universal(def_id) => {
-                        let has_feature = self.sess.features_untracked().universal_impl_trait;
-                        if !t.span.allows_unstable() && !has_feature {
-                            emit_feature_err(&self.sess.parse_sess, "universal_impl_trait",
-                                             t.span, GateIssue::Language,
-                                             "`impl Trait` in argument position is experimental");
-                        }
-
                         let def_node_id = self.next_id().node_id;
 
                         // Add a definition for the in-band TyParam
@@ -1005,7 +1141,7 @@ impl<'a> LoweringContext<'a> {
                             DefPathData::ImplTrait,
                             DefIndexAddressSpace::High,
                             Mark::root(),
-                            span
+                            span,
                         );
 
                         let hir_bounds = self.lower_bounds(bounds, itctx);
@@ -1019,18 +1155,26 @@ impl<'a> LoweringContext<'a> {
                             span,
                             pure_wrt_drop: false,
                             synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
+                            attrs: P::new(),
                         });
 
-                        hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
-                            span,
-                            def: Def::TyParam(DefId::local(def_index)),
-                            segments: hir_vec![hir::PathSegment::from_name(name)],
-                        })))
-                    },
+                        hir::TyPath(hir::QPath::Resolved(
+                            None,
+                            P(hir::Path {
+                                span,
+                                def: Def::TyParam(DefId::local(def_index)),
+                                segments: hir_vec![hir::PathSegment::from_name(name)],
+                            }),
+                        ))
+                    }
                     ImplTraitContext::Disallowed => {
-                        span_err!(self.sess, t.span, E0562,
-                                  "`impl Trait` not allowed outside of function \
-                                  and inherent method return types");
+                        span_err!(
+                            self.sess,
+                            t.span,
+                            E0562,
+                            "`impl Trait` not allowed outside of function \
+                             and inherent method return types"
+                        );
                         hir::TyErr
                     }
                 }
@@ -1050,9 +1194,8 @@ impl<'a> LoweringContext<'a> {
     fn lifetimes_from_impl_trait_bounds(
         &mut self,
         parent_index: DefIndex,
-        bounds: &hir::TyParamBounds
+        bounds: &hir::TyParamBounds,
     ) -> (HirVec<hir::Lifetime>, HirVec<hir::GenericParam>) {
-
         // This visitor walks over impl trait bounds and creates defs for all lifetimes which
         // appear in the bounds, excluding lifetimes that are created within the bounds.
         // e.g. 'a, 'b, but not 'c in `impl for<'c> SomeTrait<'a, 'b, 'c>`
@@ -1067,8 +1210,9 @@ impl<'a> LoweringContext<'a> {
         }
 
         impl<'r, 'a: 'r, 'v> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a> {
-            fn nested_visit_map<'this>(&'this mut self)
-                -> hir::intravisit::NestedVisitorMap<'this, 'v> {
+            fn nested_visit_map<'this>(
+                &'this mut self,
+            ) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
                 hir::intravisit::NestedVisitorMap::None
             }
 
@@ -1096,9 +1240,11 @@ impl<'a> LoweringContext<'a> {
                 }
             }
 
-            fn visit_poly_trait_ref(&mut self,
-                                    polytr: &'v hir::PolyTraitRef,
-                                    _: hir::TraitBoundModifier) {
+            fn visit_poly_trait_ref(
+                &mut self,
+                polytr: &'v hir::PolyTraitRef,
+                _: hir::TraitBoundModifier,
+            ) {
                 let old_len = self.currently_bound_lifetimes.len();
 
                 // Record the introduction of 'a in `for<'a> ...`
@@ -1122,21 +1268,22 @@ impl<'a> LoweringContext<'a> {
 
             fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
                 let name = match lifetime.name {
-                    hir::LifetimeName::Implicit |
-                    hir::LifetimeName::Underscore =>
+                    hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
                         if self.collect_elided_lifetimes {
                             // Use `'_` for both implicit and underscore lifetimes in
                             // `abstract type Foo<'_>: SomeTrait<'_>;`
                             hir::LifetimeName::Underscore
                         } else {
-                            return
+                            return;
                         }
+                    }
+                    name @ hir::LifetimeName::Fresh(_) => name,
                     name @ hir::LifetimeName::Name(_) => name,
                     hir::LifetimeName::Static => return,
                 };
 
-                if !self.currently_bound_lifetimes.contains(&name) &&
-                   !self.already_defined_lifetimes.contains(&name)
+                if !self.currently_bound_lifetimes.contains(&name)
+                    && !self.already_defined_lifetimes.contains(&name)
                 {
                     self.already_defined_lifetimes.insert(name);
 
@@ -1153,19 +1300,20 @@ impl<'a> LoweringContext<'a> {
                         DefPathData::LifetimeDef(name.name().as_str()),
                         DefIndexAddressSpace::High,
                         Mark::root(),
-                        lifetime.span
+                        lifetime.span,
                     );
                     let def_lifetime = hir::Lifetime {
                         id: def_node_id,
                         span: lifetime.span,
                         name: name,
                     };
-                    self.output_lifetime_params.push(hir::GenericParam::Lifetime(hir::LifetimeDef {
-                        lifetime: def_lifetime,
-                        bounds: Vec::new().into(),
-                        pure_wrt_drop: false,
-                        in_band: false,
-                    }));
+                    self.output_lifetime_params
+                        .push(hir::GenericParam::Lifetime(hir::LifetimeDef {
+                            lifetime: def_lifetime,
+                            bounds: Vec::new().into(),
+                            pure_wrt_drop: false,
+                            in_band: false,
+                        }));
                 }
             }
         }
@@ -1186,14 +1334,17 @@ impl<'a> LoweringContext<'a> {
 
         (
             lifetime_collector.output_lifetimes.into(),
-            lifetime_collector.output_lifetime_params.into()
+            lifetime_collector.output_lifetime_params.into(),
         )
     }
 
     fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
         hir::ForeignMod {
             abi: fm.abi,
-            items: fm.items.iter().map(|x| self.lower_foreign_item(x)).collect(),
+            items: fm.items
+                .iter()
+                .map(|x| self.lower_foreign_item(x))
+                .collect(),
         }
     }
 
@@ -1210,94 +1361,116 @@ impl<'a> LoweringContext<'a> {
                 name: v.node.name.name,
                 attrs: self.lower_attrs(&v.node.attrs),
                 data: self.lower_variant_data(&v.node.data),
-                disr_expr: v.node.disr_expr.as_ref().map(|e| {
-                    self.lower_body(None, |this| this.lower_expr(e))
-                }),
+                disr_expr: v.node
+                    .disr_expr
+                    .as_ref()
+                    .map(|e| self.lower_body(None, |this| this.lower_expr(e))),
             },
             span: v.span,
         }
     }
 
-    fn lower_qpath(&mut self,
-                   id: NodeId,
-                   qself: &Option<QSelf>,
-                   p: &Path,
-                   param_mode: ParamMode,
-                   itctx: ImplTraitContext)
-                   -> hir::QPath {
+    fn lower_qpath(
+        &mut self,
+        id: NodeId,
+        qself: &Option<QSelf>,
+        p: &Path,
+        param_mode: ParamMode,
+        itctx: ImplTraitContext,
+    ) -> hir::QPath {
         let qself_position = qself.as_ref().map(|q| q.position);
         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
 
-        let resolution = self.resolver.get_resolution(id)
-                                      .unwrap_or(PathResolution::new(Def::Err));
+        let resolution = self.resolver
+            .get_resolution(id)
+            .unwrap_or(PathResolution::new(Def::Err));
 
         let proj_start = p.segments.len() - resolution.unresolved_segments();
         let path = P(hir::Path {
             def: resolution.base_def(),
-            segments: p.segments[..proj_start].iter().enumerate().map(|(i, segment)| {
-                let param_mode = match (qself_position, param_mode) {
-                    (Some(j), ParamMode::Optional) if i < j => {
-                        // This segment is part of the trait path in a
-                        // qualified path - one of `a`, `b` or `Trait`
-                        // in `<X as a::b::Trait>::T::U::method`.
-                        ParamMode::Explicit
-                    }
-                    _ => param_mode
-                };
+            segments: p.segments[..proj_start]
+                .iter()
+                .enumerate()
+                .map(|(i, segment)| {
+                    let param_mode = match (qself_position, param_mode) {
+                        (Some(j), ParamMode::Optional) if i < j => {
+                            // This segment is part of the trait path in a
+                            // qualified path - one of `a`, `b` or `Trait`
+                            // in `<X as a::b::Trait>::T::U::method`.
+                            ParamMode::Explicit
+                        }
+                        _ => param_mode,
+                    };
 
-                // Figure out if this is a type/trait segment,
-                // which may need lifetime elision performed.
-                let parent_def_id = |this: &mut Self, def_id: DefId| {
-                    DefId {
+                    // Figure out if this is a type/trait segment,
+                    // which may need lifetime elision performed.
+                    let parent_def_id = |this: &mut Self, def_id: DefId| DefId {
                         krate: def_id.krate,
-                        index: this.def_key(def_id).parent.expect("missing parent")
-                    }
-                };
-                let type_def_id = match resolution.base_def() {
-                    Def::AssociatedTy(def_id) if i + 2 == proj_start => {
-                        Some(parent_def_id(self, def_id))
-                    }
-                    Def::Variant(def_id) if i + 1 == proj_start => {
-                        Some(parent_def_id(self, def_id))
-                    }
-                    Def::Struct(def_id) |
-                    Def::Union(def_id) |
-                    Def::Enum(def_id) |
-                    Def::TyAlias(def_id) |
-                    Def::Trait(def_id) if i + 1 == proj_start => Some(def_id),
-                    _ => None
-                };
-                let parenthesized_generic_args = match resolution.base_def() {
-                    // `a::b::Trait(Args)`
-                    Def::Trait(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
-                    // `a::b::Trait(Args)::TraitItem`
-                    Def::Method(..) |
-                    Def::AssociatedConst(..) |
-                    Def::AssociatedTy(..) if i + 2 == proj_start => ParenthesizedGenericArgs::Ok,
-                    // Avoid duplicated errors
-                    Def::Err => ParenthesizedGenericArgs::Ok,
-                    // An error
-                    Def::Struct(..) | Def::Enum(..) | Def::Union(..) | Def::TyAlias(..) |
-                    Def::Variant(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Err,
-                    // A warning for now, for compatibility reasons
-                    _ => ParenthesizedGenericArgs::Warn,
-                };
+                        index: this.def_key(def_id).parent.expect("missing parent"),
+                    };
+                    let type_def_id = match resolution.base_def() {
+                        Def::AssociatedTy(def_id) if i + 2 == proj_start => {
+                            Some(parent_def_id(self, def_id))
+                        }
+                        Def::Variant(def_id) if i + 1 == proj_start => {
+                            Some(parent_def_id(self, def_id))
+                        }
+                        Def::Struct(def_id)
+                        | Def::Union(def_id)
+                        | Def::Enum(def_id)
+                        | Def::TyAlias(def_id)
+                        | Def::Trait(def_id) if i + 1 == proj_start =>
+                        {
+                            Some(def_id)
+                        }
+                        _ => None,
+                    };
+                    let parenthesized_generic_args = match resolution.base_def() {
+                        // `a::b::Trait(Args)`
+                        Def::Trait(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
+                        // `a::b::Trait(Args)::TraitItem`
+                        Def::Method(..) | Def::AssociatedConst(..) | Def::AssociatedTy(..)
+                            if i + 2 == proj_start =>
+                        {
+                            ParenthesizedGenericArgs::Ok
+                        }
+                        // Avoid duplicated errors
+                        Def::Err => ParenthesizedGenericArgs::Ok,
+                        // An error
+                        Def::Struct(..)
+                        | Def::Enum(..)
+                        | Def::Union(..)
+                        | Def::TyAlias(..)
+                        | Def::Variant(..) if i + 1 == proj_start =>
+                        {
+                            ParenthesizedGenericArgs::Err
+                        }
+                        // A warning for now, for compatibility reasons
+                        _ => ParenthesizedGenericArgs::Warn,
+                    };
 
-                let num_lifetimes = type_def_id.map_or(0, |def_id| {
-                    if let Some(&n) = self.type_def_lifetime_params.get(&def_id) {
-                        return n;
-                    }
-                    assert!(!def_id.is_local());
-                    let n = self.cstore
-                                .item_generics_cloned_untracked(def_id, self.sess)
-                                .regions
-                                .len();
-                    self.type_def_lifetime_params.insert(def_id, n);
-                    n
-                });
-                self.lower_path_segment(p.span, segment, param_mode, num_lifetimes,
-                                        parenthesized_generic_args, itctx)
-            }).collect(),
+                    let num_lifetimes = type_def_id.map_or(0, |def_id| {
+                        if let Some(&n) = self.type_def_lifetime_params.get(&def_id) {
+                            return n;
+                        }
+                        assert!(!def_id.is_local());
+                        let n = self.cstore
+                            .item_generics_cloned_untracked(def_id, self.sess)
+                            .regions
+                            .len();
+                        self.type_def_lifetime_params.insert(def_id, n);
+                        n
+                    });
+                    self.lower_path_segment(
+                        p.span,
+                        segment,
+                        param_mode,
+                        num_lifetimes,
+                        parenthesized_generic_args,
+                        itctx,
+                    )
+                })
+                .collect(),
             span: p.span,
         });
 
@@ -1331,9 +1504,14 @@ impl<'a> LoweringContext<'a> {
         //   3. `<<std::vec::Vec<T>>::IntoIter>::Item`
         // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
         for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
-            let segment = P(self.lower_path_segment(p.span, segment, param_mode, 0,
-                                                    ParenthesizedGenericArgs::Warn,
-                                                    itctx));
+            let segment = P(self.lower_path_segment(
+                p.span,
+                segment,
+                param_mode,
+                0,
+                ParenthesizedGenericArgs::Warn,
+                itctx,
+            ));
             let qpath = hir::QPath::TypeRelative(ty, segment);
 
             // It's finished, return the extension of the right node type.
@@ -1347,51 +1525,54 @@ impl<'a> LoweringContext<'a> {
         }
 
         // Should've returned in the for loop above.
-        span_bug!(p.span, "lower_qpath: no final extension segment in {}..{}",
-                  proj_start, p.segments.len())
+        span_bug!(
+            p.span,
+            "lower_qpath: no final extension segment in {}..{}",
+            proj_start,
+            p.segments.len()
+        )
     }
 
-    fn lower_path_extra(&mut self,
-                        id: NodeId,
-                        p: &Path,
-                        name: Option<Name>,
-                        param_mode: ParamMode,
-                        defaults_to_global: bool)
-                        -> hir::Path {
-        let mut segments = p.segments.iter();
-        if defaults_to_global && p.is_global() {
-            segments.next();
-        }
-
+    fn lower_path_extra(
+        &mut self,
+        id: NodeId,
+        p: &Path,
+        name: Option<Name>,
+        param_mode: ParamMode,
+    ) -> hir::Path {
         hir::Path {
             def: self.expect_full_def(id),
-            segments: segments.map(|segment| {
-                self.lower_path_segment(p.span, segment, param_mode, 0,
-                                        ParenthesizedGenericArgs::Err,
-                                        ImplTraitContext::Disallowed)
-            }).chain(name.map(|name| hir::PathSegment::from_name(name)))
-              .collect(),
+            segments: p.segments
+                .iter()
+                .map(|segment| {
+                    self.lower_path_segment(
+                        p.span,
+                        segment,
+                        param_mode,
+                        0,
+                        ParenthesizedGenericArgs::Err,
+                        ImplTraitContext::Disallowed,
+                    )
+                })
+                .chain(name.map(|name| hir::PathSegment::from_name(name)))
+                .collect(),
             span: p.span,
         }
     }
 
-    fn lower_path(&mut self,
-                  id: NodeId,
-                  p: &Path,
-                  param_mode: ParamMode,
-                  defaults_to_global: bool)
-                  -> hir::Path {
-        self.lower_path_extra(id, p, None, param_mode, defaults_to_global)
+    fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path {
+        self.lower_path_extra(id, p, None, param_mode)
     }
 
-    fn lower_path_segment(&mut self,
-                          path_span: Span,
-                          segment: &PathSegment,
-                          param_mode: ParamMode,
-                          expected_lifetimes: usize,
-                          parenthesized_generic_args: ParenthesizedGenericArgs,
-                          itctx: ImplTraitContext)
-                          -> hir::PathSegment {
+    fn lower_path_segment(
+        &mut self,
+        path_span: Span,
+        segment: &PathSegment,
+        param_mode: ParamMode,
+        expected_lifetimes: usize,
+        parenthesized_generic_args: ParenthesizedGenericArgs,
+        itctx: ImplTraitContext,
+    ) -> hir::PathSegment {
         let (mut parameters, infer_types) = if let Some(ref parameters) = segment.parameters {
             let msg = "parenthesized parameters may only be used with a trait";
             match **parameters {
@@ -1399,74 +1580,108 @@ impl<'a> LoweringContext<'a> {
                     self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
                 }
                 PathParameters::Parenthesized(ref data) => match parenthesized_generic_args {
-                    ParenthesizedGenericArgs::Ok =>
-                        self.lower_parenthesized_parameter_data(data),
+                    ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
                     ParenthesizedGenericArgs::Warn => {
-                        self.sess.buffer_lint(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
-                                              CRATE_NODE_ID, data.span, msg.into());
+                        self.sess.buffer_lint(
+                            PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
+                            CRATE_NODE_ID,
+                            data.span,
+                            msg.into(),
+                        );
                         (hir::PathParameters::none(), true)
                     }
                     ParenthesizedGenericArgs::Err => {
                         struct_span_err!(self.sess, data.span, E0214, "{}", msg)
-                            .span_label(data.span, "only traits may use parentheses").emit();
+                            .span_label(data.span, "only traits may use parentheses")
+                            .emit();
                         (hir::PathParameters::none(), true)
                     }
-                }
+                },
             }
         } else {
             self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode, itctx)
         };
 
         if !parameters.parenthesized && parameters.lifetimes.is_empty() {
-            parameters.lifetimes = (0..expected_lifetimes).map(|_| {
-                self.elided_lifetime(path_span)
-            }).collect();
+            parameters.lifetimes = self.elided_path_lifetimes(path_span, expected_lifetimes);
         }
 
         hir::PathSegment::new(
             self.lower_ident(segment.identifier),
             parameters,
-            infer_types
+            infer_types,
         )
     }
 
-    fn lower_angle_bracketed_parameter_data(&mut self,
-                                            data: &AngleBracketedParameterData,
-                                            param_mode: ParamMode,
-                                            itctx: ImplTraitContext)
-                                            -> (hir::PathParameters, bool) {
-        let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings, .. } = data;
-        (hir::PathParameters {
-            lifetimes: self.lower_lifetimes(lifetimes),
-            types: types.iter().map(|ty| self.lower_ty(ty, itctx)).collect(),
-            bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(),
-            parenthesized: false,
-        }, types.is_empty() && param_mode == ParamMode::Optional)
+    fn lower_angle_bracketed_parameter_data(
+        &mut self,
+        data: &AngleBracketedParameterData,
+        param_mode: ParamMode,
+        itctx: ImplTraitContext,
+    ) -> (hir::PathParameters, bool) {
+        let &AngleBracketedParameterData {
+            ref lifetimes,
+            ref types,
+            ref bindings,
+            ..
+        } = data;
+        (
+            hir::PathParameters {
+                lifetimes: self.lower_lifetimes(lifetimes),
+                types: types.iter().map(|ty| self.lower_ty(ty, itctx)).collect(),
+                bindings: bindings
+                    .iter()
+                    .map(|b| self.lower_ty_binding(b, itctx))
+                    .collect(),
+                parenthesized: false,
+            },
+            types.is_empty() && param_mode == ParamMode::Optional,
+        )
     }
 
-    fn lower_parenthesized_parameter_data(&mut self,
-                                          data: &ParenthesizedParameterData)
-                                          -> (hir::PathParameters, bool) {
+    fn lower_parenthesized_parameter_data(
+        &mut self,
+        data: &ParenthesizedParameterData,
+    ) -> (hir::PathParameters, bool) {
         const DISALLOWED: ImplTraitContext = ImplTraitContext::Disallowed;
-        let &ParenthesizedParameterData { ref inputs, ref output, span } = data;
-        let inputs = inputs.iter().map(|ty| self.lower_ty(ty, DISALLOWED)).collect();
+        let &ParenthesizedParameterData {
+            ref inputs,
+            ref output,
+            span,
+        } = data;
+        let inputs = inputs
+            .iter()
+            .map(|ty| self.lower_ty(ty, DISALLOWED))
+            .collect();
         let mk_tup = |this: &mut Self, tys, span| {
             let LoweredNodeId { node_id, hir_id } = this.next_id();
-            P(hir::Ty { node: hir::TyTup(tys), id: node_id, hir_id, span })
+            P(hir::Ty {
+                node: hir::TyTup(tys),
+                id: node_id,
+                hir_id,
+                span,
+            })
         };
 
-        (hir::PathParameters {
-            lifetimes: hir::HirVec::new(),
-            types: hir_vec![mk_tup(self, inputs, span)],
-            bindings: hir_vec![hir::TypeBinding {
-                id: self.next_id().node_id,
-                name: Symbol::intern(FN_OUTPUT_NAME),
-                ty: output.as_ref().map(|ty| self.lower_ty(&ty, DISALLOWED))
-                                   .unwrap_or_else(|| mk_tup(self, hir::HirVec::new(), span)),
-                span: output.as_ref().map_or(span, |ty| ty.span),
-            }],
-            parenthesized: true,
-        }, false)
+        (
+            hir::PathParameters {
+                lifetimes: hir::HirVec::new(),
+                types: hir_vec![mk_tup(self, inputs, span)],
+                bindings: hir_vec![
+                    hir::TypeBinding {
+                        id: self.next_id().node_id,
+                        name: Symbol::intern(FN_OUTPUT_NAME),
+                        ty: output
+                            .as_ref()
+                            .map(|ty| self.lower_ty(&ty, DISALLOWED))
+                            .unwrap_or_else(|| mk_tup(self, hir::HirVec::new(), span)),
+                        span: output.as_ref().map_or(span, |ty| ty.span),
+                    }
+                ],
+                parenthesized: true,
+            },
+            false,
+        )
     }
 
     fn lower_local(&mut self, l: &Local) -> P<hir::Local> {
@@ -1474,7 +1689,9 @@ impl<'a> LoweringContext<'a> {
         P(hir::Local {
             id: node_id,
             hir_id,
-            ty: l.ty.as_ref().map(|t| self.lower_ty(t, ImplTraitContext::Disallowed)),
+            ty: l.ty
+                .as_ref()
+                .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed)),
             pat: self.lower_pat(&l.pat),
             init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
             span: l.span,
@@ -1499,24 +1716,22 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn lower_fn_args_to_names(&mut self, decl: &FnDecl)
-                              -> hir::HirVec<Spanned<Name>> {
-        decl.inputs.iter().map(|arg| {
-            match arg.pat.node {
-                PatKind::Ident(_, ident, None) => {
-                    respan(ident.span, ident.node.name)
-                }
+    fn lower_fn_args_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Spanned<Name>> {
+        decl.inputs
+            .iter()
+            .map(|arg| match arg.pat.node {
+                PatKind::Ident(_, ident, None) => respan(ident.span, ident.node.name),
                 _ => respan(arg.pat.span, keywords::Invalid.name()),
-            }
-        }).collect()
+            })
+            .collect()
     }
 
-
-    fn lower_fn_decl(&mut self,
-                     decl: &FnDecl,
-                     fn_def_id: Option<DefId>,
-                     impl_trait_return_allow: bool)
-                     -> P<hir::FnDecl> {
+    fn lower_fn_decl(
+        &mut self,
+        decl: &FnDecl,
+        fn_def_id: Option<DefId>,
+        impl_trait_return_allow: bool,
+    ) -> P<hir::FnDecl> {
         // NOTE: The two last parameters here have to do with impl Trait. If fn_def_id is Some,
         //       then impl Trait arguments are lowered into generic parameters on the given
         //       fn_def_id, otherwise impl Trait is disallowed. (for now)
@@ -1525,38 +1740,44 @@ impl<'a> LoweringContext<'a> {
         //       return positions as well. This guards against trait declarations and their impls
         //       where impl Trait is disallowed. (again for now)
         P(hir::FnDecl {
-            inputs: decl.inputs.iter()
-                .map(|arg| if let Some(def_id) = fn_def_id {
-                    self.lower_ty(&arg.ty, ImplTraitContext::Universal(def_id))
-                } else {
-                    self.lower_ty(&arg.ty, ImplTraitContext::Disallowed)
-                }).collect(),
+            inputs: decl.inputs
+                .iter()
+                .map(|arg| {
+                    if let Some(def_id) = fn_def_id {
+                        self.lower_ty(&arg.ty, ImplTraitContext::Universal(def_id))
+                    } else {
+                        self.lower_ty(&arg.ty, ImplTraitContext::Disallowed)
+                    }
+                })
+                .collect(),
             output: match decl.output {
                 FunctionRetTy::Ty(ref ty) => match fn_def_id {
-                    Some(_) if impl_trait_return_allow =>
-                        hir::Return(self.lower_ty(ty, ImplTraitContext::Existential)),
+                    Some(_) if impl_trait_return_allow => {
+                        hir::Return(self.lower_ty(ty, ImplTraitContext::Existential))
+                    }
                     _ => hir::Return(self.lower_ty(ty, ImplTraitContext::Disallowed)),
                 },
                 FunctionRetTy::Default(span) => hir::DefaultReturn(span),
             },
             variadic: decl.variadic,
-            has_implicit_self: decl.inputs.get(0).map_or(false, |arg| {
-                match arg.ty.node {
-                    TyKind::ImplicitSelf => true,
-                    TyKind::Rptr(_, ref mt) => mt.ty.node == TyKind::ImplicitSelf,
-                    _ => false
-                }
-            })
+            has_implicit_self: decl.inputs.get(0).map_or(false, |arg| match arg.ty.node {
+                TyKind::ImplicitSelf => true,
+                TyKind::Rptr(_, ref mt) => mt.ty.node == TyKind::ImplicitSelf,
+                _ => false,
+            }),
         })
     }
 
-    fn lower_ty_param_bound(&mut self, tpb: &TyParamBound, itctx: ImplTraitContext)
-                            -> hir::TyParamBound {
+    fn lower_ty_param_bound(
+        &mut self,
+        tpb: &TyParamBound,
+        itctx: ImplTraitContext,
+    ) -> hir::TyParamBound {
         match *tpb {
-            TraitTyParamBound(ref ty, modifier) => {
-                hir::TraitTyParamBound(self.lower_poly_trait_ref(ty, itctx),
-                                       self.lower_trait_bound_modifier(modifier))
-            }
+            TraitTyParamBound(ref ty, modifier) => hir::TraitTyParamBound(
+                self.lower_poly_trait_ref(ty, itctx),
+                self.lower_trait_bound_modifier(modifier),
+            ),
             RegionTyParamBound(ref lifetime) => {
                 hir::RegionTyParamBound(self.lower_lifetime(lifetime))
             }
@@ -1576,47 +1797,60 @@ impl<'a> LoweringContext<'a> {
         let itctx = ImplTraitContext::Universal(self.resolver.definitions().local_def_id(tp.id));
         let mut bounds = self.lower_bounds(&tp.bounds, itctx);
         if !add_bounds.is_empty() {
-            bounds = bounds.into_iter().chain(
-                self.lower_bounds(add_bounds, itctx).into_iter()
-            ).collect();
+            bounds = bounds
+                .into_iter()
+                .chain(self.lower_bounds(add_bounds, itctx).into_iter())
+                .collect();
         }
 
         hir::TyParam {
             id: self.lower_node_id(tp.id).node_id,
             name,
             bounds,
-            default: tp.default.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
+            default: tp.default
+                .as_ref()
+                .map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
             span: tp.span,
             pure_wrt_drop: attr::contains_name(&tp.attrs, "may_dangle"),
-            synthetic: tp.attrs.iter()
-                               .filter(|attr| attr.check_name("rustc_synthetic"))
-                               .map(|_| hir::SyntheticTyParamKind::ImplTrait)
-                               .nth(0),
+            synthetic: tp.attrs
+                .iter()
+                .filter(|attr| attr.check_name("rustc_synthetic"))
+                .map(|_| hir::SyntheticTyParamKind::ImplTrait)
+                .nth(0),
+            attrs: self.lower_attrs(&tp.attrs),
         }
     }
 
     fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
-        let name = match self.lower_ident(l.ident) {
-            x if x == "'_" => hir::LifetimeName::Underscore,
-            x if x == "'static" => hir::LifetimeName::Static,
-            name => {
-                if  self.is_collecting_in_band_lifetimes &&
-                    !self.in_scope_lifetimes.contains(&name) &&
-                    self.lifetimes_to_define.iter()
-                        .find(|&&(_, lt_name)| lt_name == name)
-                        .is_none()
-                {
-                    self.lifetimes_to_define.push((l.span, name));
+        match self.lower_ident(l.ident) {
+            x if x == "'static" => self.new_named_lifetime(l.id, l.span, hir::LifetimeName::Static),
+            x if x == "'_" => match self.anonymous_lifetime_mode {
+                AnonymousLifetimeMode::CreateParameter => {
+                    let fresh_name = self.collect_fresh_in_band_lifetime(l.span);
+                    self.new_named_lifetime(l.id, l.span, fresh_name)
                 }
 
-                hir::LifetimeName::Name(name)
+                AnonymousLifetimeMode::PassThrough => {
+                    self.new_named_lifetime(l.id, l.span, hir::LifetimeName::Underscore)
+                }
+            },
+            name => {
+                self.maybe_collect_in_band_lifetime(l.span, name);
+                self.new_named_lifetime(l.id, l.span, hir::LifetimeName::Name(name))
             }
-        };
+        }
+    }
 
+    fn new_named_lifetime(
+        &mut self,
+        id: NodeId,
+        span: Span,
+        name: hir::LifetimeName,
+    ) -> hir::Lifetime {
         hir::Lifetime {
-            id: self.lower_node_id(l.id).node_id,
-            name,
-            span: l.span,
+            id: self.lower_node_id(id).node_id,
+            span,
+            name: name,
         }
     }
 
@@ -1645,17 +1879,16 @@ impl<'a> LoweringContext<'a> {
         params: &Vec<GenericParam>,
         add_bounds: &NodeMap<Vec<TyParamBound>>,
     ) -> hir::HirVec<hir::GenericParam> {
-        params.iter()
+        params
+            .iter()
             .map(|param| match *param {
                 GenericParam::Lifetime(ref lifetime_def) => {
                     hir::GenericParam::Lifetime(self.lower_lifetime_def(lifetime_def))
                 }
-                GenericParam::Type(ref ty_param) => {
-                    hir::GenericParam::Type(self.lower_ty_param(
-                        ty_param,
-                        add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x)
-                    ))
-                }
+                GenericParam::Type(ref ty_param) => hir::GenericParam::Type(self.lower_ty_param(
+                    ty_param,
+                    add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x),
+                )),
             })
             .collect()
     }
@@ -1671,24 +1904,30 @@ impl<'a> LoweringContext<'a> {
                 'next_bound: for bound in &bound_pred.bounds {
                     if let TraitTyParamBound(_, TraitBoundModifier::Maybe) = *bound {
                         let report_error = |this: &mut Self| {
-                            this.diagnostic().span_err(bound_pred.bounded_ty.span,
-                                                       "`?Trait` bounds are only permitted at the \
-                                                        point where a type parameter is declared");
+                            this.diagnostic().span_err(
+                                bound_pred.bounded_ty.span,
+                                "`?Trait` bounds are only permitted at the \
+                                 point where a type parameter is declared",
+                            );
                         };
                         // Check if the where clause type is a plain type parameter.
                         match bound_pred.bounded_ty.node {
                             TyKind::Path(None, ref path)
-                                    if path.segments.len() == 1 &&
-                                       bound_pred.bound_generic_params.is_empty() => {
-                                if let Some(Def::TyParam(def_id)) =
-                                        self.resolver.get_resolution(bound_pred.bounded_ty.id)
-                                                     .map(|d| d.base_def()) {
+                                if path.segments.len() == 1
+                                    && bound_pred.bound_generic_params.is_empty() =>
+                            {
+                                if let Some(Def::TyParam(def_id)) = self.resolver
+                                    .get_resolution(bound_pred.bounded_ty.id)
+                                    .map(|d| d.base_def())
+                                {
                                     if let Some(node_id) =
-                                            self.resolver.definitions().as_local_node_id(def_id) {
+                                        self.resolver.definitions().as_local_node_id(def_id)
+                                    {
                                         for param in &g.params {
                                             if let GenericParam::Type(ref ty_param) = *param {
                                                 if node_id == ty_param.id {
-                                                    add_bounds.entry(ty_param.id)
+                                                    add_bounds
+                                                        .entry(ty_param.id)
                                                         .or_insert(Vec::new())
                                                         .push(bound.clone());
                                                     continue 'next_bound;
@@ -1699,7 +1938,7 @@ impl<'a> LoweringContext<'a> {
                                 }
                                 report_error(self)
                             }
-                            _ => report_error(self)
+                            _ => report_error(self),
                         }
                     }
                 }
@@ -1717,81 +1956,93 @@ impl<'a> LoweringContext<'a> {
         hir::WhereClause {
             id: self.lower_node_id(wc.id).node_id,
             predicates: wc.predicates
-                          .iter()
-                          .map(|predicate| self.lower_where_predicate(predicate))
-                          .collect(),
+                .iter()
+                .map(|predicate| self.lower_where_predicate(predicate))
+                .collect(),
         }
     }
 
     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
         match *pred {
-            WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_generic_params,
-                                                                ref bounded_ty,
-                                                                ref bounds,
-                                                                span}) => {
+            WherePredicate::BoundPredicate(WhereBoundPredicate {
+                ref bound_generic_params,
+                ref bounded_ty,
+                ref bounds,
+                span,
+            }) => {
                 self.with_in_scope_lifetime_defs(
-                    &bound_generic_params.iter()
-                        .filter_map(|p| match *p {
-                            GenericParam::Lifetime(ref ld) => Some(ld.clone()),
-                            _ => None,
-                        })
-                        .collect::<Vec<_>>(),
+                    bound_generic_params.iter().filter_map(|p| match p {
+                        GenericParam::Lifetime(ld) => Some(ld),
+                        _ => None,
+                    }),
                     |this| {
                         hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                            bound_generic_params:
-                                this.lower_generic_params(bound_generic_params, &NodeMap()),
+                            bound_generic_params: this.lower_generic_params(
+                                bound_generic_params,
+                                &NodeMap(),
+                            ),
                             bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed),
-                            bounds: bounds.iter().filter_map(|bound| match *bound {
-                                // Ignore `?Trait` bounds.
-                                // Tthey were copied into type parameters already.
-                                TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
-                                _ => Some(this.lower_ty_param_bound(
-                                        bound, ImplTraitContext::Disallowed))
-                            }).collect(),
+                            bounds: bounds
+                                .iter()
+                                .filter_map(|bound| match *bound {
+                                    // Ignore `?Trait` bounds.
+                                    // Tthey were copied into type parameters already.
+                                    TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
+                                    _ => Some(this.lower_ty_param_bound(
+                                        bound,
+                                        ImplTraitContext::Disallowed,
+                                    )),
+                                })
+                                .collect(),
                             span,
                         })
-                    }
+                    },
                 )
             }
-            WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime,
-                                                                  ref bounds,
-                                                                  span}) => {
-                hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
-                    span,
-                    lifetime: self.lower_lifetime(lifetime),
-                    bounds: bounds.iter().map(|bound| self.lower_lifetime(bound)).collect(),
-                })
-            }
-            WherePredicate::EqPredicate(WhereEqPredicate{ id,
-                                                          ref lhs_ty,
-                                                          ref rhs_ty,
-                                                          span}) => {
-                hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
-                    id: self.lower_node_id(id).node_id,
-                    lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::Disallowed),
-                    rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::Disallowed),
-                    span,
-                })
-            }
+            WherePredicate::RegionPredicate(WhereRegionPredicate {
+                ref lifetime,
+                ref bounds,
+                span,
+            }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
+                span,
+                lifetime: self.lower_lifetime(lifetime),
+                bounds: bounds
+                    .iter()
+                    .map(|bound| self.lower_lifetime(bound))
+                    .collect(),
+            }),
+            WherePredicate::EqPredicate(WhereEqPredicate {
+                id,
+                ref lhs_ty,
+                ref rhs_ty,
+                span,
+            }) => hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
+                id: self.lower_node_id(id).node_id,
+                lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::Disallowed),
+                rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::Disallowed),
+                span,
+            }),
         }
     }
 
     fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
         match *vdata {
-            VariantData::Struct(ref fields, id) => {
-                hir::VariantData::Struct(fields.iter()
-                                               .enumerate()
-                                               .map(|f| self.lower_struct_field(f))
-                                               .collect(),
-                                         self.lower_node_id(id).node_id)
-            }
-            VariantData::Tuple(ref fields, id) => {
-                hir::VariantData::Tuple(fields.iter()
-                                              .enumerate()
-                                              .map(|f| self.lower_struct_field(f))
-                                              .collect(),
-                                        self.lower_node_id(id).node_id)
-            }
+            VariantData::Struct(ref fields, id) => hir::VariantData::Struct(
+                fields
+                    .iter()
+                    .enumerate()
+                    .map(|f| self.lower_struct_field(f))
+                    .collect(),
+                self.lower_node_id(id).node_id,
+            ),
+            VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple(
+                fields
+                    .iter()
+                    .enumerate()
+                    .map(|f| self.lower_struct_field(f))
+                    .collect(),
+                self.lower_node_id(id).node_id,
+            ),
             VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id).node_id),
         }
     }
@@ -1799,7 +2050,7 @@ impl<'a> LoweringContext<'a> {
     fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> hir::TraitRef {
         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
             hir::QPath::Resolved(None, path) => path.and_then(|path| path),
-            qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath)
+            qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
         };
         hir::TraitRef {
             path,
@@ -1807,13 +2058,15 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn lower_poly_trait_ref(&mut self,
-                            p: &PolyTraitRef,
-                            itctx: ImplTraitContext)
-                            -> hir::PolyTraitRef {
+    fn lower_poly_trait_ref(
+        &mut self,
+        p: &PolyTraitRef,
+        itctx: ImplTraitContext,
+    ) -> hir::PolyTraitRef {
         let bound_generic_params = self.lower_generic_params(&p.bound_generic_params, &NodeMap());
         let trait_ref = self.with_parent_impl_lifetime_defs(
-            &bound_generic_params.iter()
+            &bound_generic_params
+                .iter()
                 .filter_map(|p| match *p {
                     hir::GenericParam::Lifetime(ref ld) => Some(ld.clone()),
                     _ => None,
@@ -1836,7 +2089,10 @@ impl<'a> LoweringContext<'a> {
             name: self.lower_ident(match f.ident {
                 Some(ident) => ident,
                 // FIXME(jseyfried) positional field hygiene
-                None => Ident { name: Symbol::intern(&index.to_string()), ctxt: f.span.ctxt() },
+                None => Ident {
+                    name: Symbol::intern(&index.to_string()),
+                    ctxt: f.span.ctxt(),
+                },
             }),
             vis: self.lower_visibility(&f.vis, None),
             ty: self.lower_ty(&f.ty, ImplTraitContext::Disallowed),
@@ -1860,9 +2116,15 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn lower_bounds(&mut self, bounds: &[TyParamBound], itctx: ImplTraitContext)
-                    -> hir::TyParamBounds {
-        bounds.iter().map(|bound| self.lower_ty_param_bound(bound, itctx)).collect()
+    fn lower_bounds(
+        &mut self,
+        bounds: &[TyParamBound],
+        itctx: ImplTraitContext,
+    ) -> hir::TyParamBounds {
+        bounds
+            .iter()
+            .map(|bound| self.lower_ty_param_bound(bound, itctx))
+            .collect()
     }
 
     fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
@@ -1896,15 +2158,16 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn lower_item_kind(&mut self,
-                       id: NodeId,
-                       name: &mut Name,
-                       attrs: &hir::HirVec<Attribute>,
-                       vis: &mut hir::Visibility,
-                       i: &ItemKind)
-                       -> hir::Item_ {
+    fn lower_item_kind(
+        &mut self,
+        id: NodeId,
+        name: &mut Name,
+        attrs: &hir::HirVec<Attribute>,
+        vis: &mut hir::Visibility,
+        i: &ItemKind,
+    ) -> hir::Item_ {
         match *i {
-            ItemKind::ExternCrate(string) => hir::ItemExternCrate(string),
+            ItemKind::ExternCrate(orig_name) => hir::ItemExternCrate(orig_name),
             ItemKind::Use(ref use_tree) => {
                 // Start with an empty prefix
                 let prefix = Path {
@@ -1916,49 +2179,57 @@ impl<'a> LoweringContext<'a> {
             }
             ItemKind::Static(ref t, m, ref e) => {
                 let value = self.lower_body(None, |this| this.lower_expr(e));
-                hir::ItemStatic(self.lower_ty(t, ImplTraitContext::Disallowed),
-                                self.lower_mutability(m),
-                                value)
+                hir::ItemStatic(
+                    self.lower_ty(t, ImplTraitContext::Disallowed),
+                    self.lower_mutability(m),
+                    value,
+                )
             }
             ItemKind::Const(ref t, ref e) => {
                 let value = self.lower_body(None, |this| this.lower_expr(e));
                 hir::ItemConst(self.lower_ty(t, ImplTraitContext::Disallowed), value)
             }
             ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
-                let fn_def_id = self.resolver.definitions().opt_local_def_id(id);
+                let fn_def_id = self.resolver.definitions().local_def_id(id);
                 self.with_new_scopes(|this| {
                     let body_id = this.lower_body(Some(decl), |this| {
                         let body = this.lower_block(body, false);
                         this.expr_block(body, ThinVec::new())
                     });
-                    let (generics, fn_decl) =
-                        this.add_in_band_defs(generics, fn_def_id, |this|
-                            this.lower_fn_decl(decl, fn_def_id, true));
-
-                    hir::ItemFn(fn_decl,
-                                this.lower_unsafety(unsafety),
-                                this.lower_constness(constness),
-                                abi,
-                                generics,
-                                body_id)
+                    let (generics, fn_decl) = this.add_in_band_defs(
+                        generics,
+                        fn_def_id,
+                        AnonymousLifetimeMode::PassThrough,
+                        |this| this.lower_fn_decl(decl, Some(fn_def_id), true),
+                    );
+
+                    hir::ItemFn(
+                        fn_decl,
+                        this.lower_unsafety(unsafety),
+                        this.lower_constness(constness),
+                        abi,
+                        generics,
+                        body_id,
+                    )
                 })
             }
             ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
             ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
             ItemKind::GlobalAsm(ref ga) => hir::ItemGlobalAsm(self.lower_global_asm(ga)),
-            ItemKind::Ty(ref t, ref generics) => {
-                hir::ItemTy(self.lower_ty(t, ImplTraitContext::Disallowed),
-                            self.lower_generics(generics))
-            }
-            ItemKind::Enum(ref enum_definition, ref generics) => {
-                hir::ItemEnum(hir::EnumDef {
-                                  variants: enum_definition.variants
-                                                           .iter()
-                                                           .map(|x| self.lower_variant(x))
-                                                           .collect(),
-                              },
-                              self.lower_generics(generics))
-            }
+            ItemKind::Ty(ref t, ref generics) => hir::ItemTy(
+                self.lower_ty(t, ImplTraitContext::Disallowed),
+                self.lower_generics(generics),
+            ),
+            ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemEnum(
+                hir::EnumDef {
+                    variants: enum_definition
+                        .variants
+                        .iter()
+                        .map(|x| self.lower_variant(x))
+                        .collect(),
+                },
+                self.lower_generics(generics),
+            ),
             ItemKind::Struct(ref struct_def, ref generics) => {
                 let struct_def = self.lower_variant_data(struct_def);
                 hir::ItemStruct(struct_def, self.lower_generics(generics))
@@ -1967,21 +2238,40 @@ impl<'a> LoweringContext<'a> {
                 let vdata = self.lower_variant_data(vdata);
                 hir::ItemUnion(vdata, self.lower_generics(generics))
             }
-            ItemKind::Impl(unsafety,
-                           polarity,
-                           defaultness,
-                           ref ast_generics,
-                           ref ifce,
-                           ref ty,
-                           ref impl_items) => {
-                let def_id = self.resolver.definitions().opt_local_def_id(id);
-                let (generics, (ifce, lowered_ty)) =
-                    self.add_in_band_defs(ast_generics, def_id, |this| {
-                        let ifce = ifce.as_ref().map(|trait_ref| {
+            ItemKind::Impl(
+                unsafety,
+                polarity,
+                defaultness,
+                ref ast_generics,
+                ref trait_ref,
+                ref ty,
+                ref impl_items,
+            ) => {
+                let def_id = self.resolver.definitions().local_def_id(id);
+
+                // Lower the "impl header" first. This ordering is important
+                // for in-band lifetimes! Consider `'a` here:
+                //
+                //     impl Foo<'a> for u32 {
+                //         fn method(&'a self) { .. }
+                //     }
+                //
+                // Because we start by lowering the `Foo<'a> for u32`
+                // part, we will add `'a` to the list of generics on
+                // the impl. When we then encounter it later in the
+                // method, it will not be considered an in-band
+                // lifetime to be added, but rather a reference to a
+                // parent lifetime.
+                let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
+                    ast_generics,
+                    def_id,
+                    AnonymousLifetimeMode::CreateParameter,
+                    |this| {
+                        let trait_ref = trait_ref.as_ref().map(|trait_ref| {
                             this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
                         });
 
-                        if let Some(ref trait_ref) = ifce {
+                        if let Some(ref trait_ref) = trait_ref {
                             if let Def::Trait(def_id) = trait_ref.path.def {
                                 this.trait_impls.entry(def_id).or_insert(vec![]).push(id);
                             }
@@ -1989,46 +2279,51 @@ impl<'a> LoweringContext<'a> {
 
                         let lowered_ty = this.lower_ty(ty, ImplTraitContext::Disallowed);
 
-                        (ifce, lowered_ty)
-                    });
+                        (trait_ref, lowered_ty)
+                    },
+                );
 
                 let new_impl_items = self.with_in_scope_lifetime_defs(
-                    &ast_generics.params
-                        .iter()
-                        .filter_map(|p| match *p {
-                            GenericParam::Lifetime(ref ld) => Some(ld.clone()),
-                            _ => None,
-                        })
-                        .collect::<Vec<_>>(),
+                    ast_generics.params.iter().filter_map(|p| match p {
+                        GenericParam::Lifetime(ld) => Some(ld),
+                        _ => None,
+                    }),
                     |this| {
-                        impl_items.iter()
+                        impl_items
+                            .iter()
                             .map(|item| this.lower_impl_item_ref(item))
                             .collect()
-                    }
+                    },
                 );
 
-
-                hir::ItemImpl(self.lower_unsafety(unsafety),
-                              self.lower_impl_polarity(polarity),
-                              self.lower_defaultness(defaultness, true /* [1] */),
-                              generics,
-                              ifce,
-                              lowered_ty,
-                              new_impl_items)
+                hir::ItemImpl(
+                    self.lower_unsafety(unsafety),
+                    self.lower_impl_polarity(polarity),
+                    self.lower_defaultness(defaultness, true /* [1] */),
+                    generics,
+                    trait_ref,
+                    lowered_ty,
+                    new_impl_items,
+                )
             }
             ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
                 let bounds = self.lower_bounds(bounds, ImplTraitContext::Disallowed);
-                let items = items.iter().map(|item| self.lower_trait_item_ref(item)).collect();
-                hir::ItemTrait(self.lower_is_auto(is_auto),
-                               self.lower_unsafety(unsafety),
-                               self.lower_generics(generics),
-                               bounds,
-                               items)
-            }
-            ItemKind::TraitAlias(ref generics, ref bounds) => {
-                hir::ItemTraitAlias(self.lower_generics(generics),
-                                    self.lower_bounds(bounds, ImplTraitContext::Disallowed))
+                let items = items
+                    .iter()
+                    .map(|item| self.lower_trait_item_ref(item))
+                    .collect();
+                hir::ItemTrait(
+                    self.lower_is_auto(is_auto),
+                    self.lower_unsafety(unsafety),
+                    self.lower_generics(generics),
+                    bounds,
+                    items,
+                )
             }
+            ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemTraitAlias(
+                self.lower_generics(generics),
+                self.lower_bounds(bounds, ImplTraitContext::Disallowed),
+            ),
             ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
         }
 
@@ -2036,56 +2331,65 @@ impl<'a> LoweringContext<'a> {
         //     not cause an assertion failure inside the `lower_defaultness` function
     }
 
-    fn lower_use_tree(&mut self,
-                       tree: &UseTree,
-                       prefix: &Path,
-                       id: NodeId,
-                       vis: &mut hir::Visibility,
-                       name: &mut Name,
-                       attrs: &hir::HirVec<Attribute>)
-                       -> hir::Item_ {
+    fn lower_use_tree(
+        &mut self,
+        tree: &UseTree,
+        prefix: &Path,
+        id: NodeId,
+        vis: &mut hir::Visibility,
+        name: &mut Name,
+        attrs: &hir::HirVec<Attribute>,
+    ) -> hir::Item_ {
         let path = &tree.prefix;
 
         match tree.kind {
-            UseTreeKind::Simple(ident) => {
-                *name = ident.name;
+            UseTreeKind::Simple(rename) => {
+                *name = tree.ident().name;
 
                 // First apply the prefix to the path
                 let mut path = Path {
-                    segments: prefix.segments
+                    segments: prefix
+                        .segments
                         .iter()
                         .chain(path.segments.iter())
                         .cloned()
                         .collect(),
-                    span: path.span
+                    span: path.span,
                 };
 
                 // Correctly resolve `self` imports
-                if path.segments.len() > 1 &&
-                   path.segments.last().unwrap().identifier.name == keywords::SelfValue.name() {
+                if path.segments.len() > 1
+                    && path.segments.last().unwrap().identifier.name == keywords::SelfValue.name()
+                {
                     let _ = path.segments.pop();
-                    if ident.name == keywords::SelfValue.name() {
+                    if rename.is_none() {
                         *name = path.segments.last().unwrap().identifier.name;
                     }
                 }
 
-                let path = P(self.lower_path(id, &path, ParamMode::Explicit, true));
+                let path = P(self.lower_path(id, &path, ParamMode::Explicit));
                 hir::ItemUse(path, hir::UseKind::Single)
             }
             UseTreeKind::Glob => {
-                let path = P(self.lower_path(id, &Path {
-                    segments: prefix.segments
-                        .iter()
-                        .chain(path.segments.iter())
-                        .cloned()
-                        .collect(),
-                    span: path.span,
-                }, ParamMode::Explicit, true));
+                let path = P(self.lower_path(
+                    id,
+                    &Path {
+                        segments: prefix
+                            .segments
+                            .iter()
+                            .chain(path.segments.iter())
+                            .cloned()
+                            .collect(),
+                        span: path.span,
+                    },
+                    ParamMode::Explicit,
+                ));
                 hir::ItemUse(path, hir::UseKind::Glob)
             }
             UseTreeKind::Nested(ref trees) => {
                 let prefix = Path {
-                    segments: prefix.segments
+                    segments: prefix
+                        .segments
                         .iter()
                         .chain(path.segments.iter())
                         .cloned()
@@ -2103,16 +2407,15 @@ impl<'a> LoweringContext<'a> {
 
                     let mut vis = vis.clone();
                     let mut name = name.clone();
-                    let item = self.lower_use_tree(
-                        use_tree, &prefix, new_id, &mut vis, &mut name, &attrs,
-                    );
+                    let item =
+                        self.lower_use_tree(use_tree, &prefix, new_id, &mut vis, &mut name, &attrs);
 
                     self.with_hir_id_owner(new_id, |this| {
                         let vis = match vis {
                             hir::Visibility::Public => hir::Visibility::Public,
                             hir::Visibility::Crate => hir::Visibility::Crate,
                             hir::Visibility::Inherited => hir::Visibility::Inherited,
-                            hir::Visibility::Restricted { ref path, id: _  } => {
+                            hir::Visibility::Restricted { ref path, id: _ } => {
                                 hir::Visibility::Restricted {
                                     path: path.clone(),
                                     // We are allocating a new NodeId here
@@ -2121,22 +2424,25 @@ impl<'a> LoweringContext<'a> {
                             }
                         };
 
-                        this.items.insert(new_id, hir::Item {
-                            id: new_id,
-                            hir_id: new_hir_id,
-                            name: name,
-                            attrs: attrs.clone(),
-                            node: item,
-                            vis,
-                            span: use_tree.span,
-                        });
+                        this.items.insert(
+                            new_id,
+                            hir::Item {
+                                id: new_id,
+                                hir_id: new_hir_id,
+                                name: name,
+                                attrs: attrs.clone(),
+                                node: item,
+                                vis,
+                                span: use_tree.span,
+                            },
+                        );
                     });
                 }
 
                 // Privatize the degenerate import base, used only to check
                 // the stability of `use a::{};`, to avoid it showing up as
                 // a re-export by accident when `pub`, e.g. in documentation.
-                let path = P(self.lower_path(id, &prefix, ParamMode::Explicit, true));
+                let path = P(self.lower_path(id, &prefix, ParamMode::Explicit));
                 *vis = hir::Inherited;
                 hir::ItemUse(path, hir::UseKind::ListStem)
             }
@@ -2146,25 +2452,31 @@ impl<'a> LoweringContext<'a> {
     fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
         self.with_parent_def(i.id, |this| {
             let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id);
-            let fn_def_id = this.resolver.definitions().opt_local_def_id(node_id);
+            let trait_item_def_id = this.resolver.definitions().local_def_id(node_id);
 
             let (generics, node) = match i.node {
-                TraitItemKind::Const(ref ty, ref default) => {
-                    (
-                        this.lower_generics(&i.generics),
-                        hir::TraitItemKind::Const(
-                            this.lower_ty(ty, ImplTraitContext::Disallowed),
-                            default.as_ref().map(|x| {
-                                this.lower_body(None, |this| this.lower_expr(x))
-                            }))
-                    )
-                }
+                TraitItemKind::Const(ref ty, ref default) => (
+                    this.lower_generics(&i.generics),
+                    hir::TraitItemKind::Const(
+                        this.lower_ty(ty, ImplTraitContext::Disallowed),
+                        default
+                            .as_ref()
+                            .map(|x| this.lower_body(None, |this| this.lower_expr(x))),
+                    ),
+                ),
                 TraitItemKind::Method(ref sig, None) => {
                     let names = this.lower_fn_args_to_names(&sig.decl);
-                    this.add_in_band_defs(&i.generics, fn_def_id, |this|
-                        hir::TraitItemKind::Method(
-                            this.lower_method_sig(sig, fn_def_id, false),
-                            hir::TraitMethod::Required(names)))
+                    this.add_in_band_defs(
+                        &i.generics,
+                        trait_item_def_id,
+                        AnonymousLifetimeMode::PassThrough,
+                        |this| {
+                            hir::TraitItemKind::Method(
+                                this.lower_method_sig(sig, trait_item_def_id, false),
+                                hir::TraitMethod::Required(names),
+                            )
+                        },
+                    )
                 }
                 TraitItemKind::Method(ref sig, Some(ref body)) => {
                     let body_id = this.lower_body(Some(&sig.decl), |this| {
@@ -2172,21 +2484,27 @@ impl<'a> LoweringContext<'a> {
                         this.expr_block(body, ThinVec::new())
                     });
 
-                    this.add_in_band_defs(&i.generics, fn_def_id, |this|
-                        hir::TraitItemKind::Method(
-                            this.lower_method_sig(sig, fn_def_id, false),
-                           hir::TraitMethod::Provided(body_id)))
-                }
-                TraitItemKind::Type(ref bounds, ref default) => {
-                    (
-                        this.lower_generics(&i.generics),
-                        hir::TraitItemKind::Type(
-                            this.lower_bounds(bounds, ImplTraitContext::Disallowed),
-                            default.as_ref().map(|x| {
-                                this.lower_ty(x, ImplTraitContext::Disallowed)
-                            }))
+                    this.add_in_band_defs(
+                        &i.generics,
+                        trait_item_def_id,
+                        AnonymousLifetimeMode::PassThrough,
+                        |this| {
+                            hir::TraitItemKind::Method(
+                                this.lower_method_sig(sig, trait_item_def_id, false),
+                                hir::TraitMethod::Provided(body_id),
+                            )
+                        },
                     )
                 }
+                TraitItemKind::Type(ref bounds, ref default) => (
+                    this.lower_generics(&i.generics),
+                    hir::TraitItemKind::Type(
+                        this.lower_bounds(bounds, ImplTraitContext::Disallowed),
+                        default
+                            .as_ref()
+                            .map(|x| this.lower_ty(x, ImplTraitContext::Disallowed)),
+                    ),
+                ),
                 TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
             };
 
@@ -2210,11 +2528,12 @@ impl<'a> LoweringContext<'a> {
             TraitItemKind::Type(_, ref default) => {
                 (hir::AssociatedItemKind::Type, default.is_some())
             }
-            TraitItemKind::Method(ref sig, ref default) => {
-                (hir::AssociatedItemKind::Method {
+            TraitItemKind::Method(ref sig, ref default) => (
+                hir::AssociatedItemKind::Method {
                     has_self: sig.decl.has_self(),
-                 }, default.is_some())
-            }
+                },
+                default.is_some(),
+            ),
             TraitItemKind::Macro(..) => unimplemented!(),
         };
         hir::TraitItemRef {
@@ -2229,7 +2548,7 @@ impl<'a> LoweringContext<'a> {
     fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
         self.with_parent_def(i.id, |this| {
             let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id);
-            let fn_def_id = this.resolver.definitions().opt_local_def_id(node_id);
+            let impl_item_def_id = this.resolver.definitions().local_def_id(node_id);
 
             let (generics, node) = match i.node {
                 ImplItemKind::Const(ref ty, ref expr) => {
@@ -2238,8 +2557,8 @@ impl<'a> LoweringContext<'a> {
                         this.lower_generics(&i.generics),
                         hir::ImplItemKind::Const(
                             this.lower_ty(ty, ImplTraitContext::Disallowed),
-                            body_id
-                        )
+                            body_id,
+                        ),
                     )
                 }
                 ImplItemKind::Method(ref sig, ref body) => {
@@ -2249,15 +2568,25 @@ impl<'a> LoweringContext<'a> {
                     });
                     let impl_trait_return_allow = !this.is_in_trait_impl;
 
-                    this.add_in_band_defs(&i.generics, fn_def_id, |this|
-                        hir::ImplItemKind::Method(
-                            this.lower_method_sig(sig, fn_def_id, impl_trait_return_allow),
-                            body_id))
+                    this.add_in_band_defs(
+                        &i.generics,
+                        impl_item_def_id,
+                        AnonymousLifetimeMode::PassThrough,
+                        |this| {
+                            hir::ImplItemKind::Method(
+                                this.lower_method_sig(
+                                    sig,
+                                    impl_item_def_id,
+                                    impl_trait_return_allow,
+                                ),
+                                body_id,
+                            )
+                        },
+                    )
                 }
                 ImplItemKind::Type(ref ty) => (
                     this.lower_generics(&i.generics),
-                    hir::ImplItemKind::Type(
-                        this.lower_ty(ty, ImplTraitContext::Disallowed)),
+                    hir::ImplItemKind::Type(this.lower_ty(ty, ImplTraitContext::Disallowed)),
                 ),
                 ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
             };
@@ -2288,10 +2617,8 @@ impl<'a> LoweringContext<'a> {
             kind: match i.node {
                 ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
                 ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
-                ImplItemKind::Method(ref sig, _) => {
-                    hir::AssociatedItemKind::Method {
-                        has_self: sig.decl.has_self(),
-                    }
+                ImplItemKind::Method(ref sig, _) => hir::AssociatedItemKind::Method {
+                    has_self: sig.decl.has_self(),
                 },
                 ImplItemKind::Macro(..) => unimplemented!(),
             },
@@ -2322,12 +2649,10 @@ impl<'a> LoweringContext<'a> {
 
     fn lower_item_id_use_tree(&self, tree: &UseTree, vec: &mut SmallVector<hir::ItemId>) {
         match tree.kind {
-            UseTreeKind::Nested(ref nested_vec) => {
-                for &(ref nested, id) in nested_vec {
-                    vec.push(hir::ItemId { id, });
-                    self.lower_item_id_use_tree(nested, vec);
-                }
-            }
+            UseTreeKind::Nested(ref nested_vec) => for &(ref nested, id) in nested_vec {
+                vec.push(hir::ItemId { id });
+                self.lower_item_id_use_tree(nested, vec);
+            },
             UseTreeKind::Glob => {}
             UseTreeKind::Simple(..) => {}
         }
@@ -2380,25 +2705,25 @@ impl<'a> LoweringContext<'a> {
                 attrs: this.lower_attrs(&i.attrs),
                 node: match i.node {
                     ForeignItemKind::Fn(ref fdec, ref generics) => {
-                        // Disallow impl Trait in foreign items
-                        let (generics, (fn_dec, fn_args)) =
-                            this.add_in_band_defs(
-                                generics,
-                                Some(def_id),
-                                |this| (
+                        let (generics, (fn_dec, fn_args)) = this.add_in_band_defs(
+                            generics,
+                            def_id,
+                            AnonymousLifetimeMode::PassThrough,
+                            |this| {
+                                (
+                                    // Disallow impl Trait in foreign items
                                     this.lower_fn_decl(fdec, None, false),
-                                    this.lower_fn_args_to_names(fdec)
+                                    this.lower_fn_args_to_names(fdec),
                                 )
-                            );
+                            },
+                        );
 
                         hir::ForeignItemFn(fn_dec, fn_args, generics)
                     }
                     ForeignItemKind::Static(ref t, m) => {
                         hir::ForeignItemStatic(this.lower_ty(t, ImplTraitContext::Disallowed), m)
                     }
-                    ForeignItemKind::Ty => {
-                        hir::ForeignItemType
-                    }
+                    ForeignItemKind::Ty => hir::ForeignItemType,
                 },
                 vis: this.lower_visibility(&i.vis, None),
                 span: i.span,
@@ -2406,16 +2731,17 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn lower_method_sig(&mut self,
-                        sig: &MethodSig,
-                        fn_def_id: Option<DefId>,
-                        impl_trait_return_allow: bool)
-                        -> hir::MethodSig {
+    fn lower_method_sig(
+        &mut self,
+        sig: &MethodSig,
+        fn_def_id: DefId,
+        impl_trait_return_allow: bool,
+    ) -> hir::MethodSig {
         hir::MethodSig {
             abi: sig.abi,
             unsafety: self.lower_unsafety(sig.unsafety),
             constness: self.lower_constness(sig.constness),
-            decl: self.lower_fn_decl(&sig.decl, fn_def_id, impl_trait_return_allow),
+            decl: self.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow),
         }
     }
 
@@ -2483,52 +2809,67 @@ impl<'a> LoweringContext<'a> {
                     def @ None | def @ Some(Def::Local(_)) => {
                         let canonical_id = match def {
                             Some(Def::Local(id)) => id,
-                            _ => p.id
+                            _ => p.id,
                         };
-                        hir::PatKind::Binding(self.lower_binding_mode(binding_mode),
-                                                canonical_id,
-                                                respan(pth1.span, pth1.node.name),
-                                                sub.as_ref().map(|x| self.lower_pat(x)))
+                        hir::PatKind::Binding(
+                            self.lower_binding_mode(binding_mode),
+                            canonical_id,
+                            respan(pth1.span, pth1.node.name),
+                            sub.as_ref().map(|x| self.lower_pat(x)),
+                        )
                     }
-                    Some(def) => {
-                        hir::PatKind::Path(hir::QPath::Resolved(None, P(hir::Path {
+                    Some(def) => hir::PatKind::Path(hir::QPath::Resolved(
+                        None,
+                        P(hir::Path {
                             span: pth1.span,
                             def,
-                            segments: hir_vec![
-                                hir::PathSegment::from_name(pth1.node.name)
-                            ],
-                        })))
-                    }
+                            segments: hir_vec![hir::PathSegment::from_name(pth1.node.name)],
+                        }),
+                    )),
                 }
             }
             PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
             PatKind::TupleStruct(ref path, ref pats, ddpos) => {
-                let qpath = self.lower_qpath(p.id, &None, path, ParamMode::Optional,
-                                                ImplTraitContext::Disallowed);
-                hir::PatKind::TupleStruct(qpath,
-                                            pats.iter().map(|x| self.lower_pat(x)).collect(),
-                                            ddpos)
-            }
-            PatKind::Path(ref qself, ref path) => {
-                hir::PatKind::Path(self.lower_qpath(p.id, qself, path, ParamMode::Optional,
-                                                    ImplTraitContext::Disallowed))
+                let qpath = self.lower_qpath(
+                    p.id,
+                    &None,
+                    path,
+                    ParamMode::Optional,
+                    ImplTraitContext::Disallowed,
+                );
+                hir::PatKind::TupleStruct(
+                    qpath,
+                    pats.iter().map(|x| self.lower_pat(x)).collect(),
+                    ddpos,
+                )
             }
+            PatKind::Path(ref qself, ref path) => hir::PatKind::Path(self.lower_qpath(
+                p.id,
+                qself,
+                path,
+                ParamMode::Optional,
+                ImplTraitContext::Disallowed,
+            )),
             PatKind::Struct(ref path, ref fields, etc) => {
-                let qpath = self.lower_qpath(p.id, &None, path, ParamMode::Optional,
-                                                ImplTraitContext::Disallowed);
-
-                let fs = fields.iter()
-                                .map(|f| {
-                                    Spanned {
-                                        span: f.span,
-                                        node: hir::FieldPat {
-                                            name: self.lower_ident(f.node.ident),
-                                            pat: self.lower_pat(&f.node.pat),
-                                            is_shorthand: f.node.is_shorthand,
-                                        },
-                                    }
-                                })
-                                .collect();
+                let qpath = self.lower_qpath(
+                    p.id,
+                    &None,
+                    path,
+                    ParamMode::Optional,
+                    ImplTraitContext::Disallowed,
+                );
+
+                let fs = fields
+                    .iter()
+                    .map(|f| Spanned {
+                        span: f.span,
+                        node: hir::FieldPat {
+                            name: self.lower_ident(f.node.ident),
+                            pat: self.lower_pat(&f.node.pat),
+                            is_shorthand: f.node.is_shorthand,
+                        },
+                    })
+                    .collect();
                 hir::PatKind::Struct(qpath, fs, etc)
             }
             PatKind::Tuple(ref elts, ddpos) => {
@@ -2538,16 +2879,16 @@ impl<'a> LoweringContext<'a> {
             PatKind::Ref(ref inner, mutbl) => {
                 hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
             }
-            PatKind::Range(ref e1, ref e2, ref end) => {
-                hir::PatKind::Range(P(self.lower_expr(e1)),
-                                    P(self.lower_expr(e2)),
-                                    self.lower_range_end(end))
-            }
-            PatKind::Slice(ref before, ref slice, ref after) => {
-                hir::PatKind::Slice(before.iter().map(|x| self.lower_pat(x)).collect(),
-                            slice.as_ref().map(|x| self.lower_pat(x)),
-                            after.iter().map(|x| self.lower_pat(x)).collect())
-            }
+            PatKind::Range(ref e1, ref e2, ref end) => hir::PatKind::Range(
+                P(self.lower_expr(e1)),
+                P(self.lower_expr(e2)),
+                self.lower_range_end(end),
+            ),
+            PatKind::Slice(ref before, ref slice, ref after) => hir::PatKind::Slice(
+                before.iter().map(|x| self.lower_pat(x)).collect(),
+                slice.as_ref().map(|x| self.lower_pat(x)),
+                after.iter().map(|x| self.lower_pat(x)).collect(),
+            ),
             PatKind::Paren(ref inner) => return self.lower_pat(inner),
             PatKind::Mac(_) => panic!("Shouldn't exist here"),
         };
@@ -2586,9 +2927,7 @@ impl<'a> LoweringContext<'a> {
             // }
             //
             // But for now there are type-inference issues doing that.
-            ExprKind::Box(ref inner) => {
-                hir::ExprBox(P(self.lower_expr(inner)))
-            }
+            ExprKind::Box(ref inner) => hir::ExprBox(P(self.lower_expr(inner))),
 
             // Desugar ExprBox: `in (PLACE) EXPR`
             ExprKind::InPlace(ref placer, ref value_expr) => {
@@ -2629,9 +2968,7 @@ impl<'a> LoweringContext<'a> {
                 };
 
                 // let placer = <placer_expr> ;
-                let (s1, placer_binding) = {
-                    mk_stmt_let(self, placer_ident, placer_expr)
-                };
+                let (s1, placer_binding) = { mk_stmt_let(self, placer_ident, placer_expr) };
 
                 // let mut place = Placer::make_place(placer);
                 let (s2, place_binding) = {
@@ -2650,11 +2987,13 @@ impl<'a> LoweringContext<'a> {
 
                 // pop_unsafe!(EXPR));
                 let pop_unsafe_expr = {
-                    self.signal_block_expr(hir_vec![],
-                                           value_expr,
-                                           e.span,
-                                           hir::PopUnsafeBlock(hir::CompilerGenerated),
-                                           ThinVec::new())
+                    self.signal_block_expr(
+                        hir_vec![],
+                        value_expr,
+                        e.span,
+                        hir::PopUnsafeBlock(hir::CompilerGenerated),
+                        ThinVec::new(),
+                    )
                 };
 
                 // push_unsafe!({
@@ -2663,19 +3002,21 @@ impl<'a> LoweringContext<'a> {
                 // })
                 let expr = {
                     let ptr = self.expr_ident(e.span, p_ptr_ident, p_ptr_binding);
-                    let call_move_val_init =
-                        hir::StmtSemi(
-                            make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
-                            self.next_id().node_id);
+                    let call_move_val_init = hir::StmtSemi(
+                        make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
+                        self.next_id().node_id,
+                    );
                     let call_move_val_init = respan(e.span, call_move_val_init);
 
                     let place = self.expr_ident(e.span, place_ident, place_binding);
                     let call = make_call(self, &inplace_finalize, hir_vec![place]);
-                    P(self.signal_block_expr(hir_vec![call_move_val_init],
-                                             call,
-                                             e.span,
-                                             hir::PushUnsafeBlock(hir::CompilerGenerated),
-                                             ThinVec::new()))
+                    P(self.signal_block_expr(
+                        hir_vec![call_move_val_init],
+                        call,
+                        e.span,
+                        hir::PushUnsafeBlock(hir::CompilerGenerated),
+                        ThinVec::new(),
+                    ))
                 };
 
                 let block = self.block_all(e.span, hir_vec![s1, s2, s3], Some(expr));
@@ -2698,9 +3039,14 @@ impl<'a> LoweringContext<'a> {
                 hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect())
             }
             ExprKind::MethodCall(ref seg, ref args) => {
-                let hir_seg = self.lower_path_segment(e.span, seg, ParamMode::Optional, 0,
-                                                      ParenthesizedGenericArgs::Err,
-                                                      ImplTraitContext::Disallowed);
+                let hir_seg = self.lower_path_segment(
+                    e.span,
+                    seg,
+                    ParamMode::Optional,
+                    0,
+                    ParenthesizedGenericArgs::Err,
+                    ImplTraitContext::Disallowed,
+                );
                 let args = args.iter().map(|x| self.lower_expr(x)).collect();
                 hir::ExprMethodCall(hir_seg, seg.span, args)
             }
@@ -2738,10 +3084,7 @@ impl<'a> LoweringContext<'a> {
                             // wrap the if-let expr in a block
                             let span = els.span;
                             let els = P(self.lower_expr(els));
-                            let LoweredNodeId {
-                                node_id,
-                                hir_id,
-                            } = self.next_id();
+                            let LoweredNodeId { node_id, hir_id } = self.next_id();
                             let blk = P(hir::Block {
                                 stmts: hir_vec![],
                                 expr: Some(els),
@@ -2763,28 +3106,28 @@ impl<'a> LoweringContext<'a> {
 
                 hir::ExprIf(P(self.lower_expr(cond)), P(then_expr), else_opt)
             }
-            ExprKind::While(ref cond, ref body, opt_label) => {
-                self.with_loop_scope(e.id, |this|
-                    hir::ExprWhile(
-                        this.with_loop_condition_scope(|this| P(this.lower_expr(cond))),
-                        this.lower_block(body, false),
-                        this.lower_label(opt_label)))
-            }
-            ExprKind::Loop(ref body, opt_label) => {
-                self.with_loop_scope(e.id, |this|
-                    hir::ExprLoop(this.lower_block(body, false),
-                                  this.lower_label(opt_label),
-                                  hir::LoopSource::Loop))
-            }
+            ExprKind::While(ref cond, ref body, opt_label) => self.with_loop_scope(e.id, |this| {
+                hir::ExprWhile(
+                    this.with_loop_condition_scope(|this| P(this.lower_expr(cond))),
+                    this.lower_block(body, false),
+                    this.lower_label(opt_label),
+                )
+            }),
+            ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| {
+                hir::ExprLoop(
+                    this.lower_block(body, false),
+                    this.lower_label(opt_label),
+                    hir::LoopSource::Loop,
+                )
+            }),
             ExprKind::Catch(ref body) => {
-                self.with_catch_scope(body.id, |this|
-                    hir::ExprBlock(this.lower_block(body, true)))
-            }
-            ExprKind::Match(ref expr, ref arms) => {
-                hir::ExprMatch(P(self.lower_expr(expr)),
-                               arms.iter().map(|x| self.lower_arm(x)).collect(),
-                               hir::MatchSource::Normal)
+                self.with_catch_scope(body.id, |this| hir::ExprBlock(this.lower_block(body, true)))
             }
+            ExprKind::Match(ref expr, ref arms) => hir::ExprMatch(
+                P(self.lower_expr(expr)),
+                arms.iter().map(|x| self.lower_arm(x)).collect(),
+                hir::MatchSource::Normal,
+            ),
             ExprKind::Closure(capture_clause, movability, ref decl, ref body, fn_decl_span) => {
                 self.with_new_scopes(|this| {
                     this.with_parent_def(e.id, |this| {
@@ -2796,8 +3139,12 @@ impl<'a> LoweringContext<'a> {
                         });
                         let generator_option = if is_generator {
                             if !decl.inputs.is_empty() {
-                                span_err!(this.sess, fn_decl_span, E0628,
-                                        "generators cannot have explicit arguments");
+                                span_err!(
+                                    this.sess,
+                                    fn_decl_span,
+                                    E0628,
+                                    "generators cannot have explicit arguments"
+                                );
                                 this.sess.abort_if_errors();
                             }
                             Some(match movability {
@@ -2806,16 +3153,22 @@ impl<'a> LoweringContext<'a> {
                             })
                         } else {
                             if movability == Movability::Static {
-                                span_err!(this.sess, fn_decl_span, E0906,
-                                        "closures cannot be static");
+                                span_err!(
+                                    this.sess,
+                                    fn_decl_span,
+                                    E0906,
+                                    "closures cannot be static"
+                                );
                             }
                             None
                         };
-                        hir::ExprClosure(this.lower_capture_clause(capture_clause),
-                                         this.lower_fn_decl(decl, None, false),
-                                         body_id,
-                                         fn_decl_span,
-                                         generator_option)
+                        hir::ExprClosure(
+                            this.lower_capture_clause(capture_clause),
+                            this.lower_fn_decl(decl, None, false),
+                            body_id,
+                            fn_decl_span,
+                            generator_option,
+                        )
                     })
                 })
             }
@@ -2823,18 +3176,16 @@ impl<'a> LoweringContext<'a> {
             ExprKind::Assign(ref el, ref er) => {
                 hir::ExprAssign(P(self.lower_expr(el)), P(self.lower_expr(er)))
             }
-            ExprKind::AssignOp(op, ref el, ref er) => {
-                hir::ExprAssignOp(self.lower_binop(op),
-                                  P(self.lower_expr(el)),
-                                  P(self.lower_expr(er)))
-            }
-            ExprKind::Field(ref el, ident) => {
-                hir::ExprField(P(self.lower_expr(el)),
-                               respan(ident.span, self.lower_ident(ident.node)))
-            }
-            ExprKind::TupField(ref el, ident) => {
-                hir::ExprTupField(P(self.lower_expr(el)), ident)
-            }
+            ExprKind::AssignOp(op, ref el, ref er) => hir::ExprAssignOp(
+                self.lower_binop(op),
+                P(self.lower_expr(el)),
+                P(self.lower_expr(er)),
+            ),
+            ExprKind::Field(ref el, ident) => hir::ExprField(
+                P(self.lower_expr(el)),
+                respan(ident.span, self.lower_ident(ident.node)),
+            ),
+            ExprKind::TupField(ref el, ident) => hir::ExprTupField(P(self.lower_expr(el)), ident),
             ExprKind::Index(ref el, ref er) => {
                 hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er)))
             }
@@ -2848,25 +3199,27 @@ impl<'a> LoweringContext<'a> {
                     (&Some(..), &Some(..), HalfOpen) => "Range",
                     (&None, &Some(..), Closed) => "RangeToInclusive",
                     (&Some(..), &Some(..), Closed) => "RangeInclusive",
-                    (_, &None, Closed) =>
-                        self.diagnostic().span_fatal(
-                            e.span, "inclusive range with no end").raise(),
+                    (_, &None, Closed) => self.diagnostic()
+                        .span_fatal(e.span, "inclusive range with no end")
+                        .raise(),
                 };
 
-                let fields =
-                    e1.iter().map(|e| ("start", e)).chain(e2.iter().map(|e| ("end", e)))
+                let fields = e1.iter()
+                    .map(|e| ("start", e))
+                    .chain(e2.iter().map(|e| ("end", e)))
                     .map(|(s, e)| {
                         let expr = P(self.lower_expr(&e));
                         let unstable_span =
                             self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
                         self.field(Symbol::intern(s), expr, unstable_span)
-                    }).collect::<P<[hir::Field]>>();
+                    })
+                    .collect::<P<[hir::Field]>>();
 
                 let is_unit = fields.is_empty();
                 let unstable_span =
                     self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
-                let struct_path =
-                    iter::once("ops").chain(iter::once(path))
+                let struct_path = iter::once("ops")
+                    .chain(iter::once(path))
                     .collect::<Vec<_>>();
                 let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
                 let struct_path = hir::QPath::Resolved(None, P(struct_path));
@@ -2885,46 +3238,53 @@ impl<'a> LoweringContext<'a> {
                     attrs: e.attrs.clone(),
                 };
             }
-            ExprKind::Path(ref qself, ref path) => {
-                hir::ExprPath(self.lower_qpath(e.id, qself, path, ParamMode::Optional,
-                                               ImplTraitContext::Disallowed))
-            }
+            ExprKind::Path(ref qself, ref path) => hir::ExprPath(self.lower_qpath(
+                e.id,
+                qself,
+                path,
+                ParamMode::Optional,
+                ImplTraitContext::Disallowed,
+            )),
             ExprKind::Break(opt_label, ref opt_expr) => {
                 let destination = if self.is_in_loop_condition && opt_label.is_none() {
                     hir::Destination {
                         label: None,
                         target_id: hir::ScopeTarget::Loop(
-                                Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into()),
+                            Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
+                        ),
                     }
                 } else {
                     self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
                 };
                 hir::ExprBreak(
-                        destination,
-                        opt_expr.as_ref().map(|x| P(self.lower_expr(x))))
-            }
-            ExprKind::Continue(opt_label) =>
-                hir::ExprAgain(
-                    if self.is_in_loop_condition && opt_label.is_none() {
-                        hir::Destination {
-                            label: None,
-                            target_id: hir::ScopeTarget::Loop(Err(
-                                hir::LoopIdError::UnlabeledCfInWhileCondition).into()),
-                        }
-                    } else {
-                        self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
-                    }),
+                    destination,
+                    opt_expr.as_ref().map(|x| P(self.lower_expr(x))),
+                )
+            }
+            ExprKind::Continue(opt_label) => {
+                hir::ExprAgain(if self.is_in_loop_condition && opt_label.is_none() {
+                    hir::Destination {
+                        label: None,
+                        target_id: hir::ScopeTarget::Loop(
+                            Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
+                        ),
+                    }
+                } else {
+                    self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
+                })
+            }
             ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| P(self.lower_expr(x)))),
             ExprKind::InlineAsm(ref asm) => {
                 let hir_asm = hir::InlineAsm {
                     inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
-                    outputs: asm.outputs.iter().map(|out| {
-                        hir::InlineAsmOutput {
+                    outputs: asm.outputs
+                        .iter()
+                        .map(|out| hir::InlineAsmOutput {
                             constraint: out.constraint.clone(),
                             is_rw: out.is_rw,
                             is_indirect: out.is_indirect,
-                        }
-                    }).collect(),
+                        })
+                        .collect(),
                     asm: asm.asm.clone(),
                     asm_str_style: asm.asm_str_style,
                     clobbers: asm.clobbers.clone().into(),
@@ -2933,18 +3293,27 @@ impl<'a> LoweringContext<'a> {
                     dialect: asm.dialect,
                     ctxt: asm.ctxt,
                 };
-                let outputs =
-                    asm.outputs.iter().map(|out| self.lower_expr(&out.expr)).collect();
-                let inputs =
-                    asm.inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect();
+                let outputs = asm.outputs
+                    .iter()
+                    .map(|out| self.lower_expr(&out.expr))
+                    .collect();
+                let inputs = asm.inputs
+                    .iter()
+                    .map(|&(_, ref input)| self.lower_expr(input))
+                    .collect();
                 hir::ExprInlineAsm(P(hir_asm), outputs, inputs)
             }
-            ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
-                hir::ExprStruct(self.lower_qpath(e.id, &None, path, ParamMode::Optional,
-                                                 ImplTraitContext::Disallowed),
-                                fields.iter().map(|x| self.lower_field(x)).collect(),
-                                maybe_expr.as_ref().map(|x| P(self.lower_expr(x))))
-            }
+            ExprKind::Struct(ref path, ref fields, ref maybe_expr) => hir::ExprStruct(
+                self.lower_qpath(
+                    e.id,
+                    &None,
+                    path,
+                    ParamMode::Optional,
+                    ImplTraitContext::Disallowed,
+                ),
+                fields.iter().map(|x| self.lower_field(x)).collect(),
+                maybe_expr.as_ref().map(|x| P(self.lower_expr(x))),
+            ),
             ExprKind::Paren(ref ex) => {
                 let mut ex = self.lower_expr(ex);
                 // include parens in span, but only if it is a super-span.
@@ -2960,9 +3329,10 @@ impl<'a> LoweringContext<'a> {
 
             ExprKind::Yield(ref opt_expr) => {
                 self.is_generator = true;
-                let expr = opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| {
-                    self.expr(e.span, hir::ExprTup(hir_vec![]), ThinVec::new())
-                });
+                let expr = opt_expr
+                    .as_ref()
+                    .map(|x| self.lower_expr(x))
+                    .unwrap_or_else(|| self.expr(e.span, hir::ExprTup(hir_vec![]), ThinVec::new()));
                 hir::ExprYield(P(expr))
             }
 
@@ -3007,7 +3377,8 @@ impl<'a> LoweringContext<'a> {
                     arms.into(),
                     hir::MatchSource::IfLetDesugar {
                         contains_else_clause,
-                    })
+                    },
+                )
             }
 
             // Desugar ExprWhileLet
@@ -3024,11 +3395,13 @@ impl<'a> LoweringContext<'a> {
 
                 // Note that the block AND the condition are evaluated in the loop scope.
                 // This is done to allow `break` from inside the condition of the loop.
-                let (body, break_expr, sub_expr) = self.with_loop_scope(e.id, |this| (
-                    this.lower_block(body, false),
-                    this.expr_break(e.span, ThinVec::new()),
-                    this.with_loop_condition_scope(|this| P(this.lower_expr(sub_expr))),
-                ));
+                let (body, break_expr, sub_expr) = self.with_loop_scope(e.id, |this| {
+                    (
+                        this.lower_block(body, false),
+                        this.expr_break(e.span, ThinVec::new()),
+                        this.with_loop_condition_scope(|this| P(this.lower_expr(sub_expr))),
+                    )
+                });
 
                 // `<pat> => <body>`
                 let pat_arm = {
@@ -3045,16 +3418,19 @@ impl<'a> LoweringContext<'a> {
 
                 // `match <sub_expr> { ... }`
                 let arms = hir_vec![pat_arm, break_arm];
-                let match_expr = self.expr(sub_expr.span,
-                                           hir::ExprMatch(sub_expr,
-                                                          arms,
-                                                          hir::MatchSource::WhileLetDesugar),
-                                           ThinVec::new());
+                let match_expr = self.expr(
+                    sub_expr.span,
+                    hir::ExprMatch(sub_expr, arms, hir::MatchSource::WhileLetDesugar),
+                    ThinVec::new(),
+                );
 
                 // `[opt_ident]: loop { ... }`
                 let loop_block = P(self.block_expr(P(match_expr)));
-                let loop_expr = hir::ExprLoop(loop_block, self.lower_label(opt_label),
-                                              hir::LoopSource::WhileLet);
+                let loop_expr = hir::ExprLoop(
+                    loop_block,
+                    self.lower_label(opt_label),
+                    hir::LoopSource::WhileLet,
+                );
                 // add attributes to the outer returned expr node
                 loop_expr
             }
@@ -3088,9 +3464,11 @@ impl<'a> LoweringContext<'a> {
                 let iter = self.str_to_ident("iter");
 
                 let next_ident = self.str_to_ident("__next");
-                let next_pat = self.pat_ident_binding_mode(pat.span,
-                                                           next_ident,
-                                                           hir::BindingAnnotation::Mutable);
+                let next_pat = self.pat_ident_binding_mode(
+                    pat.span,
+                    next_ident,
+                    hir::BindingAnnotation::Mutable,
+                );
 
                 // `::std::option::Option::Some(val) => next = val`
                 let pat_arm = {
@@ -3098,25 +3476,26 @@ impl<'a> LoweringContext<'a> {
                     let val_pat = self.pat_ident(pat.span, val_ident);
                     let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat.id));
                     let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat.id));
-                    let assign = P(self.expr(pat.span,
-                                             hir::ExprAssign(next_expr, val_expr),
-                                             ThinVec::new()));
+                    let assign = P(self.expr(
+                        pat.span,
+                        hir::ExprAssign(next_expr, val_expr),
+                        ThinVec::new(),
+                    ));
                     let some_pat = self.pat_some(pat.span, val_pat);
                     self.arm(hir_vec![some_pat], assign)
                 };
 
                 // `::std::option::Option::None => break`
                 let break_arm = {
-                    let break_expr = self.with_loop_scope(e.id, |this|
-                        this.expr_break(e.span, ThinVec::new()));
+                    let break_expr =
+                        self.with_loop_scope(e.id, |this| this.expr_break(e.span, ThinVec::new()));
                     let pat = self.pat_none(e.span);
                     self.arm(hir_vec![pat], break_expr)
                 };
 
                 // `mut iter`
-                let iter_pat = self.pat_ident_binding_mode(head_sp,
-                                                           iter,
-                                                           hir::BindingAnnotation::Mutable);
+                let iter_pat =
+                    self.pat_ident_binding_mode(head_sp, iter, hir::BindingAnnotation::Mutable);
 
                 // `match ::std::iter::Iterator::next(&mut iter) { ... }`
                 let match_expr = {
@@ -3124,46 +3503,48 @@ impl<'a> LoweringContext<'a> {
                     let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
                     let next_path = &["iter", "Iterator", "next"];
                     let next_path = P(self.expr_std_path(head_sp, next_path, ThinVec::new()));
-                    let next_expr = P(self.expr_call(head_sp, next_path,
-                                      hir_vec![ref_mut_iter]));
+                    let next_expr = P(self.expr_call(head_sp, next_path, hir_vec![ref_mut_iter]));
                     let arms = hir_vec![pat_arm, break_arm];
 
-                    P(self.expr(head_sp,
-                                hir::ExprMatch(next_expr, arms,
-                                               hir::MatchSource::ForLoopDesugar),
-                                ThinVec::new()))
+                    P(self.expr(
+                        head_sp,
+                        hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar),
+                        ThinVec::new(),
+                    ))
                 };
                 let match_stmt = respan(head_sp, hir::StmtExpr(match_expr, self.next_id().node_id));
 
                 let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id));
 
                 // `let mut __next`
-                let next_let = self.stmt_let_pat(head_sp,
-                    None,
-                    next_pat,
-                    hir::LocalSource::ForLoopDesugar);
+                let next_let =
+                    self.stmt_let_pat(head_sp, None, next_pat, hir::LocalSource::ForLoopDesugar);
 
                 // `let <pat> = __next`
                 let pat = self.lower_pat(pat);
-                let pat_let = self.stmt_let_pat(head_sp,
+                let pat_let = self.stmt_let_pat(
+                    head_sp,
                     Some(next_expr),
                     pat,
-                    hir::LocalSource::ForLoopDesugar);
+                    hir::LocalSource::ForLoopDesugar,
+                );
 
                 let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
                 let body_expr = P(self.expr_block(body_block, ThinVec::new()));
                 let body_stmt = respan(body.span, hir::StmtExpr(body_expr, self.next_id().node_id));
 
-                let loop_block = P(self.block_all(e.span,
-                                                  hir_vec![next_let,
-                                                           match_stmt,
-                                                           pat_let,
-                                                           body_stmt],
-                                                  None));
+                let loop_block = P(self.block_all(
+                    e.span,
+                    hir_vec![next_let, match_stmt, pat_let, body_stmt],
+                    None,
+                ));
 
                 // `[opt_ident]: loop { ... }`
-                let loop_expr = hir::ExprLoop(loop_block, self.lower_label(opt_label),
-                                              hir::LoopSource::ForLoop);
+                let loop_expr = hir::ExprLoop(
+                    loop_block,
+                    self.lower_label(opt_label),
+                    hir::LoopSource::ForLoop,
+                );
                 let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
                 let loop_expr = P(hir::Expr {
                     id: node_id,
@@ -3179,15 +3560,16 @@ impl<'a> LoweringContext<'a> {
                 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
                 let into_iter_expr = {
                     let into_iter_path = &["iter", "IntoIterator", "into_iter"];
-                    let into_iter = P(self.expr_std_path(head_sp, into_iter_path,
-                                                         ThinVec::new()));
+                    let into_iter = P(self.expr_std_path(head_sp, into_iter_path, ThinVec::new()));
                     P(self.expr_call(head_sp, into_iter, hir_vec![head]))
                 };
 
-                let match_expr = P(self.expr_match(head_sp,
-                                                   into_iter_expr,
-                                                   hir_vec![iter_arm],
-                                                   hir::MatchSource::ForLoopDesugar));
+                let match_expr = P(self.expr_match(
+                    head_sp,
+                    into_iter_expr,
+                    hir_vec![iter_arm],
+                    hir::MatchSource::ForLoopDesugar,
+                ));
 
                 // `{ let _result = ...; _result }`
                 // underscore prevents an unused_variables lint if the head diverges
@@ -3247,10 +3629,12 @@ impl<'a> LoweringContext<'a> {
                 let ok_arm = {
                     let val_ident = self.str_to_ident("val");
                     let val_pat = self.pat_ident(e.span, val_ident);
-                    let val_expr = P(self.expr_ident_with_attrs(e.span,
-                                                                val_ident,
-                                                                val_pat.id,
-                                                                ThinVec::from(attrs.clone())));
+                    let val_expr = P(self.expr_ident_with_attrs(
+                        e.span,
+                        val_ident,
+                        val_pat.id,
+                        ThinVec::from(attrs.clone()),
+                    ));
                     let ok_pat = self.pat_ok(e.span, val_pat);
 
                     self.arm(hir_vec![ok_pat], val_expr)
@@ -3270,8 +3654,7 @@ impl<'a> LoweringContext<'a> {
                     };
                     let from_err_expr = {
                         let path = &["ops", "Try", "from_error"];
-                        let from_err = P(self.expr_std_path(unstable_span, path,
-                                                            ThinVec::new()));
+                        let from_err = P(self.expr_std_path(unstable_span, path, ThinVec::new()));
                         P(self.expr_call(e.span, from_err, hir_vec![from_expr]))
                     };
 
@@ -3285,23 +3668,23 @@ impl<'a> LoweringContext<'a> {
                                     label: None,
                                     target_id: hir::ScopeTarget::Block(catch_node),
                                 },
-                                Some(from_err_expr)
+                                Some(from_err_expr),
                             ),
-                            thin_attrs))
+                            thin_attrs,
+                        ))
                     } else {
-                        P(self.expr(e.span,
-                                    hir::Expr_::ExprRet(Some(from_err_expr)),
-                                    thin_attrs))
+                        P(self.expr(e.span, hir::Expr_::ExprRet(Some(from_err_expr)), thin_attrs))
                     };
 
-
                     let err_pat = self.pat_err(e.span, err_local);
                     self.arm(hir_vec![err_pat], ret_expr)
                 };
 
-                hir::ExprMatch(discr,
-                               hir_vec![err_arm, ok_arm],
-                               hir::MatchSource::TryDesugar)
+                hir::ExprMatch(
+                    discr,
+                    hir_vec![err_arm, ok_arm],
+                    hir::MatchSource::TryDesugar,
+                )
             }
 
             ExprKind::Mac(_) => panic!("Shouldn't exist here"),
@@ -3321,39 +3704,42 @@ impl<'a> LoweringContext<'a> {
     fn lower_stmt(&mut self, s: &Stmt) -> SmallVector<hir::Stmt> {
         SmallVector::one(match s.node {
             StmtKind::Local(ref l) => Spanned {
-                node: hir::StmtDecl(P(Spanned {
-                    node: hir::DeclLocal(self.lower_local(l)),
-                    span: s.span,
-                }), self.lower_node_id(s.id).node_id),
+                node: hir::StmtDecl(
+                    P(Spanned {
+                        node: hir::DeclLocal(self.lower_local(l)),
+                        span: s.span,
+                    }),
+                    self.lower_node_id(s.id).node_id,
+                ),
                 span: s.span,
             },
             StmtKind::Item(ref it) => {
                 // Can only use the ID once.
                 let mut id = Some(s.id);
-                return self.lower_item_id(it).into_iter().map(|item_id| Spanned {
-                    node: hir::StmtDecl(P(Spanned {
-                        node: hir::DeclItem(item_id),
+                return self.lower_item_id(it)
+                    .into_iter()
+                    .map(|item_id| Spanned {
+                        node: hir::StmtDecl(
+                            P(Spanned {
+                                node: hir::DeclItem(item_id),
+                                span: s.span,
+                            }),
+                            id.take()
+                                .map(|id| self.lower_node_id(id).node_id)
+                                .unwrap_or_else(|| self.next_id().node_id),
+                        ),
                         span: s.span,
-                    }), id.take()
-                          .map(|id| self.lower_node_id(id).node_id)
-                          .unwrap_or_else(|| self.next_id().node_id)),
-                    span: s.span,
-                }).collect();
-            }
-            StmtKind::Expr(ref e) => {
-                Spanned {
-                    node: hir::StmtExpr(P(self.lower_expr(e)),
-                                          self.lower_node_id(s.id).node_id),
-                    span: s.span,
-                }
-            }
-            StmtKind::Semi(ref e) => {
-                Spanned {
-                    node: hir::StmtSemi(P(self.lower_expr(e)),
-                                          self.lower_node_id(s.id).node_id),
-                    span: s.span,
-                }
+                    })
+                    .collect();
             }
+            StmtKind::Expr(ref e) => Spanned {
+                node: hir::StmtExpr(P(self.lower_expr(e)), self.lower_node_id(s.id).node_id),
+                span: s.span,
+            },
+            StmtKind::Semi(ref e) => Spanned {
+                node: hir::StmtSemi(P(self.lower_expr(e)), self.lower_node_id(s.id).node_id),
+                span: s.span,
+            },
             StmtKind::Mac(..) => panic!("Shouldn't exist here"),
         })
     }
@@ -3370,30 +3756,31 @@ impl<'a> LoweringContext<'a> {
     /// lowered. This can happen during `lower_impl_item_ref()` where we need to
     /// lower a `Visibility` value although we haven't lowered the owning
     /// `ImplItem` in question yet.
-    fn lower_visibility(&mut self,
-                        v: &Visibility,
-                        explicit_owner: Option<NodeId>)
-                        -> hir::Visibility {
+    fn lower_visibility(
+        &mut self,
+        v: &Visibility,
+        explicit_owner: Option<NodeId>,
+    ) -> hir::Visibility {
         match v.node {
             VisibilityKind::Public => hir::Public,
             VisibilityKind::Crate(..) => hir::Visibility::Crate,
-            VisibilityKind::Restricted { ref path, id, .. } => {
-                hir::Visibility::Restricted {
-                    path: P(self.lower_path(id, path, ParamMode::Explicit, true)),
-                    id: if let Some(owner) = explicit_owner {
-                        self.lower_node_id_with_owner(id, owner).node_id
-                    } else {
-                        self.lower_node_id(id).node_id
-                    }
-                }
-            }
+            VisibilityKind::Restricted { ref path, id, .. } => hir::Visibility::Restricted {
+                path: P(self.lower_path(id, path, ParamMode::Explicit)),
+                id: if let Some(owner) = explicit_owner {
+                    self.lower_node_id_with_owner(id, owner).node_id
+                } else {
+                    self.lower_node_id(id).node_id
+                },
+            },
             VisibilityKind::Inherited => hir::Inherited,
         }
     }
 
     fn lower_defaultness(&mut self, d: Defaultness, has_value: bool) -> hir::Defaultness {
         match d {
-            Defaultness::Default => hir::Defaultness::Default { has_value: has_value },
+            Defaultness::Default => hir::Defaultness::Default {
+                has_value: has_value,
+            },
             Defaultness::Final => {
                 assert!(has_value);
                 hir::Defaultness::Final
@@ -3410,8 +3797,7 @@ impl<'a> LoweringContext<'a> {
 
     fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingAnnotation {
         match *b {
-            BindingMode::ByValue(Mutability::Immutable) =>
-                hir::BindingAnnotation::Unannotated,
+            BindingMode::ByValue(Mutability::Immutable) => hir::BindingAnnotation::Unannotated,
             BindingMode::ByRef(Mutability::Immutable) => hir::BindingAnnotation::Ref,
             BindingMode::ByValue(Mutability::Mutable) => hir::BindingAnnotation::Mutable,
             BindingMode::ByRef(Mutability::Mutable) => hir::BindingAnnotation::RefMut,
@@ -3452,10 +3838,7 @@ impl<'a> LoweringContext<'a> {
 
     fn field(&mut self, name: Name, expr: P<hir::Expr>, span: Span) -> hir::Field {
         hir::Field {
-            name: Spanned {
-                node: name,
-                span,
-            },
+            name: Spanned { node: name, span },
             span,
             expr,
             is_shorthand: false,
@@ -3467,8 +3850,12 @@ impl<'a> LoweringContext<'a> {
         P(self.expr(span, expr_break, attrs))
     }
 
-    fn expr_call(&mut self, span: Span, e: P<hir::Expr>, args: hir::HirVec<hir::Expr>)
-                 -> hir::Expr {
+    fn expr_call(
+        &mut self,
+        span: Span,
+        e: P<hir::Expr>,
+        args: hir::HirVec<hir::Expr>,
+    ) -> hir::Expr {
         self.expr(span, hir::ExprCall(e, args), ThinVec::new())
     }
 
@@ -3476,15 +3863,21 @@ impl<'a> LoweringContext<'a> {
         self.expr_ident_with_attrs(span, id, binding, ThinVec::new())
     }
 
-    fn expr_ident_with_attrs(&mut self, span: Span,
-                                        id: Name,
-                                        binding: NodeId,
-                                        attrs: ThinVec<Attribute>) -> hir::Expr {
-        let expr_path = hir::ExprPath(hir::QPath::Resolved(None, P(hir::Path {
-            span,
-            def: Def::Local(binding),
-            segments: hir_vec![hir::PathSegment::from_name(id)],
-        })));
+    fn expr_ident_with_attrs(
+        &mut self,
+        span: Span,
+        id: Name,
+        binding: NodeId,
+        attrs: ThinVec<Attribute>,
+    ) -> hir::Expr {
+        let expr_path = hir::ExprPath(hir::QPath::Resolved(
+            None,
+            P(hir::Path {
+                span,
+                def: Def::Local(binding),
+                segments: hir_vec![hir::PathSegment::from_name(id)],
+            }),
+        ));
 
         self.expr(span, expr_path, attrs)
     }
@@ -3493,21 +3886,27 @@ impl<'a> LoweringContext<'a> {
         self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), ThinVec::new())
     }
 
-    fn expr_std_path(&mut self,
-                     span: Span,
-                     components: &[&str],
-                     attrs: ThinVec<Attribute>)
-                     -> hir::Expr {
+    fn expr_std_path(
+        &mut self,
+        span: Span,
+        components: &[&str],
+        attrs: ThinVec<Attribute>,
+    ) -> hir::Expr {
         let path = self.std_path(span, components, true);
-        self.expr(span, hir::ExprPath(hir::QPath::Resolved(None, P(path))), attrs)
+        self.expr(
+            span,
+            hir::ExprPath(hir::QPath::Resolved(None, P(path))),
+            attrs,
+        )
     }
 
-    fn expr_match(&mut self,
-                  span: Span,
-                  arg: P<hir::Expr>,
-                  arms: hir::HirVec<hir::Arm>,
-                  source: hir::MatchSource)
-                  -> hir::Expr {
+    fn expr_match(
+        &mut self,
+        span: Span,
+        arg: P<hir::Expr>,
+        arms: hir::HirVec<hir::Arm>,
+        source: hir::MatchSource,
+    ) -> hir::Expr {
         self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new())
     }
 
@@ -3530,12 +3929,13 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn stmt_let_pat(&mut self,
-                    sp: Span,
-                    ex: Option<P<hir::Expr>>,
-                    pat: P<hir::Pat>,
-                    source: hir::LocalSource)
-                    -> hir::Stmt {
+    fn stmt_let_pat(
+        &mut self,
+        sp: Span,
+        ex: Option<P<hir::Expr>>,
+        pat: P<hir::Pat>,
+        source: hir::LocalSource,
+    ) -> hir::Stmt {
         let LoweredNodeId { node_id, hir_id } = self.next_id();
 
         let local = P(hir::Local {
@@ -3552,23 +3952,35 @@ impl<'a> LoweringContext<'a> {
         respan(sp, hir::StmtDecl(P(decl), self.next_id().node_id))
     }
 
-    fn stmt_let(&mut self, sp: Span, mutbl: bool, ident: Name, ex: P<hir::Expr>)
-                -> (hir::Stmt, NodeId) {
+    fn stmt_let(
+        &mut self,
+        sp: Span,
+        mutbl: bool,
+        ident: Name,
+        ex: P<hir::Expr>,
+    ) -> (hir::Stmt, NodeId) {
         let pat = if mutbl {
             self.pat_ident_binding_mode(sp, ident, hir::BindingAnnotation::Mutable)
         } else {
             self.pat_ident(sp, ident)
         };
         let pat_id = pat.id;
-        (self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal), pat_id)
+        (
+            self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal),
+            pat_id,
+        )
     }
 
     fn block_expr(&mut self, expr: P<hir::Expr>) -> hir::Block {
         self.block_all(expr.span, hir::HirVec::new(), Some(expr))
     }
 
-    fn block_all(&mut self, span: Span, stmts: hir::HirVec<hir::Stmt>, expr: Option<P<hir::Expr>>)
-                 -> hir::Block {
+    fn block_all(
+        &mut self,
+        span: Span,
+        stmts: hir::HirVec<hir::Stmt>,
+        expr: Option<P<hir::Expr>>,
+    ) -> hir::Block {
         let LoweredNodeId { node_id, hir_id } = self.next_id();
 
         hir::Block {
@@ -3599,11 +4011,12 @@ impl<'a> LoweringContext<'a> {
         self.pat_std_enum(span, &["option", "Option", "None"], hir_vec![])
     }
 
-    fn pat_std_enum(&mut self,
-                    span: Span,
-                    components: &[&str],
-                    subpats: hir::HirVec<P<hir::Pat>>)
-                    -> P<hir::Pat> {
+    fn pat_std_enum(
+        &mut self,
+        span: Span,
+        components: &[&str],
+        subpats: hir::HirVec<P<hir::Pat>>,
+    ) -> P<hir::Pat> {
         let path = self.std_path(span, components, true);
         let qpath = hir::QPath::Resolved(None, P(path));
         let pt = if subpats.is_empty() {
@@ -3618,20 +4031,18 @@ impl<'a> LoweringContext<'a> {
         self.pat_ident_binding_mode(span, name, hir::BindingAnnotation::Unannotated)
     }
 
-    fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingAnnotation)
-                              -> P<hir::Pat> {
+    fn pat_ident_binding_mode(
+        &mut self,
+        span: Span,
+        name: Name,
+        bm: hir::BindingAnnotation,
+    ) -> P<hir::Pat> {
         let LoweredNodeId { node_id, hir_id } = self.next_id();
 
         P(hir::Pat {
             id: node_id,
             hir_id,
-            node: hir::PatKind::Binding(bm,
-                                        node_id,
-                                        Spanned {
-                                            span,
-                                            node: name,
-                                        },
-                                        None),
+            node: hir::PatKind::Binding(bm, node_id, Spanned { span, node: name }, None),
             span,
         })
     }
@@ -3654,16 +4065,18 @@ impl<'a> LoweringContext<'a> {
     /// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
     /// The path is also resolved according to `is_value`.
     fn std_path(&mut self, span: Span, components: &[&str], is_value: bool) -> hir::Path {
-        self.resolver.resolve_str_path(span, self.crate_root, components, is_value)
+        self.resolver
+            .resolve_str_path(span, self.crate_root, components, is_value)
     }
 
-    fn signal_block_expr(&mut self,
-                         stmts: hir::HirVec<hir::Stmt>,
-                         expr: P<hir::Expr>,
-                         span: Span,
-                         rule: hir::BlockCheckMode,
-                         attrs: ThinVec<Attribute>)
-                         -> hir::Expr {
+    fn signal_block_expr(
+        &mut self,
+        stmts: hir::HirVec<hir::Stmt>,
+        expr: P<hir::Expr>,
+        span: Span,
+        rule: hir::BlockCheckMode,
+        attrs: ThinVec<Attribute>,
+    ) -> hir::Expr {
         let LoweredNodeId { node_id, hir_id } = self.next_id();
 
         let block = P(hir::Block {
@@ -3697,17 +4110,93 @@ impl<'a> LoweringContext<'a> {
                     // The original ID is taken by the `PolyTraitRef`,
                     // so the `Ty` itself needs a different one.
                     id = self.next_id();
-                    hir::TyTraitObject(hir_vec![principal], self.elided_lifetime(span))
+                    hir::TyTraitObject(hir_vec![principal], self.elided_dyn_bound(span))
                 } else {
                     hir::TyPath(hir::QPath::Resolved(None, path))
                 }
             }
-            _ => hir::TyPath(qpath)
+            _ => hir::TyPath(qpath),
         };
-        P(hir::Ty { id: id.node_id, hir_id: id.hir_id, node, span })
+        P(hir::Ty {
+            id: id.node_id,
+            hir_id: id.hir_id,
+            node,
+            span,
+        })
+    }
+
+    /// Invoked to create the lifetime argument for a type `&T`
+    /// with no explicit lifetime.
+    fn elided_ref_lifetime(&mut self, span: Span) -> hir::Lifetime {
+        match self.anonymous_lifetime_mode {
+            // Intercept when we are in an impl header and introduce an in-band lifetime.
+            // Hence `impl Foo for &u32` becomes `impl<'f> Foo for &'f u32` for some fresh
+            // `'f`.
+            AnonymousLifetimeMode::CreateParameter => {
+                let fresh_name = self.collect_fresh_in_band_lifetime(span);
+                hir::Lifetime {
+                    id: self.next_id().node_id,
+                    span,
+                    name: fresh_name,
+                }
+            }
+
+            AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
+        }
     }
 
-    fn elided_lifetime(&mut self, span: Span) -> hir::Lifetime {
+    /// Invoked to create the lifetime argument(s) for a path like
+    /// `std::cell::Ref<T>`; note that implicit lifetimes in these
+    /// sorts of cases are deprecated. This may therefore report a warning or an
+    /// error, depending on the mode.
+    fn elided_path_lifetimes(&mut self, span: Span, count: usize) -> P<[hir::Lifetime]> {
+        match self.anonymous_lifetime_mode {
+            // NB. We intentionally ignore the create-parameter mode here
+            // and instead "pass through" to resolve-lifetimes, which will then
+            // report an error. This is because we don't want to support
+            // impl elision for deprecated forms like
+            //
+            //     impl Foo for std::cell::Ref<u32> // note lack of '_
+            AnonymousLifetimeMode::CreateParameter => {}
+
+            // This is the normal case.
+            AnonymousLifetimeMode::PassThrough => {}
+        }
+
+        (0..count)
+            .map(|_| self.new_implicit_lifetime(span))
+            .collect()
+    }
+
+    /// Invoked to create the lifetime argument(s) for an elided trait object
+    /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
+    /// when the bound is written, even if it is written with `'_` like in
+    /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
+    fn elided_dyn_bound(&mut self, span: Span) -> hir::Lifetime {
+        match self.anonymous_lifetime_mode {
+            // NB. We intentionally ignore the create-parameter mode here.
+            // and instead "pass through" to resolve-lifetimes, which will apply
+            // the object-lifetime-defaulting rules. Elided object lifetime defaults
+            // do not act like other elided lifetimes. In other words, given this:
+            //
+            //     impl Foo for Box<dyn Debug>
+            //
+            // we do not introduce a fresh `'_` to serve as the bound, but instead
+            // ultimately translate to the equivalent of:
+            //
+            //     impl Foo for Box<dyn Debug + 'static>
+            //
+            // `resolve_lifetime` has the code to make that happen.
+            AnonymousLifetimeMode::CreateParameter => {}
+
+            // This is the normal case.
+            AnonymousLifetimeMode::PassThrough => {}
+        }
+
+        self.new_implicit_lifetime(span)
+    }
+
+    fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime {
         hir::Lifetime {
             id: self.next_id().node_id,
             span,
@@ -3718,9 +4207,11 @@ impl<'a> LoweringContext<'a> {
     fn maybe_lint_bare_trait(&self, span: Span, id: NodeId, is_global: bool) {
         if self.sess.features_untracked().dyn_trait {
             self.sess.buffer_lint_with_diagnostic(
-                builtin::BARE_TRAIT_OBJECT, id, span,
+                builtin::BARE_TRAIT_OBJECT,
+                id,
+                span,
                 "trait objects without an explicit `dyn` are deprecated",
-                builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global)
+                builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global),
             )
         }
     }
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 61fae4609d54f..e8bcbfbb77a17 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -962,6 +962,7 @@ impl<'hir> Map<'hir> {
             Some(NodeField(ref f)) => Some(&f.attrs[..]),
             Some(NodeExpr(ref e)) => Some(&*e.attrs),
             Some(NodeStmt(ref s)) => Some(s.node.attrs()),
+            Some(NodeTyParam(tp)) => Some(&tp.attrs[..]),
             // unit/tuple structs take the attributes straight from
             // the struct definition.
             Some(NodeStructCtor(_)) => {
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index f4638c23c5f4b..be8cceb611896 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -203,9 +203,31 @@ pub struct Lifetime {
 
 #[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
 pub enum LifetimeName {
+    /// User typed nothing. e.g. the lifetime in `&u32`.
     Implicit,
+
+    /// User typed `'_`.
     Underscore,
+
+    /// Synthetic name generated when user elided a lifetime in an impl header,
+    /// e.g. the lifetimes in cases like these:
+    ///
+    ///     impl Foo for &u32
+    ///     impl Foo<'_> for u32
+    ///
+    /// in that case, we rewrite to
+    ///
+    ///     impl<'f> Foo for &'f u32
+    ///     impl<'f> Foo<'f> for u32
+    ///
+    /// where `'f` is something like `Fresh(0)`. The indices are
+    /// unique per impl, but not necessarily continuous.
+    Fresh(usize),
+
+    /// User wrote `'static`
     Static,
+
+    /// Some user-given name like `'x`
     Name(Name),
 }
 
@@ -214,7 +236,7 @@ impl LifetimeName {
         use self::LifetimeName::*;
         match *self {
             Implicit => keywords::Invalid.name(),
-            Underscore => Symbol::intern("'_"),
+            Fresh(_) | Underscore => keywords::UnderscoreLifetime.name(),
             Static => keywords::StaticLifetime.name(),
             Name(name) => name,
         }
@@ -235,7 +257,13 @@ impl Lifetime {
         use self::LifetimeName::*;
         match self.name {
             Implicit | Underscore => true,
-            Static | Name(_) => false,
+
+            // It might seem surprising that `Fresh(_)` counts as
+            // *not* elided -- but this is because, as far as the code
+            // in the compiler is concerned -- `Fresh(_)` variants act
+            // equivalently to "some fresh name". They correspond to
+            // early-bound regions on an impl, in other words.
+            Fresh(_) | Static | Name(_) => false,
         }
     }
 
@@ -395,6 +423,15 @@ pub enum TyParamBound {
     RegionTyParamBound(Lifetime),
 }
 
+impl TyParamBound {
+    pub fn span(&self) -> Span {
+        match self {
+            &TraitTyParamBound(ref t, ..) => t.span,
+            &RegionTyParamBound(ref l) => l.span,
+        }
+    }
+}
+
 /// A modifier on a bound, currently this is only used for `?Sized`, where the
 /// modifier is `Maybe`. Negative bounds should also be handled here.
 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
@@ -414,6 +451,7 @@ pub struct TyParam {
     pub span: Span,
     pub pure_wrt_drop: bool,
     pub synthetic: Option<SyntheticTyParamKind>,
+    pub attrs: HirVec<Attribute>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
@@ -570,6 +608,16 @@ pub enum WherePredicate {
     EqPredicate(WhereEqPredicate),
 }
 
+impl WherePredicate {
+    pub fn span(&self) -> Span {
+        match self {
+            &WherePredicate::BoundPredicate(ref p) => p.span,
+            &WherePredicate::RegionPredicate(ref p) => p.span,
+            &WherePredicate::EqPredicate(ref p) => p.span,
+        }
+    }
+}
+
 /// A type bound, eg `for<'c> Foo: Send+Clone+'c`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct WhereBoundPredicate {
@@ -2011,9 +2059,9 @@ pub struct Item {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Item_ {
-    /// An `extern crate` item, with optional original crate name,
+    /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
     ///
-    /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
+    /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
     ItemExternCrate(Option<Name>),
 
     /// `use foo::bar::*;` or `use foo::bar::baz as quux;`
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 9e755f366a7de..ff501f30c891a 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -13,7 +13,7 @@ pub use self::AnnNode::*;
 use syntax::abi::Abi;
 use syntax::ast;
 use syntax::codemap::{CodeMap, Spanned};
-use syntax::parse::ParseSess;
+use syntax::parse::{token, ParseSess};
 use syntax::parse::lexer::comments;
 use syntax::print::pp::{self, Breaks};
 use syntax::print::pp::Breaks::{Consistent, Inconsistent};
@@ -524,15 +524,10 @@ impl<'a> State<'a> {
         self.print_outer_attributes(&item.attrs)?;
         self.ann.pre(self, NodeItem(item))?;
         match item.node {
-            hir::ItemExternCrate(ref optional_path) => {
+            hir::ItemExternCrate(orig_name) => {
                 self.head(&visibility_qualified(&item.vis, "extern crate"))?;
-                if let Some(p) = *optional_path {
-                    let val = p.as_str();
-                    if val.contains("-") {
-                        self.print_string(&val, ast::StrStyle::Cooked)?;
-                    } else {
-                        self.print_name(p)?;
-                    }
+                if let Some(orig_name) = orig_name {
+                    self.print_name(orig_name)?;
                     self.s.space()?;
                     self.s.word("as")?;
                     self.s.space()?;
@@ -1566,7 +1561,11 @@ impl<'a> State<'a> {
     }
 
     pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
-        self.s.word(&name.as_str())?;
+        if token::is_raw_guess(ast::Ident::with_empty_ctxt(name)) {
+            self.s.word(&format!("r#{}", name))?;
+        } else {
+            self.s.word(&name.as_str())?;
+        }
         self.ann.post(self, NodeName(&name))
     }
 
diff --git a/src/librustc/ich/impls_cstore.rs b/src/librustc/ich/impls_cstore.rs
index 18a02ff5c5882..0071850e1052b 100644
--- a/src/librustc/ich/impls_cstore.rs
+++ b/src/librustc/ich/impls_cstore.rs
@@ -33,7 +33,12 @@ impl_stable_hash_for!(struct middle::cstore::NativeLibrary {
     kind,
     name,
     cfg,
-    foreign_items
+    foreign_module
+});
+
+impl_stable_hash_for!(struct middle::cstore::ForeignModule {
+    foreign_items,
+    def_id
 });
 
 impl_stable_hash_for!(enum middle::cstore::LinkagePreference {
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index c085b803085a8..c3b3e10201f99 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -145,6 +145,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
 impl_stable_hash_for!(enum hir::LifetimeName {
     Implicit,
     Underscore,
+    Fresh(index),
     Static,
     Name(name)
 });
@@ -203,7 +204,8 @@ impl_stable_hash_for!(struct hir::TyParam {
     default,
     span,
     pure_wrt_drop,
-    synthetic
+    synthetic,
+    attrs
 });
 
 impl_stable_hash_for!(enum hir::GenericParam {
@@ -851,7 +853,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
 }
 
 impl_stable_hash_for!(enum hir::Item_ {
-    ItemExternCrate(name),
+    ItemExternCrate(orig_name),
     ItemUse(path, use_kind),
     ItemStatic(ty, mutability, body_id),
     ItemConst(ty, body_id),
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index 1e6dadae36371..c73f171806e42 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -277,6 +277,10 @@ for mir::StatementKind<'gcx> {
                 op.hash_stable(hcx, hasher);
                 places.hash_stable(hcx, hasher);
             }
+            mir::StatementKind::UserAssertTy(ref c_ty, ref local) => {
+                c_ty.hash_stable(hcx, hasher);
+                local.hash_stable(hcx, hasher);
+            }
             mir::StatementKind::Nop => {}
             mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
                 asm.hash_stable(hcx, hasher);
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 289bc753d7fec..0b037964981c9 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -287,7 +287,6 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
         token::Token::Pound |
         token::Token::Dollar |
         token::Token::Question |
-        token::Token::Underscore |
         token::Token::Whitespace |
         token::Token::Comment |
         token::Token::Eof => {}
@@ -319,7 +318,10 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
             opt_name.hash_stable(hcx, hasher);
         }
 
-        token::Token::Ident(ident) |
+        token::Token::Ident(ident, is_raw) => {
+            ident.name.hash_stable(hcx, hasher);
+            is_raw.hash_stable(hcx, hasher);
+        }
         token::Token::Lifetime(ident) => ident.name.hash_stable(hcx, hasher),
 
         token::Token::Interpolated(_) => {
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index bb3051b546e64..9a442e0529938 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -902,13 +902,59 @@ for ty::TypeVariants<'gcx>
             TyForeign(def_id) => {
                 def_id.hash_stable(hcx, hasher);
             }
-            TyInfer(..) => {
-                bug!("ty::TypeVariants::hash_stable() - Unexpected variant {:?}.", *self)
+            TyInfer(infer_ty) => {
+                infer_ty.hash_stable(hcx, hasher);
             }
         }
     }
 }
 
+impl_stable_hash_for!(enum ty::InferTy {
+    TyVar(a),
+    IntVar(a),
+    FloatVar(a),
+    FreshTy(a),
+    FreshIntTy(a),
+    FreshFloatTy(a),
+    CanonicalTy(a),
+});
+
+impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
+for ty::TyVid
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          _hcx: &mut StableHashingContext<'a>,
+                                          _hasher: &mut StableHasher<W>) {
+        // TyVid values are confined to an inference context and hence
+        // should not be hashed.
+        bug!("ty::TypeVariants::hash_stable() - can't hash a TyVid {:?}.", *self)
+    }
+}
+
+impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
+for ty::IntVid
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          _hcx: &mut StableHashingContext<'a>,
+                                          _hasher: &mut StableHasher<W>) {
+        // IntVid values are confined to an inference context and hence
+        // should not be hashed.
+        bug!("ty::TypeVariants::hash_stable() - can't hash an IntVid {:?}.", *self)
+    }
+}
+
+impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
+for ty::FloatVid
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          _hcx: &mut StableHashingContext<'a>,
+                                          _hasher: &mut StableHasher<W>) {
+        // FloatVid values are confined to an inference context and hence
+        // should not be hashed.
+        bug!("ty::TypeVariants::hash_stable() - can't hash a FloatVid {:?}.", *self)
+    }
+}
+
 impl_stable_hash_for!(struct ty::ParamTy {
     idx,
     name
@@ -1285,3 +1331,86 @@ impl_stable_hash_for!(struct infer::canonical::QueryRegionConstraints<'tcx> {
 impl_stable_hash_for!(enum infer::canonical::Certainty {
     Proven, Ambiguous
 });
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WhereClauseAtom<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        use traits::WhereClauseAtom::*;
+
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match self {
+            Implemented(trait_ref) => trait_ref.hash_stable(hcx, hasher),
+            ProjectionEq(projection) => projection.hash_stable(hcx, hasher),
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::DomainGoal<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        use traits::DomainGoal::*;
+
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match self {
+            Holds(where_clause) |
+            WellFormed(where_clause) |
+            FromEnv(where_clause) => where_clause.hash_stable(hcx, hasher),
+
+            WellFormedTy(ty) => ty.hash_stable(hcx, hasher),
+            FromEnvTy(ty) => ty.hash_stable(hcx, hasher),
+            RegionOutlives(predicate) => predicate.hash_stable(hcx, hasher),
+            TypeOutlives(predicate) => predicate.hash_stable(hcx, hasher),
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        use traits::Goal::*;
+
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match self {
+            Implies(hypotheses, goal) => {
+                hypotheses.hash_stable(hcx, hasher);
+                goal.hash_stable(hcx, hasher);
+            },
+            And(goal1, goal2) => {
+                goal1.hash_stable(hcx, hasher);
+                goal2.hash_stable(hcx, hasher);
+            }
+            Not(goal) => goal.hash_stable(hcx, hasher),
+            DomainGoal(domain_goal) => domain_goal.hash_stable(hcx, hasher),
+            Quantified(quantifier, goal) => {
+                quantifier.hash_stable(hcx, hasher);
+                goal.hash_stable(hcx, hasher);
+            },
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Clause<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        use traits::Clause::*;
+
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match self {
+            Implies(hypotheses, goal) => {
+                hypotheses.hash_stable(hcx, hasher);
+                goal.hash_stable(hcx, hasher);
+            }
+            DomainGoal(domain_goal) => domain_goal.hash_stable(hcx, hasher),
+            ForAll(clause) => clause.hash_stable(hcx, hasher),
+        }
+    }
+}
+
+impl_stable_hash_for!(enum traits::QuantifierKind {
+    Universal,
+    Existential
+});
diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs
index eb26f0c1188bf..93e8745af1b57 100644
--- a/src/librustc/infer/anon_types/mod.rs
+++ b/src/librustc/infer/anon_types/mod.rs
@@ -14,10 +14,10 @@ use infer::outlives::free_region_map::FreeRegionRelations;
 use rustc_data_structures::fx::FxHashMap;
 use syntax::ast;
 use traits::{self, PredicateObligation};
-use ty::{self, Ty};
-use ty::fold::{BottomUpFolder, TypeFoldable};
+use ty::{self, Ty, TyCtxt};
+use ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder};
 use ty::outlives::Component;
-use ty::subst::{Kind, UnpackedKind, Substs};
+use ty::subst::{Kind, Substs, UnpackedKind};
 use util::nodemap::DefIdMap;
 
 pub type AnonTypeMap<'tcx> = DefIdMap<AnonTypeDecl<'tcx>>;
@@ -113,10 +113,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     ) -> InferOk<'tcx, (T, AnonTypeMap<'tcx>)> {
         debug!(
             "instantiate_anon_types(value={:?}, parent_def_id={:?}, body_id={:?}, param_env={:?})",
-            value,
-            parent_def_id,
-            body_id,
-            param_env,
+            value, parent_def_id, body_id, param_env,
         );
         let mut instantiator = Instantiator {
             infcx: self,
@@ -458,55 +455,184 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         // Convert the type from the function into a type valid outside
         // the function, by replacing invalid regions with 'static,
         // after producing an error for each of them.
-        let definition_ty = gcx.fold_regions(&instantiated_ty, &mut false, |r, _| {
-            match *r {
-                // 'static and early-bound regions are valid.
-                ty::ReStatic | ty::ReEmpty => r,
-
-                // All other regions, we map them appropriately to their adjusted
-                // indices, erroring if we find any lifetimes that were not mapped
-                // into the new set.
-                _ => if let Some(UnpackedKind::Lifetime(r1)) = map.get(&r.into())
-                                                                  .map(|k| k.unpack()) {
-                    r1
-                } else {
-                    // No mapping was found. This means that
-                    // it is either a disallowed lifetime,
-                    // which will be caught by regionck, or it
-                    // is a region in a non-upvar closure
-                    // generic, which is explicitly
-                    // allowed. If that surprises you, read
-                    // on.
-                    //
-                    // The case of closure is a somewhat
-                    // subtle (read: hacky) consideration. The
-                    // problem is that our closure types
-                    // currently include all the lifetime
-                    // parameters declared on the enclosing
-                    // function, even if they are unused by
-                    // the closure itself. We can't readily
-                    // filter them out, so here we replace
-                    // those values with `'empty`. This can't
-                    // really make a difference to the rest of
-                    // the compiler; those regions are ignored
-                    // for the outlives relation, and hence
-                    // don't affect trait selection or auto
-                    // traits, and they are erased during
-                    // trans.
-                    gcx.types.re_empty
-                },
-            }
-        });
-
+        let definition_ty =
+            instantiated_ty.fold_with(&mut ReverseMapper::new(
+                self.tcx,
+                self.is_tainted_by_errors(),
+                def_id,
+                map,
+                instantiated_ty,
+            ));
         debug!(
             "infer_anon_definition_from_instantiation: definition_ty={:?}",
             definition_ty
         );
 
+        // We can unwrap here because our reverse mapper always
+        // produces things with 'gcx lifetime, though the type folder
+        // obscures that.
+        let definition_ty = gcx.lift(&definition_ty).unwrap();
+
         definition_ty
     }
 }
 
+struct ReverseMapper<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
+    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
+
+    /// If errors have already been reported in this fn, we suppress
+    /// our own errors because they are sometimes derivative.
+    tainted_by_errors: bool,
+
+    anon_type_def_id: DefId,
+    map: FxHashMap<Kind<'tcx>, Kind<'gcx>>,
+    map_missing_regions_to_empty: bool,
+
+    /// initially `Some`, set to `None` once error has been reported
+    hidden_ty: Option<Ty<'tcx>>,
+}
+
+impl<'cx, 'gcx, 'tcx> ReverseMapper<'cx, 'gcx, 'tcx> {
+    fn new(
+        tcx: TyCtxt<'cx, 'gcx, 'tcx>,
+        tainted_by_errors: bool,
+        anon_type_def_id: DefId,
+        map: FxHashMap<Kind<'tcx>, Kind<'gcx>>,
+        hidden_ty: Ty<'tcx>,
+    ) -> Self {
+        Self {
+            tcx,
+            tainted_by_errors,
+            anon_type_def_id,
+            map,
+            map_missing_regions_to_empty: false,
+            hidden_ty: Some(hidden_ty),
+        }
+    }
+
+    fn fold_kind_mapping_missing_regions_to_empty(&mut self, kind: Kind<'tcx>) -> Kind<'tcx> {
+        assert!(!self.map_missing_regions_to_empty);
+        self.map_missing_regions_to_empty = true;
+        let kind = kind.fold_with(self);
+        self.map_missing_regions_to_empty = false;
+        kind
+    }
+
+    fn fold_kind_normally(&mut self, kind: Kind<'tcx>) -> Kind<'tcx> {
+        assert!(!self.map_missing_regions_to_empty);
+        kind.fold_with(self)
+    }
+}
+
+impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx> {
+        self.tcx
+    }
+
+    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
+        match r {
+            // ignore bound regions that appear in the type (e.g., this
+            // would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
+            ty::ReLateBound(..) => return r,
+
+            // ignore `'static`, as that can appear anywhere
+            ty::ReStatic => return r,
+
+            _ => { }
+        }
+
+        match self.map.get(&r.into()).map(|k| k.unpack()) {
+            Some(UnpackedKind::Lifetime(r1)) => r1,
+            Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
+            None => {
+                if !self.map_missing_regions_to_empty && !self.tainted_by_errors {
+                    if let Some(hidden_ty) = self.hidden_ty.take() {
+                        let span = self.tcx.def_span(self.anon_type_def_id);
+                        let mut err = struct_span_err!(
+                            self.tcx.sess,
+                            span,
+                            E0909,
+                            "hidden type for `impl Trait` captures lifetime that \
+                             does not appear in bounds",
+                        );
+
+                        // Assuming regionck succeeded, then we must
+                        // be capturing *some* region from the fn
+                        // header, and hence it must be free, so it's
+                        // ok to invoke this fn (which doesn't accept
+                        // all regions, and would ICE if an
+                        // inappropriate region is given). We check
+                        // `is_tainted_by_errors` by errors above, so
+                        // we don't get in here unless regionck
+                        // succeeded. (Note also that if regionck
+                        // failed, then the regions we are attempting
+                        // to map here may well be giving errors
+                        // *because* the constraints were not
+                        // satisfiable.)
+                        self.tcx.note_and_explain_free_region(
+                            &mut err,
+                            &format!("hidden type `{}` captures ", hidden_ty),
+                            r,
+                            ""
+                        );
+
+                        err.emit();
+                    }
+                }
+                self.tcx.types.re_empty
+            },
+        }
+    }
+
+    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
+        match ty.sty {
+            ty::TyClosure(def_id, substs) => {
+                // I am a horrible monster and I pray for death. When
+                // we encounter a closure here, it is always a closure
+                // from within the function that we are currently
+                // type-checking -- one that is now being encapsulated
+                // in an existential abstract type. Ideally, we would
+                // go through the types/lifetimes that it references
+                // and treat them just like we would any other type,
+                // which means we would error out if we find any
+                // reference to a type/region that is not in the
+                // "reverse map".
+                //
+                // **However,** in the case of closures, there is a
+                // somewhat subtle (read: hacky) consideration. The
+                // problem is that our closure types currently include
+                // all the lifetime parameters declared on the
+                // enclosing function, even if they are unused by the
+                // closure itself. We can't readily filter them out,
+                // so here we replace those values with `'empty`. This
+                // can't really make a difference to the rest of the
+                // compiler; those regions are ignored for the
+                // outlives relation, and hence don't affect trait
+                // selection or auto traits, and they are erased
+                // during trans.
+
+                let generics = self.tcx.generics_of(def_id);
+                let parent_len = generics.parent_count();
+                let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map(
+                    |(index, &kind)| {
+                        if index < parent_len {
+                            // Accommodate missing regions in the parent kinds...
+                            self.fold_kind_mapping_missing_regions_to_empty(kind)
+                        } else {
+                            // ...but not elsewhere.
+                            self.fold_kind_normally(kind)
+                        }
+                    },
+                ));
+
+                self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs })
+            }
+
+            _ => ty.super_fold_with(self),
+        }
+    }
+}
+
 struct Instantiator<'a, 'gcx: 'tcx, 'tcx: 'a> {
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
     parent_def_id: DefId,
@@ -565,12 +691,13 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
                             return self.fold_anon_ty(ty, def_id, substs);
                         }
 
-                        debug!("instantiate_anon_types_in_map: \
-                                encountered anon with wrong parent \
-                                def_id={:?} \
-                                anon_parent_def_id={:?}",
-                               def_id,
-                               anon_parent_def_id);
+                        debug!(
+                            "instantiate_anon_types_in_map: \
+                             encountered anon with wrong parent \
+                             def_id={:?} \
+                             anon_parent_def_id={:?}",
+                            def_id, anon_parent_def_id
+                        );
                     }
                 }
 
@@ -590,8 +717,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
 
         debug!(
             "instantiate_anon_types: TyAnon(def_id={:?}, substs={:?})",
-            def_id,
-            substs
+            def_id, substs
         );
 
         // Use the same type variable if the exact same TyAnon appears more
@@ -600,8 +726,10 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
             return anon_defn.concrete_ty;
         }
         let span = tcx.def_span(def_id);
-        let ty_var = infcx.next_ty_var(ty::UniverseIndex::ROOT,
-                                       TypeVariableOrigin::TypeInference(span));
+        let ty_var = infcx.next_ty_var(
+            ty::UniverseIndex::ROOT,
+            TypeVariableOrigin::TypeInference(span),
+        );
 
         let predicates_of = tcx.predicates_of(def_id);
         let bounds = predicates_of.instantiate(tcx, substs);
diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs
index 4e0cf59e8a7fd..debddd708ea22 100644
--- a/src/librustc/infer/canonical.rs
+++ b/src/librustc/infer/canonical.rs
@@ -33,6 +33,7 @@
 
 use infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TypeVariableOrigin};
 use rustc_data_structures::indexed_vec::Idx;
+use serialize::UseSpecializedDecodable;
 use std::fmt::Debug;
 use std::ops::Index;
 use syntax::codemap::Span;
@@ -40,6 +41,7 @@ use traits::{Obligation, ObligationCause, PredicateObligation};
 use ty::{self, CanonicalVar, Lift, Region, Slice, Ty, TyCtxt, TypeFlags};
 use ty::subst::{Kind, UnpackedKind};
 use ty::fold::{TypeFoldable, TypeFolder};
+use util::captures::Captures;
 use util::common::CellUsizeExt;
 
 use rustc_data_structures::indexed_vec::IndexVec;
@@ -48,7 +50,7 @@ use rustc_data_structures::fx::FxHashMap;
 /// A "canonicalized" type `V` is one where all free inference
 /// variables have been rewriten to "canonical vars". These are
 /// numbered starting from 0 in order of first appearance.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
 pub struct Canonical<'gcx, V> {
     pub variables: CanonicalVarInfos<'gcx>,
     pub value: V,
@@ -56,6 +58,8 @@ pub struct Canonical<'gcx, V> {
 
 pub type CanonicalVarInfos<'gcx> = &'gcx Slice<CanonicalVarInfo>;
 
+impl<'gcx> UseSpecializedDecodable for CanonicalVarInfos<'gcx> { }
+
 /// A set of values corresponding to the canonical variables from some
 /// `Canonical`. You can give these values to
 /// `canonical_value.substitute` to substitute them into the canonical
@@ -68,7 +72,7 @@ pub type CanonicalVarInfos<'gcx> = &'gcx Slice<CanonicalVarInfo>;
 /// You can also use `infcx.fresh_inference_vars_for_canonical_vars`
 /// to get back a `CanonicalVarValues` containing fresh inference
 /// variables.
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
 pub struct CanonicalVarValues<'tcx> {
     pub var_values: IndexVec<CanonicalVar, Kind<'tcx>>,
 }
@@ -77,7 +81,7 @@ pub struct CanonicalVarValues<'tcx> {
 /// canonical value. This is sufficient information for code to create
 /// a copy of the canonical value in some other inference context,
 /// with fresh inference variables replacing the canonical values.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
 pub struct CanonicalVarInfo {
     pub kind: CanonicalVarKind,
 }
@@ -85,7 +89,7 @@ pub struct CanonicalVarInfo {
 /// Describes the "kind" of the canonical variable. This is a "kind"
 /// in the type-theory sense of the term -- i.e., a "meta" type system
 /// that analyzes type-like values.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
 pub enum CanonicalVarKind {
     /// Some kind of type inference variable.
     Ty(CanonicalTyVarKind),
@@ -99,7 +103,7 @@ pub enum CanonicalVarKind {
 /// 22.) can only be instantiated with integral/float types (e.g.,
 /// usize or f32). In order to faithfully reproduce a type, we need to
 /// know what set of types a given type variable can be unified with.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
 pub enum CanonicalTyVarKind {
     /// General type variable `?T` that can be unified with arbitrary types.
     General,
@@ -382,7 +386,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         unsubstituted_region_constraints: &'a QueryRegionConstraints<'tcx>,
         result_subst: &'a CanonicalVarValues<'tcx>,
-    ) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a {
+    ) -> impl Iterator<Item = PredicateObligation<'tcx>> + Captures<'gcx> + 'a {
         let QueryRegionConstraints {
             region_outlives,
             ty_outlives,
@@ -854,11 +858,14 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g
 }
 
 CloneTypeFoldableAndLiftImpls! {
+    ::infer::canonical::Certainty,
+    ::infer::canonical::CanonicalVarInfo,
+    ::infer::canonical::CanonicalVarKind,
+}
+
+CloneTypeFoldableImpls! {
     for <'tcx> {
-        ::infer::canonical::Certainty,
-        ::infer::canonical::CanonicalVarInfo,
         ::infer::canonical::CanonicalVarInfos<'tcx>,
-        ::infer::canonical::CanonicalVarKind,
     }
 }
 
@@ -869,6 +876,13 @@ BraceStructTypeFoldableImpl! {
     } where C: TypeFoldable<'tcx>
 }
 
+BraceStructLiftImpl! {
+    impl<'a, 'tcx, T> Lift<'tcx> for Canonical<'a, T> {
+        type Lifted = Canonical<'tcx, T::Lifted>;
+        variables, value
+    } where T: Lift<'tcx>
+}
+
 impl<'tcx> CanonicalVarValues<'tcx> {
     fn iter<'a>(&'a self) -> impl Iterator<Item = Kind<'tcx>> + 'a {
         self.var_values.iter().cloned()
diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs
index a317e0699b4bb..d44f2ec95492f 100644
--- a/src/librustc/infer/higher_ranked/mod.rs
+++ b/src/librustc/infer/higher_ranked/mod.rs
@@ -580,7 +580,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     /// the pop occurs as part of the rollback, so an explicit call is not
     /// needed (but is also permitted).
     ///
-    /// See `README.md` for more details.
+    /// For more information about how skolemization for HRTBs works, see
+    /// the [rustc guide].
+    ///
+    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
     pub fn skolemize_late_bound_regions<T>(&self,
                                            binder: &ty::Binder<T>,
                                            snapshot: &CombinedSnapshot<'a, 'tcx>)
diff --git a/src/librustc/infer/lexical_region_resolve/README.md b/src/librustc/infer/lexical_region_resolve/README.md
index a90230870a6c0..0086aed3e7c97 100644
--- a/src/librustc/infer/lexical_region_resolve/README.md
+++ b/src/librustc/infer/lexical_region_resolve/README.md
@@ -1,14 +1,16 @@
 # Region inference
 
+> WARNING: This README is obsolete and will be removed soon! For
+> more info on how the current borrowck works, see the [rustc guide].
+
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+
 ## Terminology
 
 Note that we use the terms region and lifetime interchangeably.
 
 ## Introduction
 
-See the [general inference README](../README.md) for an overview of
-how lexical-region-solving fits into the bigger picture.
-
 Region inference uses a somewhat more involved algorithm than type
 inference. It is not the most efficient thing ever written though it
 seems to work well enough in practice (famous last words).  The reason
diff --git a/src/librustc/infer/outlives/bounds.rs b/src/librustc/infer/outlives/bounds.rs
index 8bb3f4158ff5b..4bc64acc76306 100644
--- a/src/librustc/infer/outlives/bounds.rs
+++ b/src/librustc/infer/outlives/bounds.rs
@@ -11,7 +11,7 @@
 use infer::InferCtxt;
 use syntax::ast;
 use syntax::codemap::Span;
-use traits::FulfillmentContext;
+use traits::{FulfillmentContext, TraitEngine};
 use ty::{self, Ty, TypeFoldable};
 use ty::outlives::Component;
 use ty::wf;
diff --git a/src/librustc/infer/region_constraints/README.md b/src/librustc/infer/region_constraints/README.md
index 95f9c8c835398..07b87e2012dde 100644
--- a/src/librustc/infer/region_constraints/README.md
+++ b/src/librustc/infer/region_constraints/README.md
@@ -1,18 +1,25 @@
 # Region constraint collection
 
+> WARNING: This README is obsolete and will be removed soon! For
+> more info on how the current borrowck works, see the [rustc guide].
+
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+
 ## Terminology
 
 Note that we use the terms region and lifetime interchangeably.
 
 ## Introduction
 
-As described in the [inference README](../README.md), and unlike
+As described in the rustc guide [chapter on type inference][ti], and unlike
 normal type inference, which is similar in spirit to H-M and thus
 works progressively, the region type inference works by accumulating
 constraints over the course of a function.  Finally, at the end of
 processing a function, we process and solve the constraints all at
 once.
 
+[ti]: https://rust-lang-nursery.github.io/rustc-guide/type-inference.html
+
 The constraints are always of one of three possible forms:
 
 - `ConstrainVarSubVar(Ri, Rj)` states that region variable Ri must be
diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs
index 0c8e49fda1840..e864485539b2d 100644
--- a/src/librustc/infer/region_constraints/mod.rs
+++ b/src/librustc/infer/region_constraints/mod.rs
@@ -468,8 +468,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
     /// the APIs in `higher_ranked/mod.rs`, such as
     /// `skolemize_late_bound_regions` and `plug_leaks`, which will
     /// guide you on this path (ensure that the `SkolemizationMap` is
-    /// consumed and you are good).  There are also somewhat extensive
-    /// comments in `higher_ranked/README.md`.
+    /// consumed and you are good). For more info on how skolemization
+    /// for HRTBs works, see the [rustc guide].
+    ///
+    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
     ///
     /// The `snapshot` argument to this function is not really used;
     /// it's just there to make it explicit which snapshot bounds the
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 77259f156e5e2..ae8ae9404bc87 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -43,20 +43,19 @@
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
-#![feature(conservative_impl_trait)]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
 #![feature(const_fn)]
-#![feature(copy_closures, clone_closures)]
+#![cfg_attr(stage0, feature(copy_closures, clone_closures))]
 #![feature(core_intrinsics)]
 #![feature(drain_filter)]
 #![feature(dyn_trait)]
 #![feature(entry_or_default)]
 #![feature(from_ref)]
 #![feature(fs_read_write)]
-#![feature(i128)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type, i128))]
 #![cfg_attr(stage0, feature(inclusive_range_syntax))]
 #![cfg_attr(windows, feature(libc))]
-#![feature(match_default_bindings)]
+#![cfg_attr(stage0, feature(match_default_bindings))]
 #![feature(macro_lifetime_matcher)]
 #![feature(macro_vis_matcher)]
 #![feature(exhaustive_patterns)]
@@ -70,7 +69,7 @@
 #![feature(specialization)]
 #![feature(unboxed_closures)]
 #![feature(underscore_lifetimes)]
-#![feature(universal_impl_trait)]
+#![cfg_attr(stage0, feature(universal_impl_trait))]
 #![feature(trace_macros)]
 #![feature(trusted_len)]
 #![feature(catch_expr)]
@@ -157,6 +156,7 @@ pub mod traits;
 pub mod ty;
 
 pub mod util {
+    pub mod captures;
     pub mod common;
     pub mod ppaux;
     pub mod nodemap;
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index b4ed9c269bd88..97cfcf0f60795 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -260,6 +260,12 @@ declare_lint! {
     "floating-point literals cannot be used in patterns"
 }
 
+declare_lint! {
+    pub UNSTABLE_NAME_COLLISION,
+    Warn,
+    "detects name collision with an existing but unstable method"
+}
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 #[derive(Copy, Clone)]
@@ -307,7 +313,8 @@ impl LintPass for HardwiredLints {
             SINGLE_USE_LIFETIME,
             TYVAR_BEHIND_RAW_POINTER,
             ELIDED_LIFETIME_IN_PATH,
-            BARE_TRAIT_OBJECT
+            BARE_TRAIT_OBJECT,
+            UNSTABLE_NAME_COLLISION,
         )
     }
 }
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 4fa6594df169c..3c833251f72a7 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -41,7 +41,7 @@ use util::nodemap::FxHashMap;
 use std::default::Default as StdDefault;
 use std::cell::{Ref, RefCell};
 use syntax::ast;
-use syntax::epoch;
+use syntax::edition;
 use syntax_pos::{MultiSpan, Span};
 use errors::DiagnosticBuilder;
 use hir;
@@ -103,9 +103,9 @@ pub struct FutureIncompatibleInfo {
     pub id: LintId,
     /// e.g., a URL for an issue/PR/RFC or error code
     pub reference: &'static str,
-    /// If this is an epoch fixing lint, the epoch in which
+    /// If this is an edition fixing lint, the edition in which
     /// this lint becomes obsolete
-    pub epoch: Option<epoch::Epoch>,
+    pub edition: Option<edition::Edition>,
 }
 
 /// The target of the `by_name` map, which accounts for renaming/deprecation.
@@ -201,11 +201,11 @@ impl LintStore {
                                         sess: Option<&Session>,
                                         lints: Vec<FutureIncompatibleInfo>) {
 
-        for epoch in epoch::ALL_EPOCHS {
-            let lints = lints.iter().filter(|f| f.epoch == Some(*epoch)).map(|f| f.id)
+        for edition in edition::ALL_EDITIONS {
+            let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id)
                              .collect::<Vec<_>>();
             if !lints.is_empty() {
-                self.register_group(sess, false, epoch.lint_name(), lints)
+                self.register_group(sess, false, edition.lint_name(), lints)
             }
         }
 
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 7c103dc272109..1497be2d5ba0d 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -42,7 +42,7 @@ use session::{Session, DiagnosticMessageId};
 use std::hash;
 use syntax::ast;
 use syntax::codemap::MultiSpan;
-use syntax::epoch::Epoch;
+use syntax::edition::Edition;
 use syntax::symbol::Symbol;
 use syntax::visit as ast_visit;
 use syntax_pos::Span;
@@ -77,8 +77,8 @@ pub struct Lint {
     /// e.g. "imports that are never used"
     pub desc: &'static str,
 
-    /// Deny lint after this epoch
-    pub epoch_deny: Option<Epoch>,
+    /// Deny lint after this edition
+    pub edition_deny: Option<Edition>,
 }
 
 impl Lint {
@@ -88,8 +88,8 @@ impl Lint {
     }
 
     pub fn default_level(&self, session: &Session) -> Level {
-        if let Some(epoch_deny) = self.epoch_deny {
-            if session.epoch() >= epoch_deny {
+        if let Some(edition_deny) = self.edition_deny {
+            if session.edition() >= edition_deny {
                 return Level::Deny
             }
         }
@@ -100,12 +100,12 @@ impl Lint {
 /// Declare a static item of type `&'static Lint`.
 #[macro_export]
 macro_rules! declare_lint {
-    ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $epoch: expr) => (
+    ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $edition: expr) => (
         $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
             name: stringify!($NAME),
             default_level: $crate::lint::$Level,
             desc: $desc,
-            epoch_deny: Some($epoch)
+            edition_deny: Some($edition)
         };
     );
     ($vis: vis $NAME: ident, $Level: ident, $desc: expr) => (
@@ -113,7 +113,7 @@ macro_rules! declare_lint {
             name: stringify!($NAME),
             default_level: $crate::lint::$Level,
             desc: $desc,
-            epoch_deny: None,
+            edition_deny: None,
         };
     );
 }
@@ -498,15 +498,21 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
 
     // Check for future incompatibility lints and issue a stronger warning.
     let lints = sess.lint_store.borrow();
-    if let Some(future_incompatible) = lints.future_incompatible(LintId::of(lint)) {
-        let future = if let Some(epoch) = future_incompatible.epoch {
-            format!("the {} epoch", epoch)
+    let lint_id = LintId::of(lint);
+    if let Some(future_incompatible) = lints.future_incompatible(lint_id) {
+        const STANDARD_MESSAGE: &str =
+            "this was previously accepted by the compiler but is being phased out; \
+             it will become a hard error";
+
+        let explanation = if lint_id == LintId::of(::lint::builtin::UNSTABLE_NAME_COLLISION) {
+            "once this method is added to the standard library, \
+             there will be ambiguity here, which will cause a hard error!"
+                .to_owned()
+        } else if let Some(edition) = future_incompatible.edition {
+            format!("{} in the {} edition!", STANDARD_MESSAGE, edition)
         } else {
-            "a future release".to_owned()
+            format!("{} in a future release!", STANDARD_MESSAGE)
         };
-        let explanation = format!("this was previously accepted by the compiler \
-                                   but is being phased out; \
-                                   it will become a hard error in {}!", future);
         let citation = format!("for more information, see {}",
                                future_incompatible.reference);
         err.warn(&explanation);
diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs
index d8a723e184d2c..7dc84b9ca2956 100644
--- a/src/librustc/macros.rs
+++ b/src/librustc/macros.rs
@@ -72,7 +72,7 @@ macro_rules! __impl_stable_hash_field {
 
 #[macro_export]
 macro_rules! impl_stable_hash_for {
-    (enum $enum_name:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* }) => {
+    (enum $enum_name:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* $(,)* }) => {
         impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $enum_name {
             #[inline]
             fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs
index 8c3dfd0bce752..19a7576b7ceac 100644
--- a/src/librustc/middle/const_val.rs
+++ b/src/librustc/middle/const_val.rs
@@ -19,7 +19,7 @@ use graphviz::IntoCow;
 use syntax_pos::Span;
 
 use std::borrow::Cow;
-use std::rc::Rc;
+use rustc_data_structures::sync::Lrc;
 
 pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>;
 
@@ -52,7 +52,7 @@ impl<'tcx> ConstVal<'tcx> {
 #[derive(Clone, Debug)]
 pub struct ConstEvalErr<'tcx> {
     pub span: Span,
-    pub kind: Rc<ErrKind<'tcx>>,
+    pub kind: Lrc<ErrKind<'tcx>>,
 }
 
 #[derive(Clone, Debug)]
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 3c451d7ae46a1..add9b621596b6 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -132,7 +132,13 @@ pub struct NativeLibrary {
     pub kind: NativeLibraryKind,
     pub name: Symbol,
     pub cfg: Option<ast::MetaItem>,
+    pub foreign_module: Option<DefId>,
+}
+
+#[derive(Clone, Hash, RustcEncodable, RustcDecodable)]
+pub struct ForeignModule {
     pub foreign_items: Vec<DefId>,
+    pub def_id: DefId,
 }
 
 pub enum LoadedMacro {
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 1ff9c7a86291e..abd52624c30d4 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -318,6 +318,11 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt,
         return true;
     }
 
+    // These constants are special for wasm
+    if attr::contains_name(attrs, "wasm_custom_section") {
+        return true;
+    }
+
     tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow
 }
 
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index d13b16dce8986..966353b53a95a 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -402,12 +402,10 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
 
 fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
     for pat in &arm.pats {
-        // for struct patterns, take note of which fields used shorthand (`x`
-        // rather than `x: x`)
+        // for struct patterns, take note of which fields used shorthand (`x` rather than `x: x`)
         //
-        // FIXME: according to the rust-lang-nursery/rustc-guide book and
-        // librustc/README.md, `NodeId`s are to be phased out in favor of
-        // `HirId`s; however, we need to match the signature of `each_binding`,
+        // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be phased
+        // out in favor of `HirId`s; however, we need to match the signature of `each_binding`,
         // which uses `NodeIds`.
         let mut shorthand_field_ids = NodeSet();
         if let hir::PatKind::Struct(_, ref fields, _) = pat.node {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index c73930553cdea..c7396b34c4689 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -11,8 +11,10 @@
 //! This file builds up the `ScopeTree`, which describes
 //! the parent links in the region hierarchy.
 //!
-//! Most of the documentation on regions can be found in
-//! `middle/infer/region_constraints/README.md`
+//! For more information about how MIR-based region-checking works,
+//! see the [rustc guide].
+//!
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
 
 use ich::{StableHashingContext, NodeIdHashingMode};
 use util::nodemap::{FxHashMap, FxHashSet};
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 0aa750aba0660..ceda72dcd7ae0 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -31,6 +31,7 @@ use syntax::ptr::P;
 use syntax_pos::Span;
 use errors::DiagnosticBuilder;
 use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet};
+use session::Session;
 use std::slice;
 use rustc::lint;
 
@@ -468,11 +469,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         match item.node {
             hir::ItemFn(ref decl, _, _, _, ref generics, _) => {
-                self.visit_early_late(None,
-                                      decl,
-                                      generics,
-                                      |this| {
-                                          intravisit::walk_item(this, item);
+                self.visit_early_late(None, decl, generics, |this| {
+                    intravisit::walk_item(this, item);
                 });
             }
 
@@ -505,7 +503,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 } else {
                     0
                 };
-                let lifetimes = generics.lifetimes()
+                let lifetimes = generics
+                    .lifetimes()
                     .map(|def| Region::early(&self.tcx.hir, &mut index, def))
                     .collect();
                 let next_early_index = index + generics.ty_params().count() as u32;
@@ -526,12 +525,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) {
         match item.node {
             hir::ForeignItemFn(ref decl, _, ref generics) => {
-                self.visit_early_late(None,
-                                      decl,
-                                      generics,
-                                      |this| {
-                                          intravisit::walk_foreign_item(this, item);
-                                      })
+                self.visit_early_late(None, decl, generics, |this| {
+                    intravisit::walk_foreign_item(this, item);
+                })
             }
             hir::ForeignItemStatic(..) => {
                 intravisit::walk_foreign_item(self, item);
@@ -586,7 +582,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         // cc #48468
                         self.resolve_elided_lifetimes(slice::from_ref(lifetime), false)
                     }
-                    LifetimeName::Static | LifetimeName::Name(_) => {
+                    LifetimeName::Fresh(_) | LifetimeName::Static | LifetimeName::Name(_) => {
                         // If the user wrote an explicit name, use that.
                         self.visit_lifetime(lifetime);
                     }
@@ -670,7 +666,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 if let Some(elision_region) = elision {
                     let scope = Scope::Elision {
                         elide: Elide::Exact(elision_region),
-                        s: self.scope
+                        s: self.scope,
                     };
                     self.with(scope, |_old_scope, this| {
                         let scope = Scope::Binder {
@@ -716,12 +712,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     &trait_item.generics,
                     |this| intravisit::walk_trait_item(this, trait_item),
                 );
-            },
+            }
             Type(ref bounds, ref ty) => {
                 let generics = &trait_item.generics;
                 let mut index = self.next_early_index();
                 debug!("visit_ty: index = {}", index);
-                let lifetimes = generics.lifetimes()
+                let lifetimes = generics
+                    .lifetimes()
                     .map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
                     .collect();
 
@@ -741,12 +738,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         this.visit_ty(ty);
                     }
                 });
-            },
+            }
             Const(_, _) => {
                 // Only methods and types support generics.
                 assert!(trait_item.generics.params.is_empty());
                 intravisit::walk_trait_item(self, trait_item);
-            },
+            }
         }
     }
 
@@ -761,12 +758,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     &impl_item.generics,
                     |this| intravisit::walk_impl_item(this, impl_item),
                 )
-            },
+            }
             Type(ref ty) => {
                 let generics = &impl_item.generics;
                 let mut index = self.next_early_index();
                 debug!("visit_ty: index = {}", index);
-                let lifetimes = generics.lifetimes()
+                let lifetimes = generics
+                    .lifetimes()
                     .map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
                     .collect();
 
@@ -781,12 +779,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     this.visit_generics(generics);
                     this.visit_ty(ty);
                 });
-            },
+            }
             Const(_, _) => {
                 // Only methods and types support generics.
                 assert!(impl_item.generics.params.is_empty());
                 intravisit::walk_impl_item(self, impl_item);
-            },
+            }
         }
     }
 
@@ -822,7 +820,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
         check_mixed_explicit_and_in_band_defs(
             self.tcx,
-            &generics.lifetimes().cloned().collect::<Vec<_>>()
+            &generics.lifetimes().cloned().collect::<Vec<_>>(),
         );
         for ty_param in generics.ty_params() {
             walk_list!(self, visit_ty_param_bound, &ty_param.bounds);
@@ -842,7 +840,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         self.trait_ref_hack = true;
                         let next_early_index = self.next_early_index();
                         let scope = Scope::Binder {
-                            lifetimes: bound_generic_params.lifetimes()
+                            lifetimes: bound_generic_params
+                                .lifetimes()
                                 .map(|def| Region::late(&self.tcx.hir, def))
                                 .collect(),
                             s: self.scope,
@@ -890,8 +889,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     ) {
         debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref);
 
-        if !self.trait_ref_hack ||
-            trait_ref.bound_generic_params.iter().any(|p| p.is_lifetime_param())
+        if !self.trait_ref_hack
+            || trait_ref
+                .bound_generic_params
+                .iter()
+                .any(|p| p.is_lifetime_param())
         {
             if self.trait_ref_hack {
                 span_err!(
@@ -903,7 +905,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
             }
             let next_early_index = self.next_early_index();
             let scope = Scope::Binder {
-                lifetimes: trait_ref.bound_generic_params
+                lifetimes: trait_ref
+                    .bound_generic_params
                     .lifetimes()
                     .map(|def| Region::late(&self.tcx.hir, def))
                     .collect(),
@@ -1144,7 +1147,8 @@ fn compute_object_lifetime_defaults(
                         .map(|set| match *set {
                             Set1::Empty => "BaseDefault".to_string(),
                             Set1::One(Region::Static) => "'static".to_string(),
-                            Set1::One(Region::EarlyBound(i, _, _)) => generics.lifetimes()
+                            Set1::One(Region::EarlyBound(i, _, _)) => generics
+                                .lifetimes()
                                 .nth(i as usize)
                                 .unwrap()
                                 .lifetime
@@ -1182,7 +1186,8 @@ fn object_lifetime_defaults_for_item(
         }
     }
 
-    generics.ty_params()
+    generics
+        .ty_params()
         .map(|param| {
             let mut set = Set1::Empty;
 
@@ -1278,17 +1283,21 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                     if let hir::map::NodeLifetime(hir_lifetime) = this.tcx.hir.get(node_id) {
                         let span = hir_lifetime.span;
                         let id = hir_lifetime.id;
-                        debug!("id ={:?} span = {:?} hir_lifetime = {:?}",
-                            node_id,
-                            span,
-                            hir_lifetime);
+                        debug!(
+                            "id ={:?} span = {:?} hir_lifetime = {:?}",
+                            node_id, span, hir_lifetime
+                        );
 
                         this.tcx
-                            .struct_span_lint_node(lint::builtin::SINGLE_USE_LIFETIME,
-                                                   id,
-                                                   span,
-                                                   &format!("lifetime name `{}` only used once",
-                                                   hir_lifetime.name.name()))
+                            .struct_span_lint_node(
+                                lint::builtin::SINGLE_USE_LIFETIME,
+                                id,
+                                span,
+                                &format!(
+                                    "lifetime name `{}` only used once",
+                                    hir_lifetime.name.name()
+                                ),
+                            )
                             .emit();
                     }
                 }
@@ -1379,8 +1388,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                     next_early_index,
                     abstract_type_parent,
                     ..
-                } if (!only_abstract_type_parent || abstract_type_parent)
-                => return next_early_index,
+                } if (!only_abstract_type_parent || abstract_type_parent) =>
+                {
+                    return next_early_index
+                }
 
                 Scope::Binder { s, .. }
                 | Scope::Body { s, .. }
@@ -1698,8 +1709,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
 
             // Foreign functions, `fn(...) -> R` and `Trait(...) -> R` (both types and bounds).
-            hir::map::NodeForeignItem(_) | hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) =>
-                None,
+            hir::map::NodeForeignItem(_) | hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) => None,
             // Everything else (only closures?) doesn't
             // actually enjoy elision in return types.
             _ => {
@@ -1894,7 +1904,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                     lint::builtin::ELIDED_LIFETIME_IN_PATH,
                     id,
                     span,
-                    &format!("hidden lifetime parameters are deprecated, try `Foo<'_>`"))
+                    &format!("hidden lifetime parameters are deprecated, try `Foo<'_>`"),
+                )
                 .emit();
         }
         let error = loop {
@@ -1933,25 +1944,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
         };
 
-        let mut err = struct_span_err!(
-            self.tcx.sess,
-            span,
-            E0106,
-            "missing lifetime specifier{}",
-            if lifetime_refs.len() > 1 { "s" } else { "" }
-        );
-        let msg = if lifetime_refs.len() > 1 {
-            format!("expected {} lifetime parameters", lifetime_refs.len())
-        } else {
-            format!("expected lifetime parameter")
-        };
-        err.span_label(span, msg);
+        let mut err = report_missing_lifetime_specifiers(self.tcx.sess, span, lifetime_refs.len());
 
         if let Some(params) = error {
             if lifetime_refs.len() == 1 {
                 self.report_elision_failure(&mut err, params);
             }
         }
+
         err.emit();
     }
 
@@ -2086,7 +2086,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                         );
                         err.emit();
                     }
-                    hir::LifetimeName::Implicit | hir::LifetimeName::Name(_) => {}
+                    hir::LifetimeName::Fresh(_) | hir::LifetimeName::Implicit |
+                    hir::LifetimeName::Name(_) => {}
                 }
             }
 
@@ -2138,7 +2139,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                             ))
                             .emit();
                     }
-                    hir::LifetimeName::Implicit | hir::LifetimeName::Name(_) => {
+                    hir::LifetimeName::Fresh(_) | hir::LifetimeName::Implicit |
+                    hir::LifetimeName::Name(_) => {
                         self.resolve_lifetime_ref(bound);
                     }
                 }
@@ -2146,9 +2148,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         }
     }
 
-    fn check_lifetime_def_for_shadowing(&self,
-                                        mut old_scope: ScopeRef,
-                                        lifetime: &'tcx hir::Lifetime) {
+    fn check_lifetime_def_for_shadowing(
+        &self,
+        mut old_scope: ScopeRef,
+        lifetime: &'tcx hir::Lifetime,
+    ) {
         for &(label, label_span) in &self.labels_in_fn {
             // FIXME (#24278): non-hygienic comparison
             if lifetime.name.name() == label {
@@ -2216,14 +2220,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         self.map.defs.insert(lifetime_ref.id, def);
 
         match def {
-            Region::LateBoundAnon(..) |
-            Region::Static => {
+            Region::LateBoundAnon(..) | Region::Static => {
                 // These are anonymous lifetimes or lifetimes that are not declared.
             }
 
-            Region::Free(_, def_id) |
-            Region::LateBound(_, def_id, _) |
-            Region::EarlyBound(_, def_id, _) => {
+            Region::Free(_, def_id)
+            | Region::LateBound(_, def_id, _)
+            | Region::EarlyBound(_, def_id, _) => {
                 // A lifetime declared by the user.
                 if !self.lifetime_uses.contains_key(&def_id) {
                     self.lifetime_uses
@@ -2255,8 +2258,7 @@ fn insert_late_bound_lifetimes(
 ) {
     debug!(
         "insert_late_bound_lifetimes(decl={:?}, generics={:?})",
-        decl,
-        generics
+        decl, generics
     );
 
     let mut constrained_by_input = ConstrainedCollector {
@@ -2335,8 +2337,7 @@ fn insert_late_bound_lifetimes(
         debug!(
             "insert_late_bound_lifetimes: \
              lifetime {:?} with id {:?} is late-bound",
-            lifetime.lifetime.name,
-            lifetime.lifetime.id
+            lifetime.lifetime.name, lifetime.lifetime.id
         );
 
         let inserted = map.late_bound.insert(lifetime.lifetime.id);
@@ -2403,3 +2404,27 @@ fn insert_late_bound_lifetimes(
         }
     }
 }
+
+pub fn report_missing_lifetime_specifiers(
+    sess: &Session,
+    span: Span,
+    count: usize,
+) -> DiagnosticBuilder<'_> {
+    let mut err = struct_span_err!(
+        sess,
+        span,
+        E0106,
+        "missing lifetime specifier{}",
+        if count > 1 { "s" } else { "" }
+    );
+
+    let msg = if count > 1 {
+        format!("expected {} lifetime parameters", count)
+    } else {
+        format!("expected lifetime parameter")
+    };
+
+    err.span_label(span, msg);
+
+    err
+}
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 16c33d6bd837d..29c8ac046b815 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -474,6 +474,22 @@ struct Checker<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
+/// Result of `TyCtxt::eval_stability`.
+pub enum EvalResult {
+    /// We can use the item because it is stable or we provided the
+    /// corresponding feature gate.
+    Allow,
+    /// We cannot use the item because it is unstable and we did not provide the
+    /// corresponding feature gate.
+    Deny {
+        feature: Symbol,
+        reason: Option<Symbol>,
+        issue: u32,
+    },
+    /// The item does not have the `#[stable]` or `#[unstable]` marker assigned.
+    Unmarked,
+}
+
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     // (See issue #38412)
     fn skip_stability_check_due_to_privacy(self, mut def_id: DefId) -> bool {
@@ -509,14 +525,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
-    pub fn check_stability(self, def_id: DefId, id: NodeId, span: Span) {
+    /// Evaluates the stability of an item.
+    ///
+    /// Returns `EvalResult::Allow` if the item is stable, or unstable but the corresponding
+    /// `#![feature]` has been provided. Returns `EvalResult::Deny` which describes the offending
+    /// unstable feature otherwise.
+    ///
+    /// If `id` is `Some(_)`, this function will also check if the item at `def_id` has been
+    /// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
+    /// `id`.
+    pub fn eval_stability(self, def_id: DefId, id: Option<NodeId>, span: Span) -> EvalResult {
         if span.allows_unstable() {
             debug!("stability: \
                     skipping span={:?} since it is internal", span);
-            return;
+            return EvalResult::Allow;
         }
 
-        let lint_deprecated = |def_id: DefId, note: Option<Symbol>| {
+        let lint_deprecated = |def_id: DefId, id: NodeId, note: Option<Symbol>| {
             let path = self.item_path_str(def_id);
 
             let msg = if let Some(note) = note {
@@ -526,22 +551,21 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             };
 
             self.lint_node(lint::builtin::DEPRECATED, id, span, &msg);
+            if id == ast::DUMMY_NODE_ID {
+                span_bug!(span, "emitted a deprecated lint with dummy node id: {:?}", def_id);
+            }
         };
 
         // Deprecated attributes apply in-crate and cross-crate.
-        if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
-            let skip = if id == ast::DUMMY_NODE_ID {
-                true
-            } else {
+        if let Some(id) = id {
+            if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
                 let parent_def_id = self.hir.local_def_id(self.hir.get_parent(id));
-                self.lookup_deprecation_entry(parent_def_id).map_or(false, |parent_depr| {
-                    parent_depr.same_origin(&depr_entry)
-                })
+                let skip = self.lookup_deprecation_entry(parent_def_id)
+                    .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
+                if !skip {
+                    lint_deprecated(def_id, id, depr_entry.attr.note);
+                }
             };
-
-            if !skip {
-                lint_deprecated(def_id, depr_entry.attr.note);
-            }
         }
 
         let is_staged_api = self.lookup_stability(DefId {
@@ -549,7 +573,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             ..def_id
         }).is_some();
         if !is_staged_api {
-            return;
+            return EvalResult::Allow;
         }
 
         let stability = self.lookup_stability(def_id);
@@ -558,26 +582,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
         if let Some(&Stability{rustc_depr: Some(attr::RustcDeprecation { reason, .. }), ..})
                 = stability {
-            if id != ast::DUMMY_NODE_ID {
-                lint_deprecated(def_id, Some(reason));
+            if let Some(id) = id {
+                lint_deprecated(def_id, id, Some(reason));
             }
         }
 
         // Only the cross-crate scenario matters when checking unstable APIs
         let cross_crate = !def_id.is_local();
         if !cross_crate {
-            return
+            return EvalResult::Allow;
         }
 
         // Issue 38412: private items lack stability markers.
         if self.skip_stability_check_due_to_privacy(def_id) {
-            return
+            return EvalResult::Allow;
         }
 
         match stability {
-            Some(&Stability { level: attr::Unstable {ref reason, issue}, ref feature, .. }) => {
-                if self.stability().active_features.contains(feature) {
-                    return
+            Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => {
+                if self.stability().active_features.contains(&feature) {
+                    return EvalResult::Allow;
                 }
 
                 // When we're compiling the compiler itself we may pull in
@@ -589,19 +613,41 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 // the `-Z force-unstable-if-unmarked` flag present (we're
                 // compiling a compiler crate), then let this missing feature
                 // annotation slide.
-                if *feature == "rustc_private" && issue == 27812 {
+                if feature == "rustc_private" && issue == 27812 {
                     if self.sess.opts.debugging_opts.force_unstable_if_unmarked {
-                        return
+                        return EvalResult::Allow;
                     }
                 }
 
-                let msg = match *reason {
-                    Some(ref r) => format!("use of unstable library feature '{}': {}",
-                                           feature.as_str(), &r),
+                EvalResult::Deny { feature, reason, issue }
+            }
+            Some(_) => {
+                // Stable APIs are always ok to call and deprecated APIs are
+                // handled by the lint emitting logic above.
+                EvalResult::Allow
+            }
+            None => {
+                EvalResult::Unmarked
+            }
+        }
+    }
+
+    /// Checks if an item is stable or error out.
+    ///
+    /// If the item defined by `def_id` is unstable and the corresponding `#![feature]` does not
+    /// exist, emits an error.
+    ///
+    /// Additionally, this function will also check if the item is deprecated. If so, and `id` is
+    /// not `None`, a deprecated lint attached to `id` will be emitted.
+    pub fn check_stability(self, def_id: DefId, id: Option<NodeId>, span: Span) {
+        match self.eval_stability(def_id, id, span) {
+            EvalResult::Allow => {}
+            EvalResult::Deny { feature, reason, issue } => {
+                let msg = match reason {
+                    Some(r) => format!("use of unstable library feature '{}': {}", feature, r),
                     None => format!("use of unstable library feature '{}'", &feature)
                 };
 
-
                 let msp: MultiSpan = span.into();
                 let cm = &self.sess.parse_sess.codemap();
                 let span_key = msp.primary_span().and_then(|sp: Span|
@@ -624,12 +670,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                                      GateIssue::Library(Some(issue)), &msg);
                 }
             }
-            Some(_) => {
-                // Stable APIs are always ok to call and deprecated APIs are
-                // handled by the lint emitting logic above.
-            }
-            None => {
-                span_bug!(span, "encountered unmarked API");
+            EvalResult::Unmarked => {
+                span_bug!(span, "encountered unmarked API: {:?}", def_id);
             }
         }
     }
@@ -655,7 +697,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                     None => return,
                 };
                 let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
-                self.tcx.check_stability(def_id, item.id, item.span);
+                self.tcx.check_stability(def_id, Some(item.id), item.span);
             }
 
             // For implementations of traits, check the stability of each item
@@ -668,8 +710,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                         let trait_item_def_id = self.tcx.associated_items(trait_did)
                             .find(|item| item.name == impl_item.name).map(|item| item.def_id);
                         if let Some(def_id) = trait_item_def_id {
-                            // Pass `DUMMY_NODE_ID` to skip deprecation warnings.
-                            self.tcx.check_stability(def_id, ast::DUMMY_NODE_ID, impl_item.span);
+                            // Pass `None` to skip deprecation warnings.
+                            self.tcx.check_stability(def_id, None, impl_item.span);
                         }
                     }
                 }
@@ -705,7 +747,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
         match path.def {
             Def::Local(..) | Def::Upvar(..) |
             Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => {}
-            _ => self.tcx.check_stability(path.def.def_id(), id, path.span)
+            _ => self.tcx.check_stability(path.def.def_id(), Some(id), path.span)
         }
         intravisit::walk_path(self, path)
     }
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index 67f30f53a6810..e242ec4985ab4 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -15,11 +15,13 @@ pub use self::value::{PrimVal, PrimValKind, Value, Pointer};
 use std::collections::BTreeMap;
 use std::fmt;
 use mir;
-use ty;
+use hir::def_id::DefId;
+use ty::{self, TyCtxt};
 use ty::layout::{self, Align, HasDataLayout};
 use middle::region;
 use std::iter;
 use syntax::ast::Mutability;
+use rustc_serialize::{Encoder, Decoder, Decodable, Encodable};
 
 #[derive(Clone, Debug, PartialEq)]
 pub enum Lock {
@@ -152,6 +154,98 @@ pub struct AllocId(pub u64);
 impl ::rustc_serialize::UseSpecializedEncodable for AllocId {}
 impl ::rustc_serialize::UseSpecializedDecodable for AllocId {}
 
+pub const ALLOC_DISCRIMINANT: usize = 0;
+pub const FN_DISCRIMINANT: usize = 1;
+pub const EXTERN_STATIC_DISCRIMINANT: usize = 2;
+pub const SHORTHAND_START: usize = 3;
+
+pub fn specialized_encode_alloc_id<
+    'a, 'tcx,
+    E: Encoder,
+>(
+    encoder: &mut E,
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    alloc_id: AllocId,
+    shorthand: Option<usize>,
+) -> Result<(), E::Error> {
+    if let Some(shorthand) = shorthand {
+        return shorthand.encode(encoder);
+    }
+    if let Some(alloc) = tcx.interpret_interner.get_alloc(alloc_id) {
+        trace!("encoding {:?} with {:#?}", alloc_id, alloc);
+        ALLOC_DISCRIMINANT.encode(encoder)?;
+        alloc.encode(encoder)?;
+        // encode whether this allocation is the root allocation of a static
+        tcx.interpret_interner
+            .get_corresponding_static_def_id(alloc_id)
+            .encode(encoder)?;
+    } else if let Some(fn_instance) = tcx.interpret_interner.get_fn(alloc_id) {
+        trace!("encoding {:?} with {:#?}", alloc_id, fn_instance);
+        FN_DISCRIMINANT.encode(encoder)?;
+        fn_instance.encode(encoder)?;
+    } else if let Some(did) = tcx.interpret_interner.get_corresponding_static_def_id(alloc_id) {
+        // extern "C" statics don't have allocations, just encode its def_id
+        EXTERN_STATIC_DISCRIMINANT.encode(encoder)?;
+        did.encode(encoder)?;
+    } else {
+        bug!("alloc id without corresponding allocation: {}", alloc_id);
+    }
+    Ok(())
+}
+
+pub fn specialized_decode_alloc_id<
+    'a, 'tcx,
+    D: Decoder,
+    CACHE: FnOnce(&mut D, usize, AllocId),
+    SHORT: FnOnce(&mut D, usize) -> Result<AllocId, D::Error>
+>(
+    decoder: &mut D,
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    pos: usize,
+    cache: CACHE,
+    short: SHORT,
+) -> Result<AllocId, D::Error> {
+    match usize::decode(decoder)? {
+        ALLOC_DISCRIMINANT => {
+            let alloc_id = tcx.interpret_interner.reserve();
+            trace!("creating alloc id {:?} at {}", alloc_id, pos);
+            // insert early to allow recursive allocs
+            cache(decoder, pos, alloc_id);
+
+            let allocation = Allocation::decode(decoder)?;
+            trace!("decoded alloc {:?} {:#?}", alloc_id, allocation);
+            let allocation = tcx.intern_const_alloc(allocation);
+            tcx.interpret_interner.intern_at_reserved(alloc_id, allocation);
+
+            if let Some(glob) = Option::<DefId>::decode(decoder)? {
+                tcx.interpret_interner.cache(glob, alloc_id);
+            }
+
+            Ok(alloc_id)
+        },
+        FN_DISCRIMINANT => {
+            trace!("creating fn alloc id at {}", pos);
+            let instance = ty::Instance::decode(decoder)?;
+            trace!("decoded fn alloc instance: {:?}", instance);
+            let id = tcx.interpret_interner.create_fn_alloc(instance);
+            trace!("created fn alloc id: {:?}", id);
+            cache(decoder, pos, id);
+            Ok(id)
+        },
+        EXTERN_STATIC_DISCRIMINANT => {
+            trace!("creating extern static alloc id at {}", pos);
+            let did = DefId::decode(decoder)?;
+            let alloc_id = tcx.interpret_interner.reserve();
+            tcx.interpret_interner.cache(did, alloc_id);
+            Ok(alloc_id)
+        },
+        shorthand => {
+            trace!("loading shorthand {}", shorthand);
+            short(decoder, shorthand)
+        },
+    }
+}
+
 impl fmt::Display for AllocId {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{}", self.0)
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 939710ffd2b86..9ed4e6a8e00ae 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! MIR datatypes and passes. See the module-level [README] for details.
+//! MIR datatypes and passes. See the [rustc guide] for more info.
 //!
-//! [README]: https://github.com/rust-lang/rust/blob/master/src/librustc/mir/README.md
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir.html
 
 use graphviz::IntoCow;
 use middle::const_val::ConstVal;
@@ -27,7 +27,7 @@ use hir::def_id::DefId;
 use mir::visit::MirVisitable;
 use mir::interpret::{Value, PrimVal};
 use ty::subst::{Subst, Substs};
-use ty::{self, AdtDef, ClosureSubsts, Region, Ty, TyCtxt, GeneratorInterior};
+use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, Region, Ty, TyCtxt, GeneratorInterior};
 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use ty::TypeAndMut;
 use util::ppaux;
@@ -1253,6 +1253,23 @@ pub enum StatementKind<'tcx> {
     /// (The starting point(s) arise implicitly from borrows.)
     EndRegion(region::Scope),
 
+    /// Encodes a user's type assertion. These need to be preserved intact so that NLL can respect
+    /// them. For example:
+    ///
+    ///     let (a, b): (T, U) = y;
+    ///
+    /// Here we would insert a `UserAssertTy<(T, U)>(y)` instruction to check that the type of `y`
+    /// is the right thing.
+    ///
+    /// `CanonicalTy` is used to capture "inference variables" from the user's types. For example:
+    ///
+    ///     let x: Vec<_> = ...;
+    ///     let y: &u32 = ...;
+    ///
+    /// would result in `Vec<?0>` and `&'?0 u32` respectively (where `?0` is a canonicalized
+    /// variable).
+    UserAssertTy(CanonicalTy<'tcx>, Local),
+
     /// No-op. Useful for deleting instructions without affecting statement indices.
     Nop,
 }
@@ -1324,6 +1341,8 @@ impl<'tcx> Debug for Statement<'tcx> {
             InlineAsm { ref asm, ref outputs, ref inputs } => {
                 write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)
             },
+            UserAssertTy(ref c_ty, ref local) => write!(fmt, "UserAssertTy({:?}, {:?})",
+                                                        c_ty, local),
             Nop => write!(fmt, "nop"),
         }
     }
@@ -2184,6 +2203,7 @@ EnumTypeFoldableImpl! {
         (StatementKind::InlineAsm) { asm, outputs, inputs },
         (StatementKind::Validate)(a, b),
         (StatementKind::EndRegion)(a),
+        (StatementKind::UserAssertTy)(a, b),
         (StatementKind::Nop),
     }
 }
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 650af8dc4d903..a3fdb6f73abb0 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -10,7 +10,7 @@
 
 use hir::def_id::DefId;
 use ty::subst::Substs;
-use ty::{ClosureSubsts, Region, Ty, GeneratorInterior};
+use ty::{CanonicalTy, ClosureSubsts, Region, Ty, GeneratorInterior};
 use mir::*;
 use syntax_pos::Span;
 
@@ -144,6 +144,13 @@ macro_rules! make_mir_visitor {
                 self.super_operand(operand, location);
             }
 
+            fn visit_user_assert_ty(&mut self,
+                                    c_ty: & $($mutability)* CanonicalTy<'tcx>,
+                                    local: & $($mutability)* Local,
+                                    location: Location) {
+                self.super_user_assert_ty(c_ty, local, location);
+            }
+
             fn visit_place(&mut self,
                             place: & $($mutability)* Place<'tcx>,
                             context: PlaceContext<'tcx>,
@@ -376,6 +383,10 @@ macro_rules! make_mir_visitor {
                             self.visit_operand(input, location);
                         }
                     }
+                    StatementKind::UserAssertTy(ref $($mutability)* c_ty,
+                                                ref $($mutability)* local) => {
+                        self.visit_user_assert_ty(c_ty, local, location);
+                    }
                     StatementKind::Nop => {}
                 }
             }
@@ -619,6 +630,13 @@ macro_rules! make_mir_visitor {
                 }
             }
 
+            fn super_user_assert_ty(&mut self,
+                                    _c_ty: & $($mutability)* CanonicalTy<'tcx>,
+                                    local: & $($mutability)* Local,
+                                    location: Location) {
+                self.visit_local(local, PlaceContext::Validate, location);
+            }
+
             fn super_place(&mut self,
                             place: & $($mutability)* Place<'tcx>,
                             context: PlaceContext<'tcx>,
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 2cf09a002c9f5..59d1a298eaa69 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -21,14 +21,14 @@ use session::search_paths::SearchPaths;
 
 use ich::StableHashingContext;
 use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel};
-use rustc_back::target::Target;
+use rustc_back::target::{Target, TargetTriple};
 use rustc_data_structures::stable_hasher::ToStableHashKey;
 use lint;
 use middle::cstore;
 
 use syntax::ast::{self, IntTy, UintTy};
 use syntax::codemap::{FileName, FilePathMapping};
-use syntax::epoch::Epoch;
+use syntax::edition::Edition;
 use syntax::parse::token;
 use syntax::parse;
 use syntax::symbol::Symbol;
@@ -47,7 +47,7 @@ use std::hash::Hasher;
 use std::collections::hash_map::DefaultHasher;
 use std::collections::HashSet;
 use std::iter::FromIterator;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 
 pub struct Config {
     pub target: Target,
@@ -367,7 +367,7 @@ top_level_options!(
         libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
         maybe_sysroot: Option<PathBuf> [TRACKED],
 
-        target_triple: String [TRACKED],
+        target_triple: TargetTriple [TRACKED],
 
         test: bool [TRACKED],
         error_format: ErrorOutputType [UNTRACKED],
@@ -385,7 +385,7 @@ top_level_options!(
         externs: Externs [UNTRACKED],
         crate_name: Option<String> [TRACKED],
         // An optional name to use as the crate for std during std injection,
-        // written `extern crate std = "name"`. Default to "std". Used by
+        // written `extern crate name as std`. Defaults to `std`. Used by
         // out-of-tree drivers.
         alt_std_name: Option<String> [TRACKED],
         // Indicates how the compiler should treat unstable features
@@ -567,7 +567,7 @@ pub fn basic_options() -> Options {
         output_types: OutputTypes(BTreeMap::new()),
         search_paths: SearchPaths::new(),
         maybe_sysroot: None,
-        target_triple: host_triple().to_string(),
+        target_triple: TargetTriple::from_triple(host_triple()),
         test: false,
         incremental: None,
         debugging_opts: basic_debugging_options(),
@@ -771,7 +771,7 @@ macro_rules! options {
             Some("`string` or `string=string`");
         pub const parse_lto: Option<&'static str> =
             Some("one of `thin`, `fat`, or omitted");
-        pub const parse_epoch: Option<&'static str> =
+        pub const parse_edition: Option<&'static str> =
             Some("one of: `2015`, `2018`");
     }
 
@@ -780,7 +780,7 @@ macro_rules! options {
         use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto};
         use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel};
         use std::path::PathBuf;
-        use syntax::epoch::Epoch;
+        use syntax::edition::Edition;
 
         $(
             pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
@@ -983,11 +983,11 @@ macro_rules! options {
             true
         }
 
-        fn parse_epoch(slot: &mut Epoch, v: Option<&str>) -> bool {
+        fn parse_edition(slot: &mut Edition, v: Option<&str>) -> bool {
             match v {
                 Some(s) => {
-                    let epoch = s.parse();
-                    if let Ok(parsed) = epoch {
+                    let edition = s.parse();
+                    if let Ok(parsed) = edition {
                         *slot = parsed;
                         true
                     } else {
@@ -1208,6 +1208,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
           "set the MIR optimization level (0-3, default: 1)"),
     mutable_noalias: bool = (false, parse_bool, [UNTRACKED],
           "emit noalias metadata for mutable references"),
+    arg_align_attributes: bool = (false, parse_bool, [UNTRACKED],
+          "emit align metadata for reference arguments"),
     dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED],
           "dump MIR state at various points in translation"),
     dump_mir_dir: String = (String::from("mir_dump"), parse_string, [UNTRACKED],
@@ -1247,10 +1249,20 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "extra arguments to prepend to the linker invocation (space separated)"),
     profile: bool = (false, parse_bool, [TRACKED],
                      "insert profiling code"),
+    pgo_gen: Option<String> = (None, parse_opt_string, [TRACKED],
+        "Generate PGO profile data, to a given file, or to the default \
+         location if it's empty."),
+    pgo_use: String = (String::new(), parse_string, [TRACKED],
+        "Use PGO profile data from the given profile file."),
+    disable_instrumentation_preinliner: bool =
+        (false, parse_bool, [TRACKED], "Disable the instrumentation pre-inliner, \
+        useful for profiling / PGO."),
     relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
         "choose which RELRO level to use"),
     nll: bool = (false, parse_bool, [UNTRACKED],
                  "run the non-lexical lifetimes MIR pass"),
+    disable_nll_user_type_assert: bool = (false, parse_bool, [UNTRACKED],
+        "disable user provided type assertion in NLL"),
     trans_time_graph: bool = (false, parse_bool, [UNTRACKED],
         "generate a graphical HTML report of time spent in trans and LLVM"),
     thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
@@ -1280,16 +1292,18 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         `everybody_loops` (all function bodies replaced with `loop {}`),
         `hir` (the HIR), `hir,identified`, or
         `hir,typed` (HIR with types for each node)."),
-    epoch: Epoch = (Epoch::Epoch2015, parse_epoch, [TRACKED],
-        "The epoch to build Rust with. Newer epochs may include features
-         that require breaking changes. The default epoch is 2015 (the first
-         epoch). Crates compiled with different epochs can be linked together."),
+    edition: Edition = (Edition::Edition2015, parse_edition, [TRACKED],
+        "The edition to build Rust with. Newer editions may include features
+         that require breaking changes. The default edition is 2015 (the first
+         edition). Crates compiled with different editions can be linked together."),
     run_dsymutil: Option<bool> = (None, parse_opt_bool, [TRACKED],
           "run `dsymutil` and delete intermediate object files"),
     ui_testing: bool = (false, parse_bool, [UNTRACKED],
           "format compiler diagnostics in a way that's better suitable for UI testing"),
     embed_bitcode: bool = (false, parse_bool, [TRACKED],
           "embed LLVM bitcode in object files"),
+    strip_debuginfo_if_disabled: Option<bool> = (None, parse_opt_bool, [TRACKED],
+        "tell the linker to strip debuginfo when building without debuginfo enabled."),
 }
 
 pub fn default_lib_output() -> CrateType {
@@ -1767,6 +1781,13 @@ pub fn build_session_options_and_crate_config(
         );
     }
 
+    if debugging_opts.pgo_gen.is_some() && !debugging_opts.pgo_use.is_empty() {
+        early_error(
+            error_format,
+            "options `-Z pgo-gen` and `-Z pgo-use` are exclusive",
+        );
+    }
+
     let mut output_types = BTreeMap::new();
     if !debugging_opts.parse_only {
         for list in matches.opt_strs("emit") {
@@ -1901,9 +1922,21 @@ pub fn build_session_options_and_crate_config(
     let cg = cg;
 
     let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
-    let target = matches
-        .opt_str("target")
-        .unwrap_or(host_triple().to_string());
+    let target_triple = if let Some(target) = matches.opt_str("target") {
+        if target.ends_with(".json") {
+            let path = Path::new(&target);
+            match TargetTriple::from_path(&path) {
+                Ok(triple) => triple,
+                Err(_) => {
+                    early_error(error_format, &format!("target file {:?} does not exist", path))
+                }
+            }
+        } else {
+            TargetTriple::TargetTriple(target)
+        }
+    } else {
+        TargetTriple::from_triple(host_triple())
+    };
     let opt_level = {
         if matches.opt_present("O") {
             if cg.opt_level.is_some() {
@@ -2111,7 +2144,7 @@ pub fn build_session_options_and_crate_config(
             output_types: OutputTypes(output_types),
             search_paths,
             maybe_sysroot: sysroot_opt,
-            target_triple: target,
+            target_triple,
             test,
             incremental,
             debugging_opts,
@@ -2258,10 +2291,11 @@ mod dep_tracking {
     use std::hash::Hash;
     use std::path::PathBuf;
     use std::collections::hash_map::DefaultHasher;
-    use super::{CrateType, DebugInfoLevel, Epoch, ErrorOutputType, Lto, OptLevel, OutputTypes,
+    use super::{CrateType, DebugInfoLevel, Edition, ErrorOutputType, Lto, OptLevel, OutputTypes,
                 Passes, Sanitizer};
     use syntax::feature_gate::UnstableFeatures;
     use rustc_back::{PanicStrategy, RelroLevel};
+    use rustc_back::target::TargetTriple;
 
     pub trait DepTrackingHash {
         fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType);
@@ -2320,7 +2354,8 @@ mod dep_tracking {
     impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind);
     impl_dep_tracking_hash_via_hash!(Sanitizer);
     impl_dep_tracking_hash_via_hash!(Option<Sanitizer>);
-    impl_dep_tracking_hash_via_hash!(Epoch);
+    impl_dep_tracking_hash_via_hash!(Edition);
+    impl_dep_tracking_hash_via_hash!(TargetTriple);
 
     impl_dep_tracking_hash_for_sortable_vec_of!(String);
     impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
@@ -2880,6 +2915,14 @@ mod tests {
         opts.debugging_opts.tls_model = Some(String::from("tls model"));
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
+        opts = reference.clone();
+        opts.debugging_opts.pgo_gen = Some(String::from("abc"));
+        assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
+
+        opts = reference.clone();
+        opts.debugging_opts.pgo_use = String::from("abc");
+        assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
+
         opts = reference.clone();
         opts.cg.metadata = vec![String::from("A"), String::from("B")];
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 3f52ecfc0999b..77cf50a8341ed 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -31,7 +31,7 @@ use rustc_data_structures::sync::{Lrc, Lock};
 use syntax::ast::NodeId;
 use errors::{self, DiagnosticBuilder, DiagnosticId};
 use errors::emitter::{Emitter, EmitterWriter};
-use syntax::epoch::Epoch;
+use syntax::edition::Edition;
 use syntax::json::JsonEmitter;
 use syntax::feature_gate;
 use syntax::symbol::Symbol;
@@ -42,7 +42,7 @@ use syntax::feature_gate::AttributeType;
 use syntax_pos::{MultiSpan, Span};
 
 use rustc_back::{LinkerFlavor, PanicStrategy};
-use rustc_back::target::Target;
+use rustc_back::target::{Target, TargetTriple};
 use rustc_data_structures::flock;
 use jobserver::Client;
 
@@ -707,7 +707,7 @@ impl Session {
     pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch {
         filesearch::FileSearch::new(
             self.sysroot(),
-            &self.opts.target_triple,
+            self.opts.target_triple.triple(),
             &self.opts.search_paths,
             kind,
         )
@@ -976,13 +976,13 @@ impl Session {
         self.opts.debugging_opts.teach && !self.parse_sess.span_diagnostic.code_emitted(code)
     }
 
-    /// Are we allowed to use features from the Rust 2018 epoch?
+    /// Are we allowed to use features from the Rust 2018 edition?
     pub fn rust_2018(&self) -> bool {
-        self.opts.debugging_opts.epoch >= Epoch::Epoch2018
+        self.opts.debugging_opts.edition >= Edition::Edition2018
     }
 
-    pub fn epoch(&self) -> Epoch {
-        self.opts.debugging_opts.epoch
+    pub fn edition(&self) -> Edition {
+        self.opts.debugging_opts.edition
     }
 }
 
@@ -1085,7 +1085,8 @@ pub fn build_session_(
     span_diagnostic: errors::Handler,
     codemap: Lrc<codemap::CodeMap>,
 ) -> Session {
-    let host = match Target::search(config::host_triple()) {
+    let host_triple = TargetTriple::from_triple(config::host_triple());
+    let host = match Target::search(&host_triple) {
         Ok(t) => t,
         Err(e) => {
             span_diagnostic
diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs
new file mode 100644
index 0000000000000..8eee6f35ab956
--- /dev/null
+++ b/src/librustc/traits/engine.rs
@@ -0,0 +1,71 @@
+// Copyright 2018 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 infer::InferCtxt;
+use ty::{self, Ty, TyCtxt};
+use hir::def_id::DefId;
+
+use super::{FulfillmentContext, FulfillmentError};
+use super::{ObligationCause, PendingPredicateObligation, PredicateObligation};
+
+pub trait TraitEngine<'tcx>: 'tcx {
+    fn normalize_projection_type<'a, 'gcx>(
+        &mut self,
+        infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        projection_ty: ty::ProjectionTy<'tcx>,
+        cause: ObligationCause<'tcx>,
+    ) -> Ty<'tcx>;
+
+    fn register_bound<'a, 'gcx>(
+        &mut self,
+        infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        ty: Ty<'tcx>,
+        def_id: DefId,
+        cause: ObligationCause<'tcx>,
+    );
+
+    fn register_predicate_obligation<'a, 'gcx>(
+        &mut self,
+        infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+        obligation: PredicateObligation<'tcx>,
+    );
+
+    fn select_all_or_error<'a, 'gcx>(
+        &mut self,
+        infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+    ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
+
+    fn select_where_possible<'a, 'gcx>(
+        &mut self,
+        infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+    ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
+
+    fn pending_obligations(&self) -> Vec<PendingPredicateObligation<'tcx>>;
+}
+
+impl<'a, 'gcx, 'tcx> dyn TraitEngine<'tcx> {
+    pub fn new(_tcx: TyCtxt<'_, '_, 'tcx>) -> Box<Self> {
+        Box::new(FulfillmentContext::new())
+    }
+
+    pub fn register_predicate_obligations<I>(
+        &mut self,
+        infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+        obligations: I,
+    ) where
+        I: IntoIterator<Item = PredicateObligation<'tcx>>,
+    {
+        for obligation in obligations {
+            self.register_predicate_obligation(infcx, obligation);
+        }
+    }
+}
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 7e5dc02798dff..e640cc315c44d 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -443,10 +443,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         } else {
             4
         };
+
+        let normalize = |candidate| self.tcx.global_tcx().infer_ctxt().enter(|ref infcx| {
+            let normalized = infcx
+                .at(&ObligationCause::dummy(), ty::ParamEnv::empty())
+                .normalize(candidate)
+                .ok();
+            match normalized {
+                Some(normalized) => format!("\n  {:?}", normalized.value),
+                None => format!("\n  {:?}", candidate),
+            }
+        });
+
         err.help(&format!("the following implementations were found:{}{}",
-                          &impl_candidates[0..end].iter().map(|candidate| {
-                              format!("\n  {:?}", candidate)
-                          }).collect::<String>(),
+                          &impl_candidates[0..end].iter().map(normalize).collect::<String>(),
                           if impl_candidates.len() > 5 {
                               format!("\nand {} others", impl_candidates.len() - 4)
                           } else {
@@ -585,20 +595,23 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                          trait_ref.to_predicate(), post_message)
                             }));
 
+                        let explanation =
+                            if obligation.cause.code == ObligationCauseCode::MainFunctionType {
+                                "consider using `()`, or a `Result`".to_owned()
+                            } else {
+                                format!("{}the trait `{}` is not implemented for `{}`",
+                                        pre_message,
+                                        trait_ref,
+                                        trait_ref.self_ty())
+                            };
+
                         if let Some(ref s) = label {
                             // If it has a custom "#[rustc_on_unimplemented]"
                             // error message, let's display it as the label!
                             err.span_label(span, s.as_str());
-                            err.help(&format!("{}the trait `{}` is not implemented for `{}`",
-                                              pre_message,
-                                              trait_ref,
-                                              trait_ref.self_ty()));
+                            err.help(&explanation);
                         } else {
-                            err.span_label(span,
-                                           &*format!("{}the trait `{}` is not implemented for `{}`",
-                                                     pre_message,
-                                                     trait_ref,
-                                                     trait_ref.self_ty()));
+                            err.span_label(span, explanation);
                         }
                         if let Some(ref s) = note {
                             // If it has a custom "#[rustc_on_unimplemented]" note, let's display it
@@ -606,6 +619,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                         }
 
                         self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
+                        self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
 
                         // Try to report a help message
                         if !trait_ref.has_infer_types() &&
@@ -844,6 +858,54 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
+    /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`,
+    /// suggest removing these references until we reach a type that implements the trait.
+    fn suggest_remove_reference(&self,
+                                obligation: &PredicateObligation<'tcx>,
+                                err: &mut DiagnosticBuilder<'tcx>,
+                                trait_ref: &ty::Binder<ty::TraitRef<'tcx>>) {
+        let ty::Binder(trait_ref) = trait_ref;
+        let span = obligation.cause.span;
+
+        if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) {
+            let refs_number = snippet.chars()
+                .filter(|c| !c.is_whitespace())
+                .take_while(|c| *c == '&')
+                .count();
+
+            let mut trait_type = trait_ref.self_ty();
+            let mut selcx = SelectionContext::new(self);
+
+            for refs_remaining in 0..refs_number {
+                if let ty::TypeVariants::TyRef(_, ty::TypeAndMut{ ty: t_type, mutbl: _ }) =
+                    trait_type.sty {
+
+                    trait_type = t_type;
+
+                    let substs = self.tcx.mk_substs_trait(trait_type, &[]);
+                    let new_trait_ref = ty::TraitRef::new(trait_ref.def_id, substs);
+                    let new_obligation = Obligation::new(ObligationCause::dummy(),
+                                                         obligation.param_env,
+                                                         new_trait_ref.to_predicate());
+
+                    if selcx.evaluate_obligation(&new_obligation) {
+                        let sp = self.tcx.sess.codemap()
+                            .span_take_while(span, |c| c.is_whitespace() || *c == '&');
+
+                        let remove_refs = refs_remaining + 1;
+                        let format_str = format!("consider removing {} leading `&`-references",
+                                                 remove_refs);
+
+                        err.span_suggestion_short(sp, &format_str, String::from(""));
+                        break;
+                    }
+                } else {
+                    break;
+                }
+            }
+        }
+    }
+
     /// Given some node representing a fn-like thing in the HIR map,
     /// returns a span and `ArgKind` information that describes the
     /// arguments it expects. This can be supplied to
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 150a2ead9e96d..1c091d68a2ef1 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -21,6 +21,7 @@ use middle::const_val::{ConstEvalErr, ErrKind};
 use super::CodeAmbiguity;
 use super::CodeProjectionError;
 use super::CodeSelectionError;
+use super::engine::TraitEngine;
 use super::{FulfillmentError, FulfillmentErrorCode};
 use super::{ObligationCause, PredicateObligation, Obligation};
 use super::project;
@@ -85,6 +86,59 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
         }
     }
 
+    pub fn register_predicate_obligations<I>(&mut self,
+                                             infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+                                             obligations: I)
+        where I: IntoIterator<Item = PredicateObligation<'tcx>>
+    {
+        for obligation in obligations {
+            self.register_predicate_obligation(infcx, obligation);
+        }
+    }
+
+    /// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
+    /// only attempts to select obligations that haven't been seen before.
+    fn select(&mut self, selcx: &mut SelectionContext<'a, 'gcx, 'tcx>)
+              -> Result<(),Vec<FulfillmentError<'tcx>>> {
+        debug!("select(obligation-forest-size={})", self.predicates.len());
+
+        let mut errors = Vec::new();
+
+        loop {
+            debug!("select: starting another iteration");
+
+            // Process pending obligations.
+            let outcome = self.predicates.process_obligations(&mut FulfillProcessor {
+                selcx,
+                register_region_obligations: self.register_region_obligations
+            });
+            debug!("select: outcome={:?}", outcome);
+
+            // FIXME: if we kept the original cache key, we could mark projection
+            // obligations as complete for the projection cache here.
+
+            errors.extend(
+                outcome.errors.into_iter()
+                              .map(|e| to_fulfillment_error(e)));
+
+            // If nothing new was added, no need to keep looping.
+            if outcome.stalled {
+                break;
+            }
+        }
+
+        debug!("select({} predicates remaining, {} errors) done",
+               self.predicates.len(), errors.len());
+
+        if errors.is_empty() {
+            Ok(())
+        } else {
+            Err(errors)
+        }
+    }
+}
+
+impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
     /// "Normalize" a projection type `<SomeType as SomeTrait>::X` by
     /// creating a fresh type variable `$0` as well as a projection
     /// predicate `<SomeType as SomeTrait>::X == $0`. When the
@@ -92,12 +146,12 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
     /// `SomeTrait` or a where clause that lets us unify `$0` with
     /// something concrete. If this fails, we'll unify `$0` with
     /// `projection_ty` again.
-    pub fn normalize_projection_type(&mut self,
-                                     infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-                                     param_env: ty::ParamEnv<'tcx>,
-                                     projection_ty: ty::ProjectionTy<'tcx>,
-                                     cause: ObligationCause<'tcx>)
-                                     -> Ty<'tcx>
+    fn normalize_projection_type<'a, 'gcx>(&mut self,
+                                 infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+                                 param_env: ty::ParamEnv<'tcx>,
+                                 projection_ty: ty::ProjectionTy<'tcx>,
+                                 cause: ObligationCause<'tcx>)
+                                 -> Ty<'tcx>
     {
         debug!("normalize_projection_type(projection_ty={:?})",
                projection_ty);
@@ -125,12 +179,12 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
     /// Requires that `ty` must implement the trait with `def_id` in
     /// the given environment. This trait must not have any type
     /// parameters (except for `Self`).
-    pub fn register_bound(&mut self,
-                          infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-                          param_env: ty::ParamEnv<'tcx>,
-                          ty: Ty<'tcx>,
-                          def_id: DefId,
-                          cause: ObligationCause<'tcx>)
+    fn register_bound<'a, 'gcx>(&mut self,
+                      infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+                      param_env: ty::ParamEnv<'tcx>,
+                      ty: Ty<'tcx>,
+                      def_id: DefId,
+                      cause: ObligationCause<'tcx>)
     {
         let trait_ref = ty::TraitRef {
             def_id,
@@ -144,9 +198,9 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
         });
     }
 
-    pub fn register_predicate_obligation(&mut self,
-                                         infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-                                         obligation: PredicateObligation<'tcx>)
+    fn register_predicate_obligation<'a, 'gcx>(&mut self,
+                                     infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+                                     obligation: PredicateObligation<'tcx>)
     {
         // this helps to reduce duplicate errors, as well as making
         // debug output much nicer to read and so on.
@@ -162,19 +216,9 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
         });
     }
 
-    pub fn register_predicate_obligations<I>(&mut self,
-                                             infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-                                             obligations: I)
-        where I: IntoIterator<Item = PredicateObligation<'tcx>>
-    {
-        for obligation in obligations {
-            self.register_predicate_obligation(infcx, obligation);
-        }
-    }
-
-    pub fn select_all_or_error(&mut self,
-                               infcx: &InferCtxt<'a, 'gcx, 'tcx>)
-                               -> Result<(),Vec<FulfillmentError<'tcx>>>
+    fn select_all_or_error<'a, 'gcx>(&mut self,
+                                     infcx: &InferCtxt<'a, 'gcx, 'tcx>)
+                                     -> Result<(),Vec<FulfillmentError<'tcx>>>
     {
         self.select_where_possible(infcx)?;
 
@@ -190,58 +234,17 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
         }
     }
 
-    pub fn select_where_possible(&mut self,
-                                 infcx: &InferCtxt<'a, 'gcx, 'tcx>)
-                                 -> Result<(),Vec<FulfillmentError<'tcx>>>
+    fn select_where_possible<'a, 'gcx>(&mut self,
+                             infcx: &InferCtxt<'a, 'gcx, 'tcx>)
+                             -> Result<(),Vec<FulfillmentError<'tcx>>>
     {
         let mut selcx = SelectionContext::new(infcx);
         self.select(&mut selcx)
     }
 
-    pub fn pending_obligations(&self) -> Vec<PendingPredicateObligation<'tcx>> {
+    fn pending_obligations(&self) -> Vec<PendingPredicateObligation<'tcx>> {
         self.predicates.pending_obligations()
     }
-
-    /// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
-    /// only attempts to select obligations that haven't been seen before.
-    fn select(&mut self, selcx: &mut SelectionContext<'a, 'gcx, 'tcx>)
-              -> Result<(),Vec<FulfillmentError<'tcx>>> {
-        debug!("select(obligation-forest-size={})", self.predicates.len());
-
-        let mut errors = Vec::new();
-
-        loop {
-            debug!("select: starting another iteration");
-
-            // Process pending obligations.
-            let outcome = self.predicates.process_obligations(&mut FulfillProcessor {
-                selcx,
-                register_region_obligations: self.register_region_obligations
-            });
-            debug!("select: outcome={:?}", outcome);
-
-            // FIXME: if we kept the original cache key, we could mark projection
-            // obligations as complete for the projection cache here.
-
-            errors.extend(
-                outcome.errors.into_iter()
-                              .map(|e| to_fulfillment_error(e)));
-
-            // If nothing new was added, no need to keep looping.
-            if outcome.stalled {
-                break;
-            }
-        }
-
-        debug!("select({} predicates remaining, {} errors) done",
-               self.predicates.len(), errors.len());
-
-        if errors.is_empty() {
-            Ok(())
-        } else {
-            Err(errors)
-        }
-    }
 }
 
 struct FulfillProcessor<'a, 'b: 'a, 'gcx: 'tcx, 'tcx: 'b> {
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index bd8f99780f9f1..1d5d3e41c9c9a 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -29,11 +29,12 @@ use infer::{InferCtxt};
 
 use rustc_data_structures::sync::Lrc;
 use std::rc::Rc;
+use std::convert::From;
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
 
 pub use self::coherence::{orphan_check, overlapping_impls, OrphanCheckErr, OverlapResult};
-pub use self::fulfill::FulfillmentContext;
+pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
 pub use self::project::MismatchedProjectionTypes;
 pub use self::project::{normalize, normalize_projection_type, poly_project_and_unify_type};
 pub use self::project::{ProjectionCache, ProjectionCacheSnapshot, Reveal, Normalized};
@@ -44,6 +45,7 @@ pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
 pub use self::select::IntercrateAmbiguityCause;
 pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
 pub use self::specialize::{SpecializesCache, find_associated_item};
+pub use self::engine::TraitEngine;
 pub use self::util::elaborate_predicates;
 pub use self::util::supertraits;
 pub use self::util::Supertraits;
@@ -53,6 +55,7 @@ pub use self::util::transitive_bounds;
 
 mod coherence;
 pub mod error_reporting;
+mod engine;
 mod fulfill;
 mod project;
 mod object_safety;
@@ -244,6 +247,69 @@ pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
 pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
 pub type TraitObligations<'tcx> = Vec<TraitObligation<'tcx>>;
 
+/// The following types:
+/// * `WhereClauseAtom`
+/// * `DomainGoal`
+/// * `Goal`
+/// * `Clause`
+/// are used for representing the trait system in the form of
+/// logic programming clauses. They are part of the interface
+/// for the chalk SLG solver.
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+pub enum WhereClauseAtom<'tcx> {
+    Implemented(ty::TraitPredicate<'tcx>),
+    ProjectionEq(ty::ProjectionPredicate<'tcx>),
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+pub enum DomainGoal<'tcx> {
+    Holds(WhereClauseAtom<'tcx>),
+    WellFormed(WhereClauseAtom<'tcx>),
+    FromEnv(WhereClauseAtom<'tcx>),
+    WellFormedTy(Ty<'tcx>),
+    FromEnvTy(Ty<'tcx>),
+    RegionOutlives(ty::RegionOutlivesPredicate<'tcx>),
+    TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+pub enum QuantifierKind {
+    Universal,
+    Existential,
+}
+
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+pub enum Goal<'tcx> {
+    // FIXME: use interned refs instead of `Box`
+    Implies(Vec<Clause<'tcx>>, Box<Goal<'tcx>>),
+    And(Box<Goal<'tcx>>, Box<Goal<'tcx>>),
+    Not(Box<Goal<'tcx>>),
+    DomainGoal(DomainGoal<'tcx>),
+    Quantified(QuantifierKind, Box<ty::Binder<Goal<'tcx>>>)
+}
+
+impl<'tcx> From<DomainGoal<'tcx>> for Goal<'tcx> {
+    fn from(domain_goal: DomainGoal<'tcx>) -> Self {
+        Goal::DomainGoal(domain_goal)
+    }
+}
+
+impl<'tcx> From<DomainGoal<'tcx>> for Clause<'tcx> {
+    fn from(domain_goal: DomainGoal<'tcx>) -> Self {
+        Clause::DomainGoal(domain_goal)
+    }
+}
+
+/// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary
+/// Harrop Formulas".
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+pub enum Clause<'tcx> {
+    // FIXME: again, use interned refs instead of `Box`
+    Implies(Vec<Goal<'tcx>>, DomainGoal<'tcx>),
+    DomainGoal(DomainGoal<'tcx>),
+    ForAll(Box<ty::Binder<Clause<'tcx>>>),
+}
+
 pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
 
 #[derive(Clone,Debug)]
diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs
index 1caab6fd89ef9..af1d2c77c28a8 100644
--- a/src/librustc/traits/query/dropck_outlives.rs
+++ b/src/librustc/traits/query/dropck_outlives.rs
@@ -15,7 +15,7 @@ use std::iter::FromIterator;
 use traits::query::CanonicalTyGoal;
 use ty::{self, Ty, TyCtxt};
 use ty::subst::Kind;
-use std::rc::Rc;
+use rustc_data_structures::sync::Lrc;
 
 impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
     /// Given a type `ty` of some value being dropped, computes a set
@@ -51,6 +51,7 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
         let gcx = tcx.global_tcx();
         let (c_ty, orig_values) = self.infcx.canonicalize_query(&self.param_env.and(ty));
         let span = self.cause.span;
+        debug!("c_ty = {:?}", c_ty);
         match &gcx.dropck_outlives(c_ty) {
             Ok(result) if result.is_proven() => {
                 match self.infcx.instantiate_query_result(
@@ -182,13 +183,13 @@ impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> {
 
 impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, DropckOutlivesResult<'tcx>> {
     // we ought to intern this, but I'm too lazy just now
-    type Canonicalized = Rc<Canonical<'gcx, QueryResult<'gcx, DropckOutlivesResult<'gcx>>>>;
+    type Canonicalized = Lrc<Canonical<'gcx, QueryResult<'gcx, DropckOutlivesResult<'gcx>>>>;
 
     fn intern(
         _gcx: TyCtxt<'_, 'gcx, 'gcx>,
         value: Canonical<'gcx, Self::Lifted>,
     ) -> Self::Canonicalized {
-        Rc::new(value)
+        Lrc::new(value)
     }
 }
 
diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs
index 70c5cf5f39029..63f50cff4c2ad 100644
--- a/src/librustc/traits/query/normalize.rs
+++ b/src/librustc/traits/query/normalize.rs
@@ -17,7 +17,7 @@ use infer::at::At;
 use infer::canonical::{Canonical, Canonicalize, QueryResult};
 use middle::const_val::ConstVal;
 use mir::interpret::GlobalId;
-use std::rc::Rc;
+use rustc_data_structures::sync::Lrc;
 use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
 use traits::query::CanonicalProjectionGoal;
 use traits::project::Normalized;
@@ -259,13 +259,13 @@ impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, ty::Pr
 
 impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, NormalizationResult<'tcx>> {
     // we ought to intern this, but I'm too lazy just now
-    type Canonicalized = Rc<Canonical<'gcx, QueryResult<'gcx, NormalizationResult<'gcx>>>>;
+    type Canonicalized = Lrc<Canonical<'gcx, QueryResult<'gcx, NormalizationResult<'gcx>>>>;
 
     fn intern(
         _gcx: TyCtxt<'_, 'gcx, 'gcx>,
         value: Canonical<'gcx, Self::Lifted>,
     ) -> Self::Canonicalized {
-        Rc::new(value)
+        Lrc::new(value)
     }
 }
 
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 4db81cf1dec1d..11daa96134c59 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -2086,14 +2086,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
 
             ty::TyClosure(def_id, substs) => {
                 let trait_id = obligation.predicate.def_id();
-                let copy_closures =
-                    Some(trait_id) == self.tcx().lang_items().copy_trait() &&
-                    self.tcx().has_copy_closures(def_id.krate);
-                let clone_closures =
-                    Some(trait_id) == self.tcx().lang_items().clone_trait() &&
-                    self.tcx().has_clone_closures(def_id.krate);
-
-                if copy_closures || clone_closures {
+                let is_copy_trait = Some(trait_id) == self.tcx().lang_items().copy_trait();
+                let is_clone_trait = Some(trait_id) == self.tcx().lang_items().clone_trait();
+                if is_copy_trait || is_clone_trait {
                     Where(ty::Binder(substs.upvar_tys(def_id, self.tcx()).collect()))
                 } else {
                     Never
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index 5ea089abb8e86..a9d1c8bcc3d99 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -26,7 +26,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use hir::def_id::DefId;
 use infer::{InferCtxt, InferOk};
 use ty::subst::{Subst, Substs};
-use traits::{self, ObligationCause};
+use traits::{self, ObligationCause, TraitEngine};
 use traits::select::IntercrateAmbiguityCause;
 use ty::{self, TyCtxt, TypeFoldable};
 use syntax_pos::DUMMY_SP;
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index f8b895177f381..e56a8662f3eb4 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -19,6 +19,7 @@ use ty::{self, TyCtxt, TypeFoldable};
 use ty::fast_reject::{self, SimplifiedType};
 use rustc_data_structures::sync::Lrc;
 use syntax::ast::Name;
+use util::captures::Captures;
 use util::nodemap::{DefIdMap, FxHashMap};
 
 /// A per-trait graph of impls in specialization order. At the moment, this
@@ -36,6 +37,7 @@ use util::nodemap::{DefIdMap, FxHashMap};
 ///   parents of a given specializing impl, which is needed for extracting
 ///   default items amongst other things. In the simple "chain" rule, every impl
 ///   has at most one parent.
+#[derive(RustcEncodable, RustcDecodable)]
 pub struct Graph {
     // all impls have a parent; the "root" impls have as their parent the def_id
     // of the trait
@@ -47,6 +49,7 @@ pub struct Graph {
 
 /// Children of a given impl, grouped into blanket/non-blanket varieties as is
 /// done in `TraitDef`.
+#[derive(RustcEncodable, RustcDecodable)]
 struct Children {
     // Impls of a trait (or specializations of a given impl). To allow for
     // quicker lookup, the impls are indexed by a simplified version of their
@@ -311,9 +314,10 @@ impl<'a, 'gcx, 'tcx> Node {
     }
 
     /// Iterate over the items defined directly by the given (impl or trait) node.
-    #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
-    pub fn items(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
-                 -> impl Iterator<Item = ty::AssociatedItem> + 'a {
+    pub fn items(
+        &self,
+        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    ) -> impl Iterator<Item = ty::AssociatedItem> + 'a {
         tcx.associated_items(self.def_id())
     }
 
@@ -365,9 +369,13 @@ impl<'a, 'gcx, 'tcx> Ancestors {
     /// Search the items from the given ancestors, returning each definition
     /// with the given name and the given kind.
     #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
-    pub fn defs(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, trait_item_name: Name,
-                trait_item_kind: ty::AssociatedKind, trait_def_id: DefId)
-                -> impl Iterator<Item = NodeItem<ty::AssociatedItem>> + 'a {
+    pub fn defs(
+        self,
+        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        trait_item_name: Name,
+        trait_item_kind: ty::AssociatedKind,
+        trait_def_id: DefId,
+    ) -> impl Iterator<Item = NodeItem<ty::AssociatedItem>> + Captures<'gcx> + Captures<'tcx> + 'a {
         self.flat_map(move |node| {
             node.items(tcx).filter(move |impl_item| {
                 impl_item.kind == trait_item_kind &&
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index a2d98a456f49a..d6e6f0e98adc4 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -425,3 +425,138 @@ BraceStructTypeFoldableImpl! {
         obligations
     } where T: TypeFoldable<'tcx>
 }
+
+impl<'tcx> fmt::Display for traits::WhereClauseAtom<'tcx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        use traits::WhereClauseAtom::*;
+
+        match self {
+            Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref),
+            ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection),
+        }
+    }
+}
+
+impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        use traits::DomainGoal::*;
+        use traits::WhereClauseAtom::*;
+
+        match self {
+            Holds(wc) => write!(fmt, "{}", wc),
+            WellFormed(Implemented(trait_ref)) => write!(fmt, "WellFormed({})", trait_ref),
+            WellFormed(ProjectionEq(projection)) => write!(fmt, "WellFormed({})", projection),
+            FromEnv(Implemented(trait_ref)) => write!(fmt, "FromEnv({})", trait_ref),
+            FromEnv(ProjectionEq(projection)) => write!(fmt, "FromEnv({})", projection),
+            WellFormedTy(ty) => write!(fmt, "WellFormed({})", ty),
+            FromEnvTy(ty) => write!(fmt, "FromEnv({})", ty),
+            RegionOutlives(predicate) => write!(fmt, "RegionOutlives({})", predicate),
+            TypeOutlives(predicate) => write!(fmt, "TypeOutlives({})", predicate),
+        }
+    }
+}
+
+impl fmt::Display for traits::QuantifierKind {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        use traits::QuantifierKind::*;
+
+        match self {
+            Universal => write!(fmt, "forall"),
+            Existential => write!(fmt, "exists"),
+        }
+    }
+}
+
+impl<'tcx> fmt::Display for traits::Goal<'tcx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        use traits::Goal::*;
+
+        match self {
+            Implies(hypotheses, goal) => {
+                write!(fmt, "if (")?;
+                for (index, hyp) in hypotheses.iter().enumerate() {
+                    if index > 0 {
+                        write!(fmt, ", ")?;
+                    }
+                    write!(fmt, "{}", hyp)?;
+                }
+                write!(fmt, ") {{ {} }}", goal)
+            }
+            And(goal1, goal2) => write!(fmt, "({} && {})", goal1, goal2),
+            Not(goal) => write!(fmt, "not {{ {} }}", goal),
+            DomainGoal(goal) => write!(fmt, "{}", goal),
+            Quantified(qkind, goal) => {
+                // FIXME: appropriate binder names
+                write!(fmt, "{}<> {{ {} }}", qkind, goal.skip_binder())
+            }
+        }
+    }
+}
+
+impl<'tcx> fmt::Display for traits::Clause<'tcx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        use traits::Clause::*;
+
+        match self {
+            Implies(hypotheses, goal) => {
+                write!(fmt, "{}", goal)?;
+                if !hypotheses.is_empty() {
+                    write!(fmt, " :- ")?;
+                    for (index, condition) in hypotheses.iter().enumerate() {
+                        if index > 0 {
+                            write!(fmt, ", ")?;
+                        }
+                        write!(fmt, "{}", condition)?;
+                    }
+                }
+                write!(fmt, ".")
+            }
+            DomainGoal(domain_goal) => write!(fmt, "{}.", domain_goal),
+            ForAll(clause) => {
+                // FIXME: appropriate binder names
+                write!(fmt, "forall<> {{ {} }}", clause.skip_binder())
+            }
+        }
+    }
+}
+
+EnumTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for traits::WhereClauseAtom<'tcx> {
+        (traits::WhereClauseAtom::Implemented)(trait_ref),
+        (traits::WhereClauseAtom::ProjectionEq)(projection),
+    }
+}
+
+EnumTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for traits::DomainGoal<'tcx> {
+        (traits::DomainGoal::Holds)(wc),
+        (traits::DomainGoal::WellFormed)(wc),
+        (traits::DomainGoal::FromEnv)(wc),
+        (traits::DomainGoal::WellFormedTy)(ty),
+        (traits::DomainGoal::FromEnvTy)(ty),
+        (traits::DomainGoal::RegionOutlives)(predicate),
+        (traits::DomainGoal::TypeOutlives)(predicate),
+    }
+}
+
+CloneTypeFoldableImpls! {
+    traits::QuantifierKind,
+}
+
+EnumTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
+        (traits::Goal::Implies)(hypotheses, goal),
+        (traits::Goal::And)(goal1, goal2),
+        (traits::Goal::Not)(goal),
+        (traits::Goal::DomainGoal)(domain_goal),
+        (traits::Goal::Quantified)(qkind, goal),
+    }
+}
+
+EnumTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for traits::Clause<'tcx> {
+        (traits::Clause::Implies)(hypotheses, goal),
+        (traits::Clause::DomainGoal)(domain_goal),
+        (traits::Clause::ForAll)(clause),
+    }
+}
diff --git a/src/librustc/traits/trans/mod.rs b/src/librustc/traits/trans/mod.rs
index cc8b74e0ee23a..31e851126d76a 100644
--- a/src/librustc/traits/trans/mod.rs
+++ b/src/librustc/traits/trans/mod.rs
@@ -18,7 +18,8 @@ use std::marker::PhantomData;
 use syntax_pos::DUMMY_SP;
 use infer::InferCtxt;
 use syntax_pos::Span;
-use traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, Vtable};
+use traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext,
+             TraitEngine, Vtable};
 use ty::{self, Ty, TyCtxt};
 use ty::subst::{Subst, Substs};
 use ty::fold::TypeFoldable;
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
index f98bc95356098..4e15f0711a5aa 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -17,6 +17,7 @@
 // persisting to incr. comp. caches.
 
 use hir::def_id::{DefId, CrateNum};
+use infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_serialize::{Decodable, Decoder, Encoder, Encodable, opaque};
 use std::hash::Hash;
@@ -239,6 +240,19 @@ pub fn decode_existential_predicate_slice<'a, 'tcx, D>(decoder: &mut D)
               .mk_existential_predicates((0..len).map(|_| Decodable::decode(decoder)))?)
 }
 
+#[inline]
+pub fn decode_canonical_var_infos<'a, 'tcx, D>(decoder: &mut D)
+    -> Result<CanonicalVarInfos<'tcx>, D::Error>
+    where D: TyDecoder<'a, 'tcx>,
+          'tcx: 'a,
+{
+    let len = decoder.read_usize()?;
+    let interned: Result<Vec<CanonicalVarInfo>, _> = (0..len).map(|_| Decodable::decode(decoder))
+                                                             .collect();
+    Ok(decoder.tcx()
+              .intern_canonical_var_infos(interned?.as_slice()))
+}
+
 #[inline]
 pub fn decode_const<'a, 'tcx, D>(decoder: &mut D)
                                  -> Result<&'tcx ty::Const<'tcx>, D::Error>
@@ -262,6 +276,7 @@ macro_rules! implement_ty_decoder {
     ($DecoderName:ident <$($typaram:tt),*>) => {
         mod __ty_decoder_impl {
             use super::$DecoderName;
+            use $crate::infer::canonical::CanonicalVarInfos;
             use $crate::ty;
             use $crate::ty::codec::*;
             use $crate::ty::subst::Substs;
@@ -364,6 +379,14 @@ macro_rules! implement_ty_decoder {
                 }
             }
 
+            impl<$($typaram),*> SpecializedDecoder<CanonicalVarInfos<'tcx>>
+                for $DecoderName<$($typaram),*> {
+                fn specialized_decode(&mut self)
+                    -> Result<CanonicalVarInfos<'tcx>, Self::Error> {
+                    decode_canonical_var_infos(self)
+                }
+            }
+
             impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::Const<'tcx>>
             for $DecoderName<$($typaram),*> {
                 fn specialized_decode(&mut self) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index fd3465f59ebf2..fdda2286da03b 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -48,6 +48,7 @@ use ty::layout::{LayoutDetails, TargetDataLayout};
 use ty::maps;
 use ty::steal::Steal;
 use ty::BindingMode;
+use ty::CanonicalTy;
 use util::nodemap::{NodeMap, DefIdSet, ItemLocalMap};
 use util::nodemap::{FxHashMap, FxHashSet};
 use rustc_data_structures::accumulate_vec::AccumulateVec;
@@ -161,12 +162,12 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
                  -> Ty<'tcx> {
         let ty = {
             let mut interner = self.type_.borrow_mut();
-            let global_interner = global_interners.map(|interners| {
-                interners.type_.borrow_mut()
-            });
             if let Some(&Interned(ty)) = interner.get(&st) {
                 return ty;
             }
+            let global_interner = global_interners.map(|interners| {
+                interners.type_.borrow_mut()
+            });
             if let Some(ref interner) = global_interner {
                 if let Some(&Interned(ty)) = interner.get(&st) {
                     return ty;
@@ -344,6 +345,10 @@ pub struct TypeckTables<'tcx> {
     /// method calls, including those of overloaded operators.
     type_dependent_defs: ItemLocalMap<Def>,
 
+    /// Stores the canonicalized types provided by the user. See also `UserAssertTy` statement in
+    /// MIR.
+    user_provided_tys: ItemLocalMap<CanonicalTy<'tcx>>,
+
     /// Stores the types for various nodes in the AST.  Note that this table
     /// is not guaranteed to be populated until after typeck.  See
     /// typeck::check::fn_ctxt for details.
@@ -420,6 +425,7 @@ impl<'tcx> TypeckTables<'tcx> {
         TypeckTables {
             local_id_root,
             type_dependent_defs: ItemLocalMap(),
+            user_provided_tys: ItemLocalMap(),
             node_types: ItemLocalMap(),
             node_substs: ItemLocalMap(),
             adjustments: ItemLocalMap(),
@@ -461,6 +467,20 @@ impl<'tcx> TypeckTables<'tcx> {
         }
     }
 
+    pub fn user_provided_tys(&self) -> LocalTableInContext<CanonicalTy<'tcx>> {
+        LocalTableInContext {
+            local_id_root: self.local_id_root,
+            data: &self.user_provided_tys
+        }
+    }
+
+    pub fn user_provided_tys_mut(&mut self) -> LocalTableInContextMut<CanonicalTy<'tcx>> {
+        LocalTableInContextMut {
+            local_id_root: self.local_id_root,
+            data: &mut self.user_provided_tys
+        }
+    }
+
     pub fn node_types(&self) -> LocalTableInContext<Ty<'tcx>> {
         LocalTableInContext {
             local_id_root: self.local_id_root,
@@ -685,6 +705,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
         let ty::TypeckTables {
             local_id_root,
             ref type_dependent_defs,
+            ref user_provided_tys,
             ref node_types,
             ref node_substs,
             ref adjustments,
@@ -704,6 +725,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
 
         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
             type_dependent_defs.hash_stable(hcx, hasher);
+            user_provided_tys.hash_stable(hcx, hasher);
             node_types.hash_stable(hcx, hasher);
             node_substs.hash_stable(hcx, hasher);
             adjustments.hash_stable(hcx, hasher);
@@ -1010,17 +1032,16 @@ impl<'tcx> InterpretInterner<'tcx> {
     }
 }
 
-impl<'tcx> GlobalCtxt<'tcx> {
+impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     /// Get the global TyCtxt.
-    pub fn global_tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
+    #[inline]
+    pub fn global_tcx(self) -> TyCtxt<'a, 'gcx, 'gcx> {
         TyCtxt {
-            gcx: self,
-            interners: &self.global_interners
+            gcx: self.gcx,
+            interners: &self.gcx.global_interners,
         }
     }
-}
 
-impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics {
         self.global_arenas.generics.alloc(generics)
     }
@@ -1081,12 +1102,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         self,
         alloc: interpret::Allocation,
     ) -> &'gcx interpret::Allocation {
-        if let Some(alloc) = self.interpret_interner.inner.borrow().allocs.get(&alloc) {
+        let allocs = &mut self.interpret_interner.inner.borrow_mut().allocs;
+        if let Some(alloc) = allocs.get(&alloc) {
             return alloc;
         }
 
         let interned = self.global_arenas.const_allocs.alloc(alloc);
-        if let Some(prev) = self.interpret_interner.inner.borrow_mut().allocs.replace(interned) {
+        if let Some(prev) = allocs.replace(interned) {
             bug!("Tried to overwrite interned Allocation: {:#?}", prev)
         }
         interned
@@ -1113,24 +1135,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
-        if let Some(st) = self.stability_interner.borrow().get(&stab) {
+        let mut stability_interner = self.stability_interner.borrow_mut();
+        if let Some(st) = stability_interner.get(&stab) {
             return st;
         }
 
         let interned = self.global_interners.arena.alloc(stab);
-        if let Some(prev) = self.stability_interner.borrow_mut().replace(interned) {
+        if let Some(prev) = stability_interner.replace(interned) {
             bug!("Tried to overwrite interned Stability: {:?}", prev)
         }
         interned
     }
 
     pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails {
-        if let Some(layout) = self.layout_interner.borrow().get(&layout) {
+        let mut layout_interner = self.layout_interner.borrow_mut();
+        if let Some(layout) = layout_interner.get(&layout) {
             return layout;
         }
 
         let interned = self.global_arenas.layout.alloc(layout);
-        if let Some(prev) = self.layout_interner.borrow_mut().replace(interned) {
+        if let Some(prev) = layout_interner.replace(interned) {
             bug!("Tried to overwrite interned Layout: {:?}", prev)
         }
         interned
@@ -1635,6 +1659,24 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice<Predicate<'a>> {
     }
 }
 
+impl<'a, 'tcx> Lift<'tcx> for &'a Slice<CanonicalVarInfo> {
+    type Lifted = &'tcx Slice<CanonicalVarInfo>;
+    fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
+        if self.len() == 0 {
+            return Some(Slice::empty());
+        }
+        if tcx.interners.arena.in_arena(*self as *const _) {
+            return Some(unsafe { mem::transmute(*self) });
+        }
+        // Also try in the global tcx if we're not that.
+        if !tcx.is_global() {
+            self.lift_to_tcx(tcx.global_tcx())
+        } else {
+            None
+        }
+    }
+}
+
 pub mod tls {
     use super::{CtxtInterners, GlobalCtxt, TyCtxt};
 
@@ -2520,14 +2562,6 @@ pub fn provide(providers: &mut ty::maps::Providers) {
         assert_eq!(cnum, LOCAL_CRATE);
         tcx.output_filenames.clone()
     };
-    providers.has_copy_closures = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        tcx.features().copy_closures
-    };
-    providers.has_clone_closures = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        tcx.features().clone_closures
-    };
     providers.features_query = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
         Lrc::new(tcx.sess.features_untracked().clone())
diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs
index 6533a7440ac38..31b3ca44700e9 100644
--- a/src/librustc/ty/fast_reject.rs
+++ b/src/librustc/ty/fast_reject.rs
@@ -28,7 +28,7 @@ pub type SimplifiedType = SimplifiedTypeGen<DefId>;
 /// because we sometimes need to use SimplifiedTypeGen values as stable sorting
 /// keys (in which case we use a DefPathHash as id-type) but in the general case
 /// the non-stable but fast to construct DefId-version is the better choice.
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
 pub enum SimplifiedTypeGen<D>
     where D: Copy + Debug + Ord + Eq + Hash
 {
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 3a3f10cb87db4..5f9c305d92f04 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -1517,10 +1517,21 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
                             let offset = st[i].fields.offset(field_index) + offset;
                             let size = st[i].size;
 
-                            let abi = if offset.bytes() == 0 && niche.value.size(dl) == size {
-                                Abi::Scalar(niche.clone())
-                            } else {
-                                Abi::Aggregate { sized: true }
+                            let abi = match st[i].abi {
+                                Abi::Scalar(_) => Abi::Scalar(niche.clone()),
+                                Abi::ScalarPair(ref first, ref second) => {
+                                    // We need to use scalar_unit to reset the
+                                    // valid range to the maximal one for that
+                                    // primitive, because only the niche is
+                                    // guaranteed to be initialised, not the
+                                    // other primitive.
+                                    if offset.bytes() == 0 {
+                                        Abi::ScalarPair(niche.clone(), scalar_unit(second.value))
+                                    } else {
+                                        Abi::ScalarPair(scalar_unit(first.value), niche.clone())
+                                    }
+                                }
+                                _ => Abi::Aggregate { sized: true },
                             };
 
                             return Ok(tcx.intern_layout(LayoutDetails {
@@ -1544,11 +1555,17 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
                 }
 
                 let (mut min, mut max) = (i128::max_value(), i128::min_value());
+                let discr_type = def.repr.discr_type();
+                let bits = Integer::from_attr(tcx, discr_type).size().bits();
                 for (i, discr) in def.discriminants(tcx).enumerate() {
                     if variants[i].iter().any(|f| f.abi == Abi::Uninhabited) {
                         continue;
                     }
-                    let x = discr.val as i128;
+                    let mut x = discr.val as i128;
+                    if discr_type.is_signed() {
+                        // sign extend the raw representation to be an i128
+                        x = (x << (128 - bits)) >> (128 - bits);
+                    }
                     if x < min { min = x; }
                     if x > max { max = x; }
                 }
diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs
index 11675f542873d..bb9467305e335 100644
--- a/src/librustc/ty/maps/config.rs
+++ b/src/librustc/ty/maps/config.rs
@@ -430,6 +430,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::native_libraries<'tcx> {
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("looking up the foreign modules of a linked crate")
+    }
+}
+
 impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> {
     fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
         format!("looking up the plugin registrar for a crate")
@@ -604,24 +610,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::has_clone_closures<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("seeing if the crate has enabled `Clone` closures")
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> {
     fn describe(tcx: TyCtxt, key: ty::PolyTraitRef<'tcx> ) -> String {
         format!("finding all methods for trait {}", tcx.item_path_str(key.def_id()))
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::has_copy_closures<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("seeing if the crate has enabled `Copy` closures")
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> {
     fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
         format!("looking up enabled feature gates")
@@ -678,6 +672,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx>
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::wasm_custom_sections<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("custom wasm sections for a crate")
+    }
+}
+
 impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> {
     #[inline]
     fn cache_on_disk(def_id: Self::Key) -> bool {
@@ -693,6 +693,24 @@ impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> {
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> {
+    fn describe(_tcx: TyCtxt, _: DefId) -> String {
+        format!("generating chalk-style clauses")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::wasm_import_module_map<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("wasm import module map")
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("wasm import module map")
+    }
+}
+
 macro_rules! impl_disk_cacheable_query(
     ($query_name:ident, |$key:tt| $cond:expr) => {
         impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> {
@@ -721,3 +739,4 @@ impl_disk_cacheable_query!(type_of, |def_id| def_id.is_local());
 impl_disk_cacheable_query!(predicates_of, |def_id| def_id.is_local());
 impl_disk_cacheable_query!(used_trait_imports, |def_id| def_id.is_local());
 impl_disk_cacheable_query!(trans_fn_attrs, |_| true);
+impl_disk_cacheable_query!(specialization_graph_of, |_| true);
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index c1783654effef..2bfb687032923 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -18,7 +18,7 @@ use infer::canonical::{Canonical, QueryResult};
 use lint;
 use middle::borrowck::BorrowCheckResult;
 use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary,
-                     ExternBodyNestedBodies};
+                     ExternBodyNestedBodies, ForeignModule};
 use middle::cstore::{NativeLibraryKind, DepKind, CrateSource, ExternConstBody};
 use middle::privacy::AccessLevels;
 use middle::reachable::ReachableSet;
@@ -38,6 +38,7 @@ use traits::query::{CanonicalProjectionGoal, CanonicalTyGoal, NoSolution};
 use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult};
 use traits::query::normalize::NormalizationResult;
 use traits::specialization_graph;
+use traits::Clause;
 use ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
 use ty::steal::Steal;
 use ty::subst::Substs;
@@ -298,6 +299,10 @@ define_maps! { <'tcx>
 
     [] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness,
 
+    [] fn check_item_well_formed: CheckItemWellFormed(DefId) -> (),
+    [] fn check_trait_item_well_formed: CheckTraitItemWellFormed(DefId) -> (),
+    [] fn check_impl_item_well_formed: CheckImplItemWellFormed(DefId) -> (),
+
     // The DefIds of all non-generic functions and statics in the given crate
     // that can be reached from outside the crate.
     //
@@ -315,6 +320,9 @@ define_maps! { <'tcx>
 
 
     [] fn native_libraries: NativeLibraries(CrateNum) -> Lrc<Vec<NativeLibrary>>,
+
+    [] fn foreign_modules: ForeignModules(CrateNum) -> Lrc<Vec<ForeignModule>>,
+
     [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
     [] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option<DefId>,
     [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator,
@@ -326,6 +334,8 @@ define_maps! { <'tcx>
     [] fn all_trait_implementations: AllTraitImplementations(CrateNum)
         -> Lrc<Vec<DefId>>,
 
+    [] fn dllimport_foreign_items: DllimportForeignItems(CrateNum)
+        -> Lrc<FxHashSet<DefId>>,
     [] fn is_dllimport_foreign_item: IsDllimportForeignItem(DefId) -> bool,
     [] fn is_statically_included_foreign_item: IsStaticallyIncludedForeignItem(DefId) -> bool,
     [] fn native_library_kind: NativeLibraryKind(DefId)
@@ -377,9 +387,6 @@ define_maps! { <'tcx>
     [] fn output_filenames: output_filenames_node(CrateNum)
         -> Arc<OutputFilenames>,
 
-    [] fn has_copy_closures: HasCopyClosures(CrateNum) -> bool,
-    [] fn has_clone_closures: HasCloneClosures(CrateNum) -> bool,
-
     // Erases regions from `ty` to yield a new type.
     // Normally you would just use `tcx.erase_regions(&value)`,
     // however, which uses this query as a kind of cache.
@@ -417,6 +424,12 @@ define_maps! { <'tcx>
         -> usize,
 
     [] fn features_query: features_node(CrateNum) -> Lrc<feature_gate::Features>,
+
+    [] fn program_clauses_for: ProgramClausesFor(DefId) -> Lrc<Vec<Clause<'tcx>>>,
+
+    [] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc<Vec<DefId>>,
+    [] fn wasm_import_module_map: WasmImportModuleMap(CrateNum)
+        -> Lrc<FxHashMap<DefId, String>>,
 }
 
 //////////////////////////////////////////////////////////////////////
diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs
index 35e874b74d9ae..c103d6e015aa4 100644
--- a/src/librustc/ty/maps/on_disk_cache.rs
+++ b/src/librustc/ty/maps/on_disk_cache.rs
@@ -75,6 +75,13 @@ pub struct OnDiskCache<'sess> {
     // A map from dep-node to the position of any associated diagnostics in
     // `serialized_data`.
     prev_diagnostics_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
+
+    // A cache to ensure we don't read allocations twice
+    interpret_alloc_cache: RefCell<FxHashMap<usize, interpret::AllocId>>,
+
+    // A map from positions to size of the serialized allocation
+    // so we can skip over already processed allocations
+    interpret_alloc_size: RefCell<FxHashMap<usize, usize>>,
 }
 
 // This type is used only for (de-)serialization.
@@ -140,6 +147,8 @@ impl<'sess> OnDiskCache<'sess> {
             query_result_index: footer.query_result_index.into_iter().collect(),
             prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(),
             synthetic_expansion_infos: RefCell::new(FxHashMap()),
+            interpret_alloc_cache: RefCell::new(FxHashMap::default()),
+            interpret_alloc_size: RefCell::new(FxHashMap::default()),
         }
     }
 
@@ -155,6 +164,8 @@ impl<'sess> OnDiskCache<'sess> {
             query_result_index: FxHashMap(),
             prev_diagnostics_index: FxHashMap(),
             synthetic_expansion_infos: RefCell::new(FxHashMap()),
+            interpret_alloc_cache: RefCell::new(FxHashMap::default()),
+            interpret_alloc_size: RefCell::new(FxHashMap::default()),
         }
     }
 
@@ -221,6 +232,7 @@ impl<'sess> OnDiskCache<'sess> {
                 encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
                 encode_query_results::<check_match, _>(tcx, enc, qri)?;
                 encode_query_results::<trans_fn_attrs, _>(tcx, enc, qri)?;
+                encode_query_results::<specialization_graph_of, _>(tcx, enc, qri)?;
 
                 // const eval is special, it only encodes successfully evaluated constants
                 use ty::maps::plumbing::GetCacheInternal;
@@ -381,7 +393,8 @@ impl<'sess> OnDiskCache<'sess> {
             file_index_to_file: &self.file_index_to_file,
             file_index_to_stable_id: &self.file_index_to_stable_id,
             synthetic_expansion_infos: &self.synthetic_expansion_infos,
-            interpret_alloc_cache: FxHashMap::default(),
+            interpret_alloc_cache: &self.interpret_alloc_cache,
+            interpret_alloc_size: &self.interpret_alloc_size,
         };
 
         match decode_tagged(&mut decoder, dep_node_index) {
@@ -443,7 +456,8 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> {
     synthetic_expansion_infos: &'x RefCell<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
     file_index_to_file: &'x RefCell<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
     file_index_to_stable_id: &'x FxHashMap<FileMapIndex, StableFilemapId>,
-    interpret_alloc_cache: FxHashMap<usize, interpret::AllocId>,
+    interpret_alloc_cache: &'x RefCell<FxHashMap<usize, interpret::AllocId>>,
+    interpret_alloc_size: &'x RefCell<FxHashMap<usize, usize>>,
 }
 
 impl<'a, 'tcx, 'x> CacheDecoder<'a, 'tcx, 'x> {
@@ -565,47 +579,37 @@ implement_ty_decoder!( CacheDecoder<'a, 'tcx, 'x> );
 
 impl<'a, 'tcx, 'x> SpecializedDecoder<interpret::AllocId> for CacheDecoder<'a, 'tcx, 'x> {
     fn specialized_decode(&mut self) -> Result<interpret::AllocId, Self::Error> {
-        const MAX1: usize = usize::max_value() - 1;
         let tcx = self.tcx;
         let pos = TyDecoder::position(self);
-        match usize::decode(self)? {
-            ::std::usize::MAX => {
-                let alloc_id = tcx.interpret_interner.reserve();
-                trace!("creating alloc id {:?} at {}", alloc_id, pos);
-                // insert early to allow recursive allocs
-                self.interpret_alloc_cache.insert(pos, alloc_id);
-
-                let allocation = interpret::Allocation::decode(self)?;
-                trace!("decoded alloc {:?} {:#?}", alloc_id, allocation);
-                let allocation = self.tcx.intern_const_alloc(allocation);
-                tcx.interpret_interner.intern_at_reserved(alloc_id, allocation);
-
-                if let Some(glob) = Option::<DefId>::decode(self)? {
-                    trace!("connecting alloc {:?} with {:?}", alloc_id, glob);
-                    tcx.interpret_interner.cache(glob, alloc_id);
-                }
-
-                Ok(alloc_id)
-            },
-            MAX1 => {
-                trace!("creating fn alloc id at {}", pos);
-                let instance = ty::Instance::decode(self)?;
-                trace!("decoded fn alloc instance: {:?}", instance);
-                let id = tcx.interpret_interner.create_fn_alloc(instance);
-                trace!("created fn alloc id: {:?}", id);
-                self.interpret_alloc_cache.insert(pos, id);
-                Ok(id)
+        trace!("specialized_decode_alloc_id: {:?}", pos);
+        if let Some(cached) = self.interpret_alloc_cache.borrow().get(&pos).cloned() {
+            // if there's no end position we are currently deserializing a recursive
+            // allocation
+            if let Some(end) = self.interpret_alloc_size.borrow().get(&pos).cloned() {
+                trace!("{} already cached as {:?}", pos, cached);
+                // skip ahead
+                self.opaque.set_position(end);
+                return Ok(cached)
+            }
+        }
+        let id = interpret::specialized_decode_alloc_id(
+            self,
+            tcx,
+            pos,
+            |this, pos, alloc_id| {
+                assert!(this.interpret_alloc_cache.borrow_mut().insert(pos, alloc_id).is_none());
             },
-            shorthand => {
-                trace!("loading shorthand {}", shorthand);
-                if let Some(&alloc_id) = self.interpret_alloc_cache.get(&shorthand) {
-                    return Ok(alloc_id);
-                }
-                trace!("shorthand {} not cached, loading entire allocation", shorthand);
+            |this, shorthand| {
                 // need to load allocation
-                self.with_position(shorthand, |this| interpret::AllocId::decode(this))
-            },
-        }
+                this.with_position(shorthand, |this| interpret::AllocId::decode(this))
+            }
+        )?;
+        assert!(self
+            .interpret_alloc_size
+            .borrow_mut()
+            .insert(pos, TyDecoder::position(self))
+            .is_none());
+        Ok(id)
     }
 }
 impl<'a, 'tcx, 'x> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx, 'x> {
@@ -806,30 +810,27 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder<interpret::AllocId> for CacheEncoder<
     where E: 'enc + ty_codec::TyEncoder
 {
     fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
-        trace!("encoding {:?} at {}", alloc_id, self.position());
-        if let Some(shorthand) = self.interpret_alloc_shorthands.get(alloc_id).cloned() {
-            trace!("encoding {:?} as shorthand to {}", alloc_id, shorthand);
-            return shorthand.encode(self);
-        }
-        let start = self.position();
-        // cache the allocation shorthand now, because the allocation itself might recursively
-        // point to itself.
-        self.interpret_alloc_shorthands.insert(*alloc_id, start);
-        if let Some(alloc) = self.tcx.interpret_interner.get_alloc(*alloc_id) {
-            trace!("encoding {:?} with {:#?}", alloc_id, alloc);
-            usize::max_value().encode(self)?;
-            alloc.encode(self)?;
-            self.tcx.interpret_interner
-                .get_corresponding_static_def_id(*alloc_id)
-                .encode(self)?;
-        } else if let Some(fn_instance) = self.tcx.interpret_interner.get_fn(*alloc_id) {
-            trace!("encoding {:?} with {:#?}", alloc_id, fn_instance);
-            (usize::max_value() - 1).encode(self)?;
-            fn_instance.encode(self)?;
-        } else {
-            bug!("alloc id without corresponding allocation: {}", alloc_id);
-        }
-        Ok(())
+        use std::collections::hash_map::Entry;
+        let tcx = self.tcx;
+        let pos = self.position();
+        let shorthand = match self.interpret_alloc_shorthands.entry(*alloc_id) {
+            Entry::Occupied(entry) => Some(entry.get().clone()),
+            Entry::Vacant(entry) => {
+                // ensure that we don't place any AllocIds at the very beginning
+                // of the metadata file, because that would end up making our indices
+                // not special. It is essentially impossible for that to happen,
+                // but let's make sure
+                assert!(pos >= interpret::SHORTHAND_START);
+                entry.insert(pos);
+                None
+            },
+        };
+        interpret::specialized_encode_alloc_id(
+            self,
+            tcx,
+            *alloc_id,
+            shorthand,
+        )
     }
 }
 
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index bc7186f781a82..50a19526ba8c4 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -871,6 +871,9 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::GetPanicStrategy => { force!(panic_strategy, krate!()); }
         DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); }
         DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); }
+        DepKind::CheckItemWellFormed => { force!(check_item_well_formed, def_id!()); }
+        DepKind::CheckTraitItemWellFormed => { force!(check_trait_item_well_formed, def_id!()); }
+        DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); }
         DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); }
         DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
         DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
@@ -883,6 +886,9 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
             force!(all_trait_implementations, krate!());
         }
 
+        DepKind::DllimportForeignItems => {
+            force!(dllimport_foreign_items, krate!());
+        }
         DepKind::IsDllimportForeignItem => {
             force!(is_dllimport_foreign_item, def_id!());
         }
@@ -914,8 +920,6 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         }
         DepKind::UsedCrateSource => { force!(used_crate_source, krate!()); }
         DepKind::PostorderCnums => { force!(postorder_cnums, LOCAL_CRATE); }
-        DepKind::HasCloneClosures => { force!(has_clone_closures, krate!()); }
-        DepKind::HasCopyClosures => { force!(has_copy_closures, krate!()); }
 
         DepKind::Freevars => { force!(freevars, def_id!()); }
         DepKind::MaybeUnusedTraitImport => {
@@ -935,6 +939,11 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
 
         DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); }
         DepKind::Features => { force!(features_query, LOCAL_CRATE); }
+
+        DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); }
+        DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); }
+        DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); }
+        DepKind::ForeignModules => { force!(foreign_modules, krate!()); }
     }
 
     true
@@ -1001,4 +1010,5 @@ impl_load_from_cache!(
     PredicatesOfItem => predicates_of,
     UsedTraitImports => used_trait_imports,
     TransFnAttrs => trans_fn_attrs,
+    SpecializationGraph => specialization_graph_of,
 );
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 09b11a36352e1..e1925d964b31e 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -21,6 +21,7 @@ use hir::map::DefPathData;
 use hir::svh::Svh;
 use ich::Fingerprint;
 use ich::StableHashingContext;
+use infer::canonical::{Canonical, Canonicalize};
 use middle::const_val::ConstVal;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
 use middle::privacy::AccessLevels;
@@ -34,6 +35,7 @@ use ty;
 use ty::subst::{Subst, Substs};
 use ty::util::{IntTypeExt, Discr};
 use ty::walk::TypeWalker;
+use util::captures::Captures;
 use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
 
 use serialize::{self, Encodable, Encoder};
@@ -553,6 +555,17 @@ pub type Ty<'tcx> = &'tcx TyS<'tcx>;
 impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {}
 impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {}
 
+pub type CanonicalTy<'gcx> = Canonical<'gcx, Ty<'gcx>>;
+
+impl <'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for Ty<'tcx> {
+    type Canonicalized = CanonicalTy<'gcx>;
+
+    fn intern(_gcx: TyCtxt<'_, 'gcx, 'gcx>,
+              value: Canonical<'gcx, Self::Lifted>) -> Self::Canonicalized {
+        value
+    }
+}
+
 /// A wrapper for slices with the additional invariant
 /// that the slice is interned and no other slice with
 /// the same contents can exist in the same context.
@@ -1073,9 +1086,12 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
-pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<ty::Region<'tcx>,
-                                                                   ty::Region<'tcx>>;
-pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>;
+pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>,
+                                                           ty::Region<'tcx>>;
+pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>,
+                                                         ty::Region<'tcx>>;
+pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<RegionOutlivesPredicate<'tcx>>;
+pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<TypeOutlivesPredicate<'tcx>>;
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct SubtypePredicate<'tcx> {
@@ -1883,7 +1899,6 @@ impl<'a, 'gcx, 'tcx> AdtDef {
     ) -> Option<Discr<'tcx>> {
         let param_env = ParamEnv::empty();
         let repr_type = self.repr.discr_type();
-        let bit_size = layout::Integer::from_attr(tcx, repr_type).size().bits();
         let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
         let instance = ty::Instance::new(expr_did, substs);
         let cid = GlobalId {
@@ -1893,25 +1908,13 @@ impl<'a, 'gcx, 'tcx> AdtDef {
         match tcx.const_eval(param_env.and(cid)) {
             Ok(&ty::Const {
                 val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(b))),
-                ..
+                ty,
             }) => {
                 trace!("discriminants: {} ({:?})", b, repr_type);
-                let ty = repr_type.to_ty(tcx);
-                if repr_type.is_signed() {
-                    let val = b as i128;
-                    // sign extend to i128
-                    let amt = 128 - bit_size;
-                    let val = (val << amt) >> amt;
-                    Some(Discr {
-                        val: val as u128,
-                        ty,
-                    })
-                } else {
-                    Some(Discr {
-                        val: b,
-                        ty,
-                    })
-                }
+                Some(Discr {
+                    val: b,
+                    ty,
+                })
             },
             Ok(&ty::Const {
                 val: ConstVal::Value(other),
@@ -1939,8 +1942,10 @@ impl<'a, 'gcx, 'tcx> AdtDef {
     }
 
     #[inline]
-    pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
-                         -> impl Iterator<Item=Discr<'tcx>> + 'a {
+    pub fn discriminants(
+        &'a self,
+        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    ) -> impl Iterator<Item=Discr<'tcx>> + Captures<'gcx> + 'a {
         let repr_type = self.repr.discr_type();
         let initial = repr_type.initial_discriminant(tcx.global_tcx());
         let mut prev_discr = None::<Discr<'tcx>>;
@@ -2287,7 +2292,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     /// Returns an iterator of the def-ids for all body-owners in this
     /// crate. If you would prefer to iterate over the bodies
     /// themselves, you can do `self.hir.krate().body_ids.iter()`.
-    pub fn body_owners(self) -> impl Iterator<Item = DefId> + 'a {
+    pub fn body_owners(
+        self,
+    ) -> impl Iterator<Item = DefId> + Captures<'tcx> + Captures<'gcx> + 'a {
         self.hir.krate()
                 .body_ids
                 .iter()
@@ -2391,11 +2398,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
-    #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
-    pub fn associated_items(self, def_id: DefId)
-                            -> impl Iterator<Item = ty::AssociatedItem> + 'a {
+    pub fn associated_items(
+        self,
+        def_id: DefId,
+    ) -> impl Iterator<Item = ty::AssociatedItem> + 'a {
         let def_ids = self.associated_item_def_ids(def_id);
-        (0..def_ids.len()).map(move |i| self.associated_item(def_ids[i]))
+        Box::new((0..def_ids.len()).map(move |i| self.associated_item(def_ids[i])))
+            as Box<dyn Iterator<Item = ty::AssociatedItem> + 'a>
     }
 
     /// Returns true if the impls are the same polarity and are implementing
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index c9a69d5405c9a..3fc20508ad7ee 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -18,6 +18,7 @@ use ty::{self, Lift, Ty, TyCtxt};
 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use rustc_data_structures::accumulate_vec::AccumulateVec;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::sync::Lrc;
 use mir::interpret;
 
 use std::rc::Rc;
@@ -465,7 +466,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> {
         tcx.lift(&*self.kind).map(|kind| {
             ConstEvalErr {
                 span: self.span,
-                kind: Rc::new(kind),
+                kind: Lrc::new(kind),
             }
         })
     }
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index ae053d7f4f58d..2b88db503030d 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -18,6 +18,7 @@ use rustc_data_structures::indexed_vec::Idx;
 use ty::subst::{Substs, Subst, Kind, UnpackedKind};
 use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
 use ty::{Slice, TyS};
+use util::captures::Captures;
 
 use std::iter;
 use std::cmp::Ordering;
@@ -384,9 +385,11 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> {
     /// This returns the types of the MIR locals which had to be stored across suspension points.
     /// It is calculated in rustc_mir::transform::generator::StateTransform.
     /// All the types here must be in the tuple in GeneratorInterior.
-    pub fn state_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
-        impl Iterator<Item=Ty<'tcx>> + 'a
-    {
+    pub fn state_tys(
+        self,
+        def_id: DefId,
+        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    ) -> impl Iterator<Item=Ty<'tcx>> + Captures<'gcx> + 'a {
         let state = tcx.generator_layout(def_id).fields.iter();
         state.map(move |d| d.ty.subst(tcx, self.substs))
     }
@@ -403,7 +406,7 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> {
     /// This is the types of all the fields stored in a generator.
     /// It includes the upvars, state types and the state discriminant which is u32.
     pub fn field_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
-        impl Iterator<Item=Ty<'tcx>> + 'a
+        impl Iterator<Item=Ty<'tcx>> + Captures<'gcx> + 'a
     {
         self.pre_transforms_tys(def_id, tcx).chain(self.state_tys(def_id, tcx))
     }
@@ -991,10 +994,11 @@ pub type Region<'tcx> = &'tcx RegionKind;
 /// the inference variable is supposed to satisfy the relation
 /// *for every value of the skolemized region*. To ensure that doesn't
 /// happen, you can use `leak_check`. This is more clearly explained
-/// by infer/higher_ranked/README.md.
+/// by the [rustc guide].
 ///
 /// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
 /// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
+/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
 #[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
 pub enum RegionKind {
     // Region bound in a type or fn declaration which will be
@@ -1666,7 +1670,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
 pub struct Const<'tcx> {
     pub ty: Ty<'tcx>,
 
-    // FIXME(eddyb) Replace this with a miri value.
     pub val: ConstVal<'tcx>,
 }
 
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 91d460a96f785..afe977d10baac 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -39,16 +39,24 @@ use syntax_pos::{Span, DUMMY_SP};
 
 #[derive(Copy, Clone, Debug)]
 pub struct Discr<'tcx> {
+    /// bit representation of the discriminant, so `-128i8` is `0xFF_u128`
     pub val: u128,
     pub ty: Ty<'tcx>
 }
 
 impl<'tcx> fmt::Display for Discr<'tcx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        if self.ty.is_signed() {
-            write!(fmt, "{}", self.val as i128)
-        } else {
-            write!(fmt, "{}", self.val)
+        match self.ty.sty {
+            ty::TyInt(ity) => {
+                let bits = ty::tls::with(|tcx| {
+                    Integer::from_attr(tcx, SignedInt(ity)).size().bits()
+                });
+                let x = self.val as i128;
+                // sign extend the raw representation to be an i128
+                let x = (x << (128 - bits)) >> (128 - bits);
+                write!(fmt, "{}", x)
+            },
+            _ => write!(fmt, "{}", self.val),
         }
     }
 }
@@ -64,15 +72,18 @@ impl<'tcx> Discr<'tcx> {
             TyUint(uty) => (Integer::from_attr(tcx, UnsignedInt(uty)), false),
             _ => bug!("non integer discriminant"),
         };
+
+        let bit_size = int.size().bits();
+        let amt = 128 - bit_size;
         if signed {
-            let (min, max) = match int {
-                Integer::I8 => (i8::min_value() as i128, i8::max_value() as i128),
-                Integer::I16 => (i16::min_value() as i128, i16::max_value() as i128),
-                Integer::I32 => (i32::min_value() as i128, i32::max_value() as i128),
-                Integer::I64 => (i64::min_value() as i128, i64::max_value() as i128),
-                Integer::I128 => (i128::min_value(), i128::max_value()),
+            let sext = |u| {
+                let i = u as i128;
+                (i << amt) >> amt
             };
-            let val = self.val as i128;
+            let min = sext(1_u128 << (bit_size - 1));
+            let max = i128::max_value() >> amt;
+            let val = sext(self.val);
+            assert!(n < (i128::max_value() as u128));
             let n = n as i128;
             let oflo = val > max - n;
             let val = if oflo {
@@ -80,22 +91,19 @@ impl<'tcx> Discr<'tcx> {
             } else {
                 val + n
             };
+            // zero the upper bits
+            let val = val as u128;
+            let val = (val << amt) >> amt;
             (Self {
                 val: val as u128,
                 ty: self.ty,
             }, oflo)
         } else {
-            let (min, max) = match int {
-                Integer::I8 => (u8::min_value() as u128, u8::max_value() as u128),
-                Integer::I16 => (u16::min_value() as u128, u16::max_value() as u128),
-                Integer::I32 => (u32::min_value() as u128, u32::max_value() as u128),
-                Integer::I64 => (u64::min_value() as u128, u64::max_value() as u128),
-                Integer::I128 => (u128::min_value(), u128::max_value()),
-            };
+            let max = u128::max_value() >> amt;
             let val = self.val;
             let oflo = val > max - n;
             let val = if oflo {
-                min + (n - (max - val) - 1)
+                n - (max - val) - 1
             } else {
                 val + n
             };
diff --git a/src/librustc/util/captures.rs b/src/librustc/util/captures.rs
new file mode 100644
index 0000000000000..b68cfd278fa9e
--- /dev/null
+++ b/src/librustc/util/captures.rs
@@ -0,0 +1,18 @@
+// Copyright 2012-2014 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.
+
+/// "Signaling" trait used in impl trait to tag lifetimes that you may
+/// need to capture but don't really need for other reasons.
+/// Basically a workaround; see [this comment] for details.
+///
+/// [this comment]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999
+pub trait Captures<'a> { }
+
+impl<'a, T: ?Sized> Captures<'a> for T { }
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 2c3ee1ec285a9..056f1278c47c7 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -1177,8 +1177,8 @@ define_print! {
                         ConstVal::Value(Value::ByVal(PrimVal::Bytes(sz))) => {
                             write!(f, "{}", sz)?;
                         }
-                        ConstVal::Unevaluated(_def_id, substs) => {
-                            write!(f, "<unevaluated{:?}>", &substs[..])?;
+                        ConstVal::Unevaluated(_def_id, _substs) => {
+                            write!(f, "_")?;
                         }
                         _ => {
                             write!(f, "{:?}", sz)?;
diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs
index c088458c3557c..ee38cca7828be 100644
--- a/src/librustc_allocator/expand.rs
+++ b/src/librustc_allocator/expand.rs
@@ -99,7 +99,7 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> {
             f.cx.item_extern_crate(f.span, f.alloc),
             f.cx.item_use_simple(
                 f.span,
-                respan(f.span.empty(), VisibilityKind::Inherited),
+                respan(f.span.shrink_to_lo(), VisibilityKind::Inherited),
                 super_path,
             ),
         ];
@@ -145,7 +145,7 @@ impl<'a> AllocFnFactory<'a> {
         let result = self.call_allocator(method.name, args);
         let (output_ty, output_expr) =
             self.ret_ty(&method.output, &mut abi_args, mk, result);
-        let kind = ItemKind::Fn(self.cx.fn_decl(abi_args, output_ty),
+        let kind = ItemKind::Fn(self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)),
                                 Unsafety::Unsafe,
                                 dummy_spanned(Constness::NotConst),
                                 Abi::Rust,
diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs
index 3afc2f684009d..6f08fcf702595 100644
--- a/src/librustc_apfloat/lib.rs
+++ b/src/librustc_apfloat/lib.rs
@@ -46,9 +46,9 @@
 #![deny(warnings)]
 #![forbid(unsafe_code)]
 
-#![feature(i128_type)]
-#![feature(slice_patterns)]
-#![feature(try_from)]
+#![cfg_attr(stage0, feature(slice_patterns))]
+#![cfg_attr(stage0, feature(i128_type))]
+#![cfg_attr(stage0, feature(try_from))]
 
 // See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
 #[allow(unused_extern_crates)]
diff --git a/src/librustc_apfloat/tests/ieee.rs b/src/librustc_apfloat/tests/ieee.rs
index ff46ee79c31d0..627d79724b28a 100644
--- a/src/librustc_apfloat/tests/ieee.rs
+++ b/src/librustc_apfloat/tests/ieee.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 
 #[macro_use]
 extern crate rustc_apfloat;
diff --git a/src/librustc_back/README.md b/src/librustc_back/README.md
index bd99c687bb6ad..3c01692c12b3c 100644
--- a/src/librustc_back/README.md
+++ b/src/librustc_back/README.md
@@ -1,6 +1,6 @@
-NB: This crate is part of the Rust compiler. For an overview of the
-compiler as a whole, see
-[the README.md file found in `librustc`](../librustc/README.md).
-
 `librustc_back` contains some very low-level details that are
 specific to different LLVM targets and so forth.
+
+For more information about how trans works, see the [rustc guide].
+
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trans.html
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index f53eeb86a9c56..507243a58a5f9 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -47,6 +47,8 @@
 use serialize::json::{Json, ToJson};
 use std::collections::BTreeMap;
 use std::default::Default;
+use std::{fmt, io};
+use std::path::{Path, PathBuf};
 use syntax::abi::{Abi, lookup as lookup_abi};
 
 use {LinkerFlavor, PanicStrategy, RelroLevel};
@@ -824,11 +826,10 @@ impl Target {
     ///
     /// The error string could come from any of the APIs called, including
     /// filesystem access and JSON decoding.
-    pub fn search(target: &str) -> Result<Target, String> {
+    pub fn search(target_triple: &TargetTriple) -> Result<Target, String> {
         use std::env;
         use std::ffi::OsString;
         use std::fs;
-        use std::path::{Path, PathBuf};
         use serialize::json;
 
         fn load_file(path: &Path) -> Result<Target, String> {
@@ -838,35 +839,40 @@ impl Target {
             Target::from_json(obj)
         }
 
-        if let Ok(t) = load_specific(target) {
-            return Ok(t)
-        }
-
-        let path = Path::new(target);
-
-        if path.is_file() {
-            return load_file(&path);
-        }
+        match target_triple {
+            &TargetTriple::TargetTriple(ref target_triple) => {
+                // check if triple is in list of supported targets
+                if let Ok(t) = load_specific(target_triple) {
+                    return Ok(t)
+                }
 
-        let path = {
-            let mut target = target.to_string();
-            target.push_str(".json");
-            PathBuf::from(target)
-        };
+                // search for a file named `target_triple`.json in RUST_TARGET_PATH
+                let path = {
+                    let mut target = target_triple.to_string();
+                    target.push_str(".json");
+                    PathBuf::from(target)
+                };
 
-        let target_path = env::var_os("RUST_TARGET_PATH")
-                              .unwrap_or(OsString::new());
+                let target_path = env::var_os("RUST_TARGET_PATH")
+                                    .unwrap_or(OsString::new());
 
-        // FIXME 16351: add a sane default search path?
+                // FIXME 16351: add a sane default search path?
 
-        for dir in env::split_paths(&target_path) {
-            let p =  dir.join(&path);
-            if p.is_file() {
-                return load_file(&p);
+                for dir in env::split_paths(&target_path) {
+                    let p =  dir.join(&path);
+                    if p.is_file() {
+                        return load_file(&p);
+                    }
+                }
+                Err(format!("Could not find specification for target {:?}", target_triple))
+            }
+            &TargetTriple::TargetPath(ref target_path) => {
+                if target_path.is_file() {
+                    return load_file(&target_path);
+                }
+                Err(format!("Target path {:?} is not a valid file", target_path))
             }
         }
-
-        Err(format!("Could not find specification for target {:?}", target))
     }
 }
 
@@ -1014,3 +1020,61 @@ fn maybe_jemalloc() -> Option<String> {
         None
     }
 }
+
+/// Either a target triple string or a path to a JSON file.
+#[derive(PartialEq, Clone, Debug, Hash, RustcEncodable, RustcDecodable)]
+pub enum TargetTriple {
+    TargetTriple(String),
+    TargetPath(PathBuf),
+}
+
+impl TargetTriple {
+    /// Creates a target triple from the passed target triple string.
+    pub fn from_triple(triple: &str) -> Self {
+        TargetTriple::TargetTriple(triple.to_string())
+    }
+
+    /// Creates a target triple from the passed target path.
+    pub fn from_path(path: &Path) -> Result<Self, io::Error> {
+        let canonicalized_path = path.canonicalize()?;
+        Ok(TargetTriple::TargetPath(canonicalized_path))
+    }
+
+    /// Returns a string triple for this target.
+    ///
+    /// If this target is a path, the file name (without extension) is returned.
+    pub fn triple(&self) -> &str {
+        match self {
+            &TargetTriple::TargetTriple(ref triple) => triple,
+            &TargetTriple::TargetPath(ref path) => {
+                path.file_stem().expect("target path must not be empty").to_str()
+                    .expect("target path must be valid unicode")
+            }
+        }
+    }
+
+    /// Returns an extended string triple for this target.
+    ///
+    /// If this target is a path, a hash of the path is appended to the triple returned
+    /// by `triple()`.
+    pub fn debug_triple(&self) -> String {
+        use std::hash::{Hash, Hasher};
+        use std::collections::hash_map::DefaultHasher;
+
+        let triple = self.triple();
+        if let &TargetTriple::TargetPath(ref path) = self {
+            let mut hasher = DefaultHasher::new();
+            path.hash(&mut hasher);
+            let hash = hasher.finish();
+            format!("{}-{}", triple, hash)
+        } else {
+            triple.to_owned()
+        }
+    }
+}
+
+impl fmt::Display for TargetTriple {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.debug_triple())
+    }
+}
diff --git a/src/librustc_borrowck/borrowck/README.md b/src/librustc_borrowck/borrowck/README.md
index da2b1ef0b1c02..29f03c06ab759 100644
--- a/src/librustc_borrowck/borrowck/README.md
+++ b/src/librustc_borrowck/borrowck/README.md
@@ -1,5 +1,10 @@
 % The Borrow Checker
 
+> WARNING: This README is more or less obsolete, and will be removed
+> soon! The new system is described in the [rustc guide].
+
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+
 This pass has the job of enforcing memory safety. This is a subtle
 topic. This docs aim to explain both the practice and the theory
 behind the borrow checker. They start with a high-level overview of
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index bb198adea4a6a..93d6247eeae47 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -253,28 +253,28 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
     used_mut_nodes: RefCell<FxHashSet<HirId>>,
 }
 
-impl<'b, 'tcx: 'b> BorrowckErrors for BorrowckCtxt<'b, 'tcx> {
-    fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
-                                                         sp: S,
-                                                         msg: &str,
-                                                         code: DiagnosticId)
-                                                         -> DiagnosticBuilder<'a>
+impl<'a, 'b, 'tcx: 'b> BorrowckErrors<'a> for &'a BorrowckCtxt<'b, 'tcx> {
+    fn struct_span_err_with_code<S: Into<MultiSpan>>(self,
+                                                     sp: S,
+                                                     msg: &str,
+                                                     code: DiagnosticId)
+                                                     -> DiagnosticBuilder<'a>
     {
         self.tcx.sess.struct_span_err_with_code(sp, msg, code)
     }
 
-    fn struct_span_err<'a, S: Into<MultiSpan>>(&'a self,
-                                               sp: S,
-                                               msg: &str)
-                                               -> DiagnosticBuilder<'a>
+    fn struct_span_err<S: Into<MultiSpan>>(self,
+                                           sp: S,
+                                           msg: &str)
+                                           -> DiagnosticBuilder<'a>
     {
         self.tcx.sess.struct_span_err(sp, msg)
     }
 
-    fn cancel_if_wrong_origin<'a>(&'a self,
-                                mut diag: DiagnosticBuilder<'a>,
-                                o: Origin)
-                                -> DiagnosticBuilder<'a>
+    fn cancel_if_wrong_origin(self,
+                              mut diag: DiagnosticBuilder<'a>,
+                              o: Origin)
+                              -> DiagnosticBuilder<'a>
     {
         if !o.should_emit_errors(self.tcx.borrowck_mode()) {
             self.tcx.sess.diagnostic().cancel(&mut diag);
diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs
index 2bdee3198f22a..d54654c60868c 100644
--- a/src/librustc_borrowck/lib.rs
+++ b/src/librustc_borrowck/lib.rs
@@ -16,7 +16,7 @@
 #![allow(non_camel_case_types)]
 
 #![feature(from_ref)]
-#![feature(match_default_bindings)]
+#![cfg_attr(stage0, feature(match_default_bindings))]
 #![feature(quote)]
 
 #[macro_use] extern crate log;
diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs
index 459aa9ea488fd..2620448927d86 100644
--- a/src/librustc_const_eval/lib.rs
+++ b/src/librustc_const_eval/lib.rs
@@ -20,11 +20,10 @@
 #![deny(warnings)]
 
 #![feature(rustc_diagnostic_macros)]
-#![feature(slice_patterns)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(macro_lifetime_matcher)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(from_ref)]
 
 extern crate arena;
diff --git a/src/librustc_const_math/lib.rs b/src/librustc_const_math/lib.rs
index 5555e727a9552..7177e2818fbcc 100644
--- a/src/librustc_const_math/lib.rs
+++ b/src/librustc_const_math/lib.rs
@@ -19,8 +19,7 @@
       html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![deny(warnings)]
 
-#![feature(i128)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type, i128))]
 
 extern crate rustc_apfloat;
 
diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs
index a5b1a7e57ab46..cbb3ff5171592 100644
--- a/src/librustc_data_structures/indexed_vec.rs
+++ b/src/librustc_data_structures/indexed_vec.rs
@@ -503,6 +503,13 @@ impl<I: Idx, T> IndexVec<I, T> {
             (c1, c2)
         }
     }
+
+    pub fn convert_index_type<Ix: Idx>(self) -> IndexVec<Ix, T> {
+        IndexVec {
+            raw: self.raw,
+            _marker: PhantomData,
+        }
+    }
 }
 
 impl<I: Idx, T: Clone> IndexVec<I, T> {
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 81246aea1b56e..378a06dd9120a 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -26,15 +26,14 @@
 #![feature(unboxed_closures)]
 #![feature(fn_traits)]
 #![feature(unsize)]
-#![feature(i128_type)]
-#![feature(i128)]
-#![feature(conservative_impl_trait)]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
+#![cfg_attr(stage0, feature(i128_type, i128))]
 #![feature(specialization)]
 #![feature(optin_builtin_traits)]
 #![feature(underscore_lifetimes)]
 #![feature(macro_vis_matcher)]
 #![feature(allow_internal_unstable)]
-#![feature(universal_impl_trait)]
+#![cfg_attr(stage0, feature(universal_impl_trait))]
 
 #![cfg_attr(unix, feature(libc))]
 #![cfg_attr(test, feature(test))]
@@ -76,6 +75,14 @@ pub mod flock;
 pub mod sync;
 pub mod owning_ref;
 
+pub struct OnDrop<F: Fn()>(pub F);
+
+impl<F: Fn()> Drop for OnDrop<F> {
+      fn drop(&mut self) {
+            (self.0)();
+      }
+}
+
 // See comments in src/librustc/lib.rs
 #[doc(hidden)]
 pub fn __noop_fix_for_27438() {}
diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs
index d7cd459e5771c..184ef1369761c 100644
--- a/src/librustc_data_structures/sync.rs
+++ b/src/librustc_data_structures/sync.rs
@@ -26,11 +26,6 @@
 //!
 //! `MTLock` is a mutex which disappears if cfg!(parallel_queries) is false.
 //!
-//! `rustc_global!` gives us a way to declare variables which are intended to be
-//! global for the current rustc session. This currently maps to thread-locals,
-//! since rustdoc uses the rustc libraries in multiple threads.
-//! These globals should eventually be moved into the `Session` structure.
-//!
 //! `rustc_erase_owner!` erases a OwningRef owner into Erased or Erased + Send + Sync
 //! depending on the value of cfg!(parallel_queries).
 
@@ -228,31 +223,6 @@ pub fn assert_sync<T: ?Sized + Sync>() {}
 pub fn assert_send_val<T: ?Sized + Send>(_t: &T) {}
 pub fn assert_send_sync_val<T: ?Sized + Sync + Send>(_t: &T) {}
 
-#[macro_export]
-#[allow_internal_unstable]
-macro_rules! rustc_global {
-    // empty (base case for the recursion)
-    () => {};
-
-    // process multiple declarations
-    ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
-        thread_local!($(#[$attr])* $vis static $name: $t = $init);
-        rustc_global!($($rest)*);
-    );
-
-    // handle a single declaration
-    ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr) => (
-        thread_local!($(#[$attr])* $vis static $name: $t = $init);
-    );
-}
-
-#[macro_export]
-macro_rules! rustc_access_global {
-    ($name:path, $callback:expr) => {
-        $name.with($callback)
-    }
-}
-
 impl<T: Copy + Debug> Debug for LockCell<T> {
     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
         f.debug_struct("LockCell")
@@ -363,6 +333,13 @@ impl<T> Lock<T> {
     }
 }
 
+impl<T: Default> Default for Lock<T> {
+    #[inline]
+    fn default() -> Self {
+        Lock::new(T::default())
+    }
+}
+
 // FIXME: Probably a bad idea
 impl<T: Clone> Clone for Lock<T> {
     #[inline]
diff --git a/src/librustc_driver/README.md b/src/librustc_driver/README.md
index 839d1831f9544..fef249a9e4eb8 100644
--- a/src/librustc_driver/README.md
+++ b/src/librustc_driver/README.md
@@ -1,7 +1,3 @@
-NB: This crate is part of the Rust compiler. For an overview of the
-compiler as a whole, see
-[the README.md file found in `librustc`](../librustc/README.md).
-
 The `driver` crate is effectively the "main" function for the rust
 compiler.  It orchestrates the compilation process and "knits together"
 the code from the other crates within rustc. This crate itself does
@@ -9,4 +5,6 @@ not contain any of the "main logic" of the compiler (though it does
 have some code related to pretty printing or other minor compiler
 options).
 
+For more information about how the driver works, see the [rustc guide].
 
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/rustc-driver.html
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index b5e31bdf6686a..a3115544f30b9 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -648,7 +648,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
 {
     let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess,
                                                          sess.opts.test,
-                                                         sess.opts.debugging_opts.epoch);
+                                                         sess.opts.debugging_opts.edition);
     // these need to be set "early" so that expansion sees `quote` if enabled.
     sess.init_features(features);
 
@@ -683,7 +683,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
     });
 
     krate = time(sess, "crate injection", || {
-        let alt_std_name = sess.opts.alt_std_name.clone();
+        let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| &**s);
         syntax::std_inject::maybe_inject_crates_ref(krate, alt_std_name)
     });
 
@@ -1091,6 +1091,10 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate,
 
         time(sess, "lint checking", || lint::check_crate(tcx));
 
+        time(sess,
+             "dumping chalk-like clauses",
+             || rustc_traits::lowering::dump_program_clauses(tcx));
+
         return Ok(f(tcx, analysis, rx, tcx.sess.compile_status()));
     })
 }
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index f1f3a0519bbcb..b9bcbccb30ef3 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -63,6 +63,7 @@ use rustc_resolve as resolve;
 use rustc_save_analysis as save;
 use rustc_save_analysis::DumpHandler;
 use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::OnDrop;
 use rustc::session::{self, config, Session, build_session, CompileResult};
 use rustc::session::CompileIncomplete;
 use rustc::session::config::{Input, PrintRequest, ErrorOutputType};
@@ -515,30 +516,35 @@ fn run_compiler_impl<'a>(args: &[String],
     target_features::add_configuration(&mut cfg, &sess, &*trans);
     sess.parse_sess.config = cfg;
 
-    let plugins = sess.opts.debugging_opts.extra_plugins.clone();
-
-    let cstore = CStore::new(trans.metadata_loader());
-
-    do_or_return!(callbacks.late_callback(&*trans,
-                                          &matches,
-                                          &sess,
-                                          &cstore,
-                                          &input,
-                                          &odir,
-                                          &ofile), Some(sess));
-
-    let control = callbacks.build_controller(&sess, &matches);
-
-    (driver::compile_input(trans,
-                           &sess,
-                           &cstore,
-                           &input_file_path,
-                           &input,
-                           &odir,
-                           &ofile,
-                           Some(plugins),
-                           &control),
-     Some(sess))
+    let result = {
+        let plugins = sess.opts.debugging_opts.extra_plugins.clone();
+
+        let cstore = CStore::new(trans.metadata_loader());
+
+        do_or_return!(callbacks.late_callback(&*trans,
+                                              &matches,
+                                              &sess,
+                                              &cstore,
+                                              &input,
+                                              &odir,
+                                              &ofile), Some(sess));
+
+        let _sess_abort_error = OnDrop(|| sess.diagnostic().print_error_count());
+
+        let control = callbacks.build_controller(&sess, &matches);
+
+        driver::compile_input(trans,
+                              &sess,
+                              &cstore,
+                              &input_file_path,
+                              &input,
+                              &odir,
+                              &ofile,
+                              Some(plugins),
+                              &control)
+    };
+
+    (result, Some(sess))
 }
 
 // Extract output directory and file from matches.
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index a25c3668bb13b..37ae64cef5725 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -17,8 +17,8 @@
 #![allow(unused_attributes)]
 #![feature(range_contains)]
 #![cfg_attr(unix, feature(libc))]
-#![feature(conservative_impl_trait)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(optin_builtin_traits)]
 
 extern crate atty;
@@ -558,21 +558,15 @@ impl Handler {
     pub fn has_errors(&self) -> bool {
         self.err_count() > 0
     }
-    pub fn abort_if_errors(&self) {
-        let s;
-        match self.err_count() {
-            0 => {
-                if let Some(bug) = self.delayed_span_bug.borrow_mut().take() {
-                    DiagnosticBuilder::new_diagnostic(self, bug).emit();
-                }
-                return;
-            }
-            1 => s = "aborting due to previous error".to_string(),
-            _ => {
-                s = format!("aborting due to {} previous errors", self.err_count());
-            }
-        }
-        let err = self.fatal(&s);
+
+    pub fn print_error_count(&self) {
+        let s = match self.err_count() {
+            0 => return,
+            1 => "aborting due to previous error".to_string(),
+            _ => format!("aborting due to {} previous errors", self.err_count())
+        };
+
+        let _ = self.fatal(&s);
 
         let can_show_explain = self.emitter.borrow().should_show_explain();
         let are_there_diagnostics = !self.tracked_diagnostic_codes.borrow().is_empty();
@@ -603,8 +597,16 @@ impl Handler {
                 }
             }
         }
+    }
 
-        err.raise();
+    pub fn abort_if_errors(&self) {
+        if self.err_count() == 0 {
+            if let Some(bug) = self.delayed_span_bug.borrow_mut().take() {
+                DiagnosticBuilder::new_diagnostic(self, bug).emit();
+            }
+            return;
+        }
+        FatalError.raise();
     }
     pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) {
         if lvl == Warning && !self.flags.can_emit_warnings {
diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs
index d7ccf9d5562e6..5a33f566e903a 100644
--- a/src/librustc_incremental/lib.rs
+++ b/src/librustc_incremental/lib.rs
@@ -15,9 +15,9 @@
       html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![deny(warnings)]
 
-#![feature(conservative_impl_trait)]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
 #![feature(fs_read_write)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![cfg_attr(stage0, feature(inclusive_range_syntax))]
 #![feature(specialization)]
 
diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs
index ca1e3563089db..a5bc1106ba0b0 100644
--- a/src/librustc_incremental/persist/save.rs
+++ b/src/librustc_incremental/persist/save.rs
@@ -162,7 +162,7 @@ fn encode_dep_graph(tcx: TyCtxt,
 
         let mut counts: FxHashMap<_, Stat> = FxHashMap();
 
-        for (i, &(node, _)) in serialized_graph.nodes.iter_enumerated() {
+        for (i, &node) in serialized_graph.nodes.iter_enumerated() {
             let stat = counts.entry(node.kind).or_insert(Stat {
                 kind: node.kind,
                 node_counter: 0,
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 031033f7208e1..c0728cb2b6669 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -46,6 +46,7 @@ use syntax::attr;
 use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes};
 use syntax_pos::{BytePos, Span, SyntaxContext};
 use syntax::symbol::keywords;
+use syntax::errors::DiagnosticBuilder;
 
 use rustc::hir::{self, PatKind};
 use rustc::hir::intravisit::FnKind;
@@ -1082,7 +1083,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
                     if !cx.access_levels.is_reachable(it.id) {
                         let msg = "function is marked #[no_mangle], but not exported";
                         let mut err = cx.struct_span_lint(PRIVATE_NO_MANGLE_FNS, it.span, msg);
-                        let insertion_span = it.span.with_hi(it.span.lo());
+                        let insertion_span = it.span.shrink_to_lo();
                         if it.vis == hir::Visibility::Inherited {
                             err.span_suggestion(insertion_span,
                                                 "try making it public",
@@ -1107,7 +1108,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
                    !cx.access_levels.is_reachable(it.id) {
                        let msg = "static is marked #[no_mangle], but not exported";
                        let mut err = cx.struct_span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, msg);
-                       let insertion_span = it.span.with_hi(it.span.lo());
+                       let insertion_span = it.span.shrink_to_lo();
                        if it.vis == hir::Visibility::Inherited {
                            err.span_suggestion(insertion_span,
                                                "try making it public",
@@ -1316,48 +1317,115 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub {
     }
 }
 
-/// Lint for trait and lifetime bounds that are (accidentally) accepted by the parser, but
-/// ignored later.
+/// Lint for trait and lifetime bounds in type aliases being mostly ignored:
+/// They are relevant when using associated types, but otherwise neither checked
+/// at definition site nor enforced at use site.
 
-pub struct IgnoredGenericBounds;
+pub struct TypeAliasBounds;
 
 declare_lint! {
-    IGNORED_GENERIC_BOUNDS,
+    TYPE_ALIAS_BOUNDS,
     Warn,
-    "these generic bounds are ignored"
+    "bounds in type aliases are not enforced"
 }
 
-impl LintPass for IgnoredGenericBounds {
+impl LintPass for TypeAliasBounds {
     fn get_lints(&self) -> LintArray {
-        lint_array!(IGNORED_GENERIC_BOUNDS)
+        lint_array!(TYPE_ALIAS_BOUNDS)
     }
 }
 
-impl EarlyLintPass for IgnoredGenericBounds {
-    fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) {
-        let type_alias_generics = match item.node {
-            ast::ItemKind::Ty(_, ref generics) => generics,
+impl TypeAliasBounds {
+    fn is_type_variable_assoc(qpath: &hir::QPath) -> bool {
+        match *qpath {
+            hir::QPath::TypeRelative(ref ty, _) => {
+                // If this is a type variable, we found a `T::Assoc`.
+                match ty.node {
+                    hir::TyPath(hir::QPath::Resolved(None, ref path)) => {
+                        match path.def {
+                            Def::TyParam(_) => true,
+                            _ => false
+                        }
+                    }
+                    _ => false
+                }
+            }
+            hir::QPath::Resolved(..) => false,
+        }
+    }
+
+    fn suggest_changing_assoc_types(ty: &hir::Ty, err: &mut DiagnosticBuilder) {
+        // Access to associates types should use `<T as Bound>::Assoc`, which does not need a
+        // bound.  Let's see if this type does that.
+
+        // We use a HIR visitor to walk the type.
+        use rustc::hir::intravisit::{self, Visitor};
+        use syntax::ast::NodeId;
+        struct WalkAssocTypes<'a, 'db> where 'db: 'a {
+            err: &'a mut DiagnosticBuilder<'db>
+        }
+        impl<'a, 'db, 'v> Visitor<'v> for WalkAssocTypes<'a, 'db> {
+            fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'v>
+            {
+                intravisit::NestedVisitorMap::None
+            }
+
+            fn visit_qpath(&mut self, qpath: &'v hir::QPath, id: NodeId, span: Span) {
+                if TypeAliasBounds::is_type_variable_assoc(qpath) {
+                    self.err.span_help(span,
+                        "use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to \
+                         associated types in type aliases");
+                }
+                intravisit::walk_qpath(self, qpath, id, span)
+            }
+        }
+
+        // Let's go for a walk!
+        let mut visitor = WalkAssocTypes { err };
+        visitor.visit_ty(ty);
+    }
+}
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds {
+    fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
+        let (ty, type_alias_generics) = match item.node {
+            hir::ItemTy(ref ty, ref generics) => (&*ty, generics),
             _ => return,
         };
+        let mut suggested_changing_assoc_types = false;
         // There must not be a where clause
         if !type_alias_generics.where_clause.predicates.is_empty() {
             let spans : Vec<_> = type_alias_generics.where_clause.predicates.iter()
                 .map(|pred| pred.span()).collect();
-            cx.span_lint(IGNORED_GENERIC_BOUNDS, spans,
-                "where clauses are ignored in type aliases");
+            let mut err = cx.struct_span_lint(TYPE_ALIAS_BOUNDS, spans,
+                "where clauses are not enforced in type aliases");
+            err.help("the clause will not be checked when the type alias is used, \
+                      and should be removed");
+            if !suggested_changing_assoc_types {
+                TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err);
+                suggested_changing_assoc_types = true;
+            }
+            err.emit();
         }
         // The parameters must not have bounds
         for param in type_alias_generics.params.iter() {
             let spans : Vec<_> = match param {
-                &ast::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(),
-                &ast::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(),
+                &hir::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(),
+                &hir::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(),
             };
             if !spans.is_empty() {
-                cx.span_lint(
-                    IGNORED_GENERIC_BOUNDS,
+                let mut err = cx.struct_span_lint(
+                    TYPE_ALIAS_BOUNDS,
                     spans,
-                    "bounds on generic parameters are ignored in type aliases",
+                    "bounds on generic parameters are not enforced in type aliases",
                 );
+                err.help("the bound will not be checked when the type alias is used, \
+                          and should be removed");
+                if !suggested_changing_assoc_types {
+                    TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err);
+                    suggested_changing_assoc_types = true;
+                }
+                err.emit();
             }
         }
     }
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 8b86c90548952..d024adad9d030 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -27,11 +27,10 @@
 #![cfg_attr(test, feature(test))]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(macro_vis_matcher)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
-#![feature(slice_patterns)]
 #![cfg_attr(stage0, feature(never_type))]
 
 #[macro_use]
@@ -49,7 +48,7 @@ use rustc::session;
 use rustc::util;
 
 use session::Session;
-use syntax::epoch::Epoch;
+use syntax::edition::Edition;
 use lint::LintId;
 use lint::FutureIncompatibleInfo;
 
@@ -110,7 +109,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
                        UnusedImportBraces,
                        AnonymousParameters,
                        UnusedDocComment,
-                       IgnoredGenericBounds,
                        );
 
     add_early_builtin_with_new!(sess,
@@ -140,6 +138,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
                  MutableTransmutes,
                  UnionsWithDropFields,
                  UnreachablePub,
+                 TypeAliasBounds,
                  );
 
     add_builtin_with_new!(sess,
@@ -198,83 +197,90 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
         FutureIncompatibleInfo {
             id: LintId::of(PRIVATE_IN_PUBLIC),
             reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE),
             reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
             reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(SAFE_EXTERN_STATICS),
             reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
             reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP),
             reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(LEGACY_IMPORTS),
             reference: "issue #38260 <https://github.com/rust-lang/rust/issues/38260>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY),
             reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(MISSING_FRAGMENT_SPECIFIER),
             reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN),
             reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(ANONYMOUS_PARAMETERS),
             reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES),
             reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS),
             reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(SAFE_PACKED_BORROWS),
             reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS),
             reference: "issue #46205 <https://github.com/rust-lang/rust/issues/46205>",
-            epoch: None,
+            edition: None,
         },
         FutureIncompatibleInfo {
             id: LintId::of(TYVAR_BEHIND_RAW_POINTER),
             reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
-            epoch: Some(Epoch::Epoch2018),
-        }
+            edition: Some(Edition::Edition2018),
+        },
+        FutureIncompatibleInfo {
+            id: LintId::of(UNSTABLE_NAME_COLLISION),
+            reference: "issue #48919 <https://github.com/rust-lang/rust/issues/48919>",
+            edition: None,
+            // Note: this item represents future incompatibility of all unstable functions in the
+            //       standard library, and thus should never be removed or changed to an error.
+        },
         ]);
 
     // Register renamed and removed lints
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index d777f6f19b0ff..86f79c553c391 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -377,11 +377,12 @@ impl UnusedImportBraces {
             // Trigger the lint if the nested item is a non-self single item
             let node_ident;
             match items[0].0.kind {
-                ast::UseTreeKind::Simple(ident) => {
-                    if ident.name == keywords::SelfValue.name() {
+                ast::UseTreeKind::Simple(rename) => {
+                    let orig_ident = items[0].0.prefix.segments.last().unwrap().identifier;
+                    if orig_ident.name == keywords::SelfValue.name() {
                         return;
                     } else {
-                        node_ident = ident;
+                        node_ident = rename.unwrap_or(orig_ident);
                     }
                 }
                 ast::UseTreeKind::Glob => {
diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs
index c5cdf6566921c..e73c570ed8231 100644
--- a/src/librustc_llvm/diagnostic.rs
+++ b/src/librustc_llvm/diagnostic.rs
@@ -121,6 +121,7 @@ impl InlineAsmDiagnostic {
 pub enum Diagnostic {
     Optimization(OptimizationDiagnostic),
     InlineAsm(InlineAsmDiagnostic),
+    PGO(DiagnosticInfoRef),
 
     /// LLVM has other types that we do not wrap here.
     UnknownDiagnostic(DiagnosticInfoRef),
@@ -160,6 +161,10 @@ impl Diagnostic {
                 Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
             }
 
+            Dk::PGOProfile => {
+                PGO(di)
+            }
+
             _ => UnknownDiagnostic(di),
         }
     }
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index c0cdd21277062..dba2e918f6f3a 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -322,6 +322,7 @@ pub enum DiagnosticKind {
     OptimizationRemarkAnalysisAliasing,
     OptimizationRemarkOther,
     OptimizationFailure,
+    PGOProfile,
 }
 
 /// LLVMRustArchiveKind
@@ -935,6 +936,11 @@ extern "C" {
                          RHS: ValueRef,
                          Name: *const c_char)
                          -> ValueRef;
+    pub fn LLVMBuildExactUDiv(B: BuilderRef,
+                              LHS: ValueRef,
+                              RHS: ValueRef,
+                              Name: *const c_char)
+                              -> ValueRef;
     pub fn LLVMBuildSDiv(B: BuilderRef,
                          LHS: ValueRef,
                          RHS: ValueRef,
@@ -1242,6 +1248,9 @@ extern "C" {
                                          IsNaN: bool)
                                          -> ValueRef;
 
+    pub fn LLVMRustBuildMinNum(B: BuilderRef, LHS: ValueRef, LHS: ValueRef) -> ValueRef;
+    pub fn LLVMRustBuildMaxNum(B: BuilderRef, LHS: ValueRef, LHS: ValueRef) -> ValueRef;
+
     pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef;
     pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef;
     pub fn LLVMBuildPtrDiff(B: BuilderRef,
@@ -1641,7 +1650,9 @@ extern "C" {
                                                OptLevel: CodeGenOptLevel,
                                                MergeFunctions: bool,
                                                SLPVectorize: bool,
-                                               LoopVectorize: bool);
+                                               LoopVectorize: bool,
+                                               PGOGenPath: *const c_char,
+                                               PGOUsePath: *const c_char);
     pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef,
                                   M: ModuleRef,
                                   DisableSimplifyLibCalls: bool);
@@ -1736,6 +1747,7 @@ extern "C" {
     pub fn LLVMRustModuleCost(M: ModuleRef) -> u64;
 
     pub fn LLVMRustThinLTOAvailable() -> bool;
+    pub fn LLVMRustPGOAvailable() -> bool;
     pub fn LLVMRustWriteThinBitcodeToFile(PMR: PassManagerRef,
                                           M: ModuleRef,
                                           BC: *const c_char) -> bool;
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index b2f014b930d60..13ebb5f61660f 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -12,7 +12,6 @@
 
 use cstore::{self, CStore, CrateSource, MetadataBlob};
 use locator::{self, CratePaths};
-use native_libs::relevant_lib;
 use schema::CrateRoot;
 use rustc_data_structures::sync::{Lrc, RwLock, Lock};
 
@@ -23,6 +22,7 @@ use rustc::middle::cstore::DepKind;
 use rustc::session::{Session, CrateDisambiguator};
 use rustc::session::config::{Sanitizer, self};
 use rustc_back::PanicStrategy;
+use rustc_back::target::TargetTriple;
 use rustc::session::search_paths::PathKind;
 use rustc::middle;
 use rustc::middle::cstore::{validate_crate_name, ExternCrate};
@@ -230,7 +230,7 @@ impl<'a> CrateLoader<'a> {
             .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
             .collect();
 
-        let mut cmeta = cstore::CrateMetadata {
+        let cmeta = cstore::CrateMetadata {
             name,
             extern_crate: Lock::new(None),
             def_path_table: Lrc::new(def_path_table),
@@ -250,25 +250,8 @@ impl<'a> CrateLoader<'a> {
                 rlib,
                 rmeta,
             },
-            // Initialize this with an empty set. The field is populated below
-            // after we were able to deserialize its contents.
-            dllimport_foreign_items: FxHashSet(),
         };
 
-        let dllimports: FxHashSet<_> = cmeta
-            .root
-            .native_libraries
-            .decode((&cmeta, self.sess))
-            .filter(|lib| relevant_lib(self.sess, lib) &&
-                          lib.kind == cstore::NativeLibraryKind::NativeUnknown)
-            .flat_map(|lib| {
-                assert!(lib.foreign_items.iter().all(|def_id| def_id.krate == cnum));
-                lib.foreign_items.into_iter().map(|def_id| def_id.index)
-            })
-            .collect();
-
-        cmeta.dllimport_foreign_items = dllimports;
-
         let cmeta = Lrc::new(cmeta);
         self.cstore.set_crate_data(cnum, cmeta.clone());
         (cnum, cmeta)
@@ -313,7 +296,7 @@ impl<'a> CrateLoader<'a> {
 
                 let mut proc_macro_locator = locator::Context {
                     target: &self.sess.host,
-                    triple: config::host_triple(),
+                    triple: &TargetTriple::from_triple(config::host_triple()),
                     filesearch: self.sess.host_filesearch(path_kind),
                     rejected_via_hash: vec![],
                     rejected_via_triple: vec![],
@@ -357,7 +340,7 @@ impl<'a> CrateLoader<'a> {
         // don't want to match a host crate against an equivalent target one
         // already loaded.
         let root = library.metadata.get_root();
-        if locate_ctxt.triple == self.sess.opts.target_triple {
+        if locate_ctxt.triple == &self.sess.opts.target_triple {
             let mut result = LoadResult::Loaded(library);
             self.cstore.iter_crate_data(|cnum, data| {
                 if data.name() == root.name && root.hash == data.hash() {
@@ -444,8 +427,9 @@ impl<'a> CrateLoader<'a> {
     fn read_extension_crate(&mut self, span: Span, orig_name: Symbol, rename: Symbol)
                             -> ExtensionCrate {
         info!("read extension crate `extern crate {} as {}`", orig_name, rename);
-        let target_triple = &self.sess.opts.target_triple[..];
-        let is_cross = target_triple != config::host_triple();
+        let target_triple = &self.sess.opts.target_triple;
+        let host_triple = TargetTriple::from_triple(config::host_triple());
+        let is_cross = target_triple != &host_triple;
         let mut target_only = false;
         let mut locate_ctxt = locator::Context {
             sess: self.sess,
@@ -455,7 +439,7 @@ impl<'a> CrateLoader<'a> {
             hash: None,
             filesearch: self.sess.host_filesearch(PathKind::Crate),
             target: &self.sess.host,
-            triple: config::host_triple(),
+            triple: &host_triple,
             root: &None,
             rejected_via_hash: vec![],
             rejected_via_triple: vec![],
@@ -802,7 +786,9 @@ impl<'a> CrateLoader<'a> {
     }
 
     fn inject_profiler_runtime(&mut self) {
-        if self.sess.opts.debugging_opts.profile {
+        if self.sess.opts.debugging_opts.profile ||
+            self.sess.opts.debugging_opts.pgo_gen.is_some()
+        {
             info!("loading profiler");
 
             let symbol = Symbol::intern("profiler_builtins");
@@ -1055,12 +1041,14 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
 
     fn process_item(&mut self, item: &ast::Item, definitions: &Definitions) {
         match item.node {
-            ast::ItemKind::ExternCrate(rename) => {
-                debug!("resolving extern crate stmt. ident: {} rename: {:?}", item.ident, rename);
-                let rename = match rename {
-                    Some(rename) => {
-                        validate_crate_name(Some(self.sess), &rename.as_str(), Some(item.span));
-                        rename
+            ast::ItemKind::ExternCrate(orig_name) => {
+                debug!("resolving extern crate stmt. ident: {} orig_name: {:?}",
+                       item.ident, orig_name);
+                let orig_name = match orig_name {
+                    Some(orig_name) => {
+                        validate_crate_name(Some(self.sess), &orig_name.as_str(),
+                                            Some(item.span));
+                        orig_name
                     }
                     None => item.ident.name,
                 };
@@ -1071,7 +1059,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
                 };
 
                 let (cnum, ..) = self.resolve_crate(
-                    &None, item.ident.name, rename, None, item.span, PathKind::Crate, dep_kind,
+                    &None, item.ident.name, orig_name, None, item.span, PathKind::Crate, dep_kind,
                 );
 
                 let def_id = definitions.opt_local_def_id(item.id).unwrap();
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index bd5ad93946e3c..8765d9d8c2bed 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -20,7 +20,7 @@ use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
 use rustc::session::{Session, CrateDisambiguator};
 use rustc_back::PanicStrategy;
 use rustc_data_structures::indexed_vec::IndexVec;
-use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
+use rustc::util::nodemap::{FxHashMap, NodeMap};
 
 use rustc_data_structures::sync::{Lrc, RwLock, Lock};
 use syntax::{ast, attr};
@@ -30,7 +30,7 @@ use syntax_pos;
 
 pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference};
 pub use rustc::middle::cstore::NativeLibraryKind::*;
-pub use rustc::middle::cstore::{CrateSource, LibSource};
+pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule};
 
 pub use cstore_impl::{provide, provide_extern};
 
@@ -84,8 +84,6 @@ pub struct CrateMetadata {
     pub source: CrateSource,
 
     pub proc_macros: Option<Vec<(ast::Name, Lrc<SyntaxExtension>)>>,
-    // Foreign items imported from a dylib (Windows only)
-    pub dllimport_foreign_items: FxHashSet<DefIndex>,
 }
 
 pub struct CStore {
@@ -228,16 +226,6 @@ impl CrateMetadata {
         attr::contains_name(&attrs, "no_builtins")
     }
 
-     pub fn has_copy_closures(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        attr::contains_feature_attr(&attrs, "copy_closures")
-    }
-
-    pub fn has_clone_closures(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        attr::contains_feature_attr(&attrs, "clone_closures")
-    }
-
     pub fn panic_strategy(&self) -> PanicStrategy {
         self.root.panic_strategy.clone()
     }
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 34c93097a51f5..5fd8ebaa9b4a6 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -12,6 +12,7 @@ use cstore;
 use encoder;
 use link_args;
 use native_libs;
+use foreign_modules;
 use schema;
 
 use rustc::ty::maps::QueryConfig;
@@ -197,6 +198,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
         Lrc::new(reachable_non_generics)
     }
     native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) }
+    foreign_modules => { Lrc::new(cdata.get_foreign_modules(tcx.sess)) }
     plugin_registrar_fn => {
         cdata.root.plugin_registrar_fn.map(|index| {
             DefId { krate: def_id.krate, index }
@@ -224,9 +226,6 @@ provide! { <'tcx> tcx, def_id, other, cdata,
         Lrc::new(result)
     }
 
-    is_dllimport_foreign_item => {
-        cdata.is_dllimport_foreign_item(def_id.index)
-    }
     visibility => { cdata.get_visibility(def_id.index) }
     dep_kind => {
         let r = *cdata.dep_kind.lock();
@@ -256,9 +255,6 @@ provide! { <'tcx> tcx, def_id, other, cdata,
 
     used_crate_source => { Lrc::new(cdata.source.clone()) }
 
-    has_copy_closures => { cdata.has_copy_closures(tcx.sess) }
-    has_clone_closures => { cdata.has_clone_closures(tcx.sess) }
-
     exported_symbols => {
         let cnum = cdata.cnum;
         assert!(cnum != LOCAL_CRATE);
@@ -271,6 +267,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
 
         Arc::new(cdata.exported_symbols())
     }
+
+    wasm_custom_sections => { Lrc::new(cdata.wasm_custom_sections()) }
 }
 
 pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
@@ -304,13 +302,28 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
             tcx.native_libraries(id.krate)
                 .iter()
                 .filter(|lib| native_libs::relevant_lib(&tcx.sess, lib))
-                .find(|l| l.foreign_items.contains(&id))
+                .find(|lib| {
+                    let fm_id = match lib.foreign_module {
+                        Some(id) => id,
+                        None => return false,
+                    };
+                    tcx.foreign_modules(id.krate)
+                        .iter()
+                        .find(|m| m.def_id == fm_id)
+                        .expect("failed to find foreign module")
+                        .foreign_items
+                        .contains(&id)
+                })
                 .map(|l| l.kind)
         },
         native_libraries: |tcx, cnum| {
             assert_eq!(cnum, LOCAL_CRATE);
             Lrc::new(native_libs::collect(tcx))
         },
+        foreign_modules: |tcx, cnum| {
+            assert_eq!(cnum, LOCAL_CRATE);
+            Lrc::new(foreign_modules::collect(tcx))
+        },
         link_args: |tcx, cnum| {
             assert_eq!(cnum, LOCAL_CRATE);
             Lrc::new(link_args::collect(tcx))
@@ -533,7 +546,7 @@ impl CrateStore for cstore::CStore {
                 tokens: body.into(),
                 legacy: def.legacy,
             }),
-            vis: codemap::respan(local_span.empty(), ast::VisibilityKind::Inherited),
+            vis: codemap::respan(local_span.shrink_to_lo(), ast::VisibilityKind::Inherited),
             tokens: None,
         })
     }
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index d83d6f26393d1..e938d5c1a97fe 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -10,11 +10,12 @@
 
 // Decoding metadata from a single crate's metadata
 
-use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary};
+use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule};
 use schema::*;
 
 use rustc_data_structures::sync::{Lrc, ReadGuard};
-use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
+use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash,
+                      DisambiguatedDefPathData};
 use rustc::hir;
 use rustc::middle::cstore::{LinkagePreference, ExternConstBody,
                             ExternBodyNestedBodies};
@@ -29,6 +30,7 @@ use rustc::session::Session;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::codec::TyDecoder;
 use rustc::mir::Mir;
+use rustc::util::captures::Captures;
 use rustc::util::nodemap::FxHashMap;
 
 use std::collections::BTreeMap;
@@ -57,6 +59,9 @@ pub struct DecodeContext<'a, 'tcx: 'a> {
 
     // interpreter allocation cache
     interpret_alloc_cache: FxHashMap<usize, interpret::AllocId>,
+    // a cache for sizes of interpreter allocations
+    // needed to skip already deserialized allocations
+    interpret_alloc_size: FxHashMap<usize, usize>,
 }
 
 /// Abstract over the various ways one can create metadata decoders.
@@ -76,6 +81,7 @@ pub trait Metadata<'a, 'tcx>: Copy {
             last_filemap_index: 0,
             lazy_state: LazyState::NoNode,
             interpret_alloc_cache: FxHashMap::default(),
+            interpret_alloc_size: FxHashMap::default(),
         }
     }
 }
@@ -142,7 +148,10 @@ impl<'a, 'tcx: 'a, T: Decodable> Lazy<T> {
 }
 
 impl<'a, 'tcx: 'a, T: Decodable> LazySeq<T> {
-    pub fn decode<M: Metadata<'a, 'tcx>>(self, meta: M) -> impl Iterator<Item = T> + 'a {
+    pub fn decode<M: Metadata<'a, 'tcx>>(
+        self,
+        meta: M,
+    ) -> impl Iterator<Item = T> + Captures<'tcx> + 'a {
         let mut dcx = meta.decoder(self.position);
         dcx.lazy_state = LazyState::NodeStart(self.position);
         (0..self.len).map(move |_| T::decode(&mut dcx).unwrap())
@@ -281,46 +290,34 @@ impl<'a, 'tcx> SpecializedDecoder<LocalDefId> for DecodeContext<'a, 'tcx> {
 
 impl<'a, 'tcx> SpecializedDecoder<interpret::AllocId> for DecodeContext<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<interpret::AllocId, Self::Error> {
-        const MAX1: usize = usize::max_value() - 1;
-        let tcx = self.tcx.unwrap();
+        let tcx = self.tcx.expect("need tcx for AllocId decoding");
         let pos = self.position();
-        match usize::decode(self)? {
-            ::std::usize::MAX => {
-                let alloc_id = tcx.interpret_interner.reserve();
-                trace!("creating alloc id {:?} at {}", alloc_id, pos);
-                // insert early to allow recursive allocs
-                self.interpret_alloc_cache.insert(pos, alloc_id);
-
-                let allocation = interpret::Allocation::decode(self)?;
-                trace!("decoded alloc {:?} {:#?}", alloc_id, allocation);
-                let allocation = self.tcx.unwrap().intern_const_alloc(allocation);
-                tcx.interpret_interner.intern_at_reserved(alloc_id, allocation);
-
-                if let Some(glob) = Option::<DefId>::decode(self)? {
-                    tcx.interpret_interner.cache(glob, alloc_id);
-                }
-
-                Ok(alloc_id)
-            },
-            MAX1 => {
-                trace!("creating fn alloc id at {}", pos);
-                let instance = ty::Instance::decode(self)?;
-                trace!("decoded fn alloc instance: {:?}", instance);
-                let id = tcx.interpret_interner.create_fn_alloc(instance);
-                trace!("created fn alloc id: {:?}", id);
-                self.interpret_alloc_cache.insert(pos, id);
-                Ok(id)
-            },
-            shorthand => {
-                trace!("loading shorthand {}", shorthand);
-                if let Some(&alloc_id) = self.interpret_alloc_cache.get(&shorthand) {
-                    return Ok(alloc_id);
-                }
-                trace!("shorthand {} not cached, loading entire allocation", shorthand);
-                // need to load allocation
-                self.with_position(shorthand, |this| interpret::AllocId::decode(this))
-            },
+        if let Some(cached) = self.interpret_alloc_cache.get(&pos).cloned() {
+            // if there's no end position we are currently deserializing a recursive
+            // allocation
+            if let Some(end) = self.interpret_alloc_size.get(&pos).cloned() {
+                trace!("{} already cached as {:?}", pos, cached);
+                // skip ahead
+                self.opaque.set_position(end);
+                return Ok(cached)
+            }
         }
+        let id = interpret::specialized_decode_alloc_id(
+            self,
+            tcx,
+            pos,
+            |this, pos, alloc_id| { this.interpret_alloc_cache.insert(pos, alloc_id); },
+            |this, shorthand| {
+                // need to load allocation
+                this.with_position(shorthand, |this| interpret::AllocId::decode(this))
+            }
+        )?;
+        let end_pos = self.position();
+        assert!(self
+            .interpret_alloc_size
+            .insert(pos, end_pos)
+            .is_none());
+        Ok(id)
     }
 }
 
@@ -1035,6 +1032,10 @@ impl<'a, 'tcx> CrateMetadata {
         self.root.native_libraries.decode((self, sess)).collect()
     }
 
+    pub fn get_foreign_modules(&self, sess: &Session) -> Vec<ForeignModule> {
+        self.root.foreign_modules.decode((self, sess)).collect()
+    }
+
     pub fn get_dylib_dependency_formats(&self) -> Vec<(CrateNum, LinkagePreference)> {
         self.root
             .dylib_dependency_formats
@@ -1071,6 +1072,16 @@ impl<'a, 'tcx> CrateMetadata {
             .collect()
     }
 
+    pub fn wasm_custom_sections(&self) -> Vec<DefId> {
+        let sections = self.root
+            .wasm_custom_sections
+            .decode(self)
+            .map(|def_index| self.local_def_id(def_index))
+            .collect::<Vec<_>>();
+        info!("loaded wasm sections {:?}", sections);
+        return sections
+    }
+
     pub fn get_macro(&self, id: DefIndex) -> (InternedString, MacroDef) {
         let entry = self.entry(id);
         match entry.kind {
@@ -1097,10 +1108,6 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    pub fn is_dllimport_foreign_item(&self, id: DefIndex) -> bool {
-        self.dllimport_foreign_items.contains(&id)
-    }
-
     pub fn fn_sig(&self,
                   id: DefIndex,
                   tcx: TyCtxt<'a, 'tcx, 'tcx>)
@@ -1119,7 +1126,23 @@ impl<'a, 'tcx> CrateMetadata {
 
     #[inline]
     pub fn def_key(&self, index: DefIndex) -> DefKey {
-        self.def_path_table.def_key(index)
+        if !self.is_proc_macro(index) {
+            self.def_path_table.def_key(index)
+        } else {
+            // FIXME(#49271) - It would be better if the DefIds were consistent
+            //                 with the DefPathTable, but for proc-macro crates
+            //                 they aren't.
+            let name = self.proc_macros
+                           .as_ref()
+                           .unwrap()[index.to_proc_macro_index()].0;
+            DefKey {
+                parent: Some(CRATE_DEF_INDEX),
+                disambiguated_data: DisambiguatedDefPathData {
+                    data: DefPathData::MacroDef(name.as_str()),
+                    disambiguator: 0,
+                }
+            }
+        }
     }
 
     // Returns the path leading to the thing with this `id`.
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index d959482417489..39de1ec852ec4 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -14,7 +14,7 @@ use isolated_encoder::IsolatedEncoder;
 use schema::*;
 
 use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
-                            EncodedMetadata};
+                            EncodedMetadata, ForeignModule};
 use rustc::hir::def::CtorKind;
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, LOCAL_CRATE};
 use rustc::hir::map::definitions::DefPathTable;
@@ -196,30 +196,26 @@ impl<'a, 'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'a, 'tcx> {
 
 impl<'a, 'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'a, 'tcx> {
     fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
-        trace!("encoding {:?} at {}", alloc_id, self.position());
-        if let Some(shorthand) = self.interpret_alloc_shorthands.get(alloc_id).cloned() {
-            trace!("encoding {:?} as shorthand to {}", alloc_id, shorthand);
-            return shorthand.encode(self);
-        }
-        let start = self.position();
-        // cache the allocation shorthand now, because the allocation itself might recursively
-        // point to itself.
-        self.interpret_alloc_shorthands.insert(*alloc_id, start);
-        if let Some(alloc) = self.tcx.interpret_interner.get_alloc(*alloc_id) {
-            trace!("encoding {:?} with {:#?}", alloc_id, alloc);
-            usize::max_value().encode(self)?;
-            alloc.encode(self)?;
-            self.tcx.interpret_interner
-                .get_corresponding_static_def_id(*alloc_id)
-                .encode(self)?;
-        } else if let Some(fn_instance) = self.tcx.interpret_interner.get_fn(*alloc_id) {
-            trace!("encoding {:?} with {:#?}", alloc_id, fn_instance);
-            (usize::max_value() - 1).encode(self)?;
-            fn_instance.encode(self)?;
-        } else {
-            bug!("alloc id without corresponding allocation: {}", alloc_id);
-        }
-        Ok(())
+        use std::collections::hash_map::Entry;
+        let tcx = self.tcx;
+        let pos = self.position();
+        let shorthand = match self.interpret_alloc_shorthands.entry(*alloc_id) {
+            Entry::Occupied(entry) => Some(entry.get().clone()),
+            Entry::Vacant(entry) => {
+                // ensure that we don't place any AllocIds at the very beginning
+                // of the metadata file, because that would end up making our indices
+                // not special. This is essentially impossible, but let's make sure
+                assert!(pos >= interpret::SHORTHAND_START);
+                entry.insert(pos);
+                None
+            },
+        };
+        interpret::specialized_encode_alloc_id(
+            self,
+            tcx,
+            *alloc_id,
+            shorthand,
+        )
     }
 }
 
@@ -416,6 +412,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             ());
         let native_lib_bytes = self.position() - i;
 
+        let foreign_modules = self.tracked(
+            IsolatedEncoder::encode_foreign_modules,
+            ());
+
         // Encode codemap
         i = self.position();
         let codemap = self.encode_codemap();
@@ -439,6 +439,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             &exported_symbols);
         let exported_symbols_bytes = self.position() - i;
 
+        // encode wasm custom sections
+        let wasm_custom_sections = self.tcx.wasm_custom_sections(LOCAL_CRATE);
+        let wasm_custom_sections = self.tracked(
+            IsolatedEncoder::encode_wasm_custom_sections,
+            &wasm_custom_sections);
+
         // Encode and index the items.
         i = self.position();
         let items = self.encode_info_for_items();
@@ -478,10 +484,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             lang_items,
             lang_items_missing,
             native_libraries,
+            foreign_modules,
             codemap,
             def_path_table,
             impls,
             exported_symbols,
+            wasm_custom_sections,
             index,
         });
 
@@ -1334,6 +1342,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
         self.lazy_seq(used_libraries.iter().cloned())
     }
 
+    fn encode_foreign_modules(&mut self, _: ()) -> LazySeq<ForeignModule> {
+        let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE);
+        self.lazy_seq(foreign_modules.iter().cloned())
+    }
+
     fn encode_crate_deps(&mut self, _: ()) -> LazySeq<CrateDep> {
         let crates = self.tcx.crates();
 
@@ -1448,6 +1461,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             .cloned())
     }
 
+    fn encode_wasm_custom_sections(&mut self, statics: &[DefId]) -> LazySeq<DefIndex> {
+        info!("encoding custom wasm section constants {:?}", statics);
+        self.lazy_seq(statics.iter().map(|id| id.index))
+    }
+
     fn encode_dylib_dependency_formats(&mut self, _: ()) -> LazySeq<Option<LinkagePreference>> {
         match self.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) {
             Some(arr) => {
diff --git a/src/librustc_metadata/foreign_modules.rs b/src/librustc_metadata/foreign_modules.rs
new file mode 100644
index 0000000000000..c44d891b7f39a
--- /dev/null
+++ b/src/librustc_metadata/foreign_modules.rs
@@ -0,0 +1,48 @@
+// Copyright 2017 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 rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::hir;
+use rustc::middle::cstore::ForeignModule;
+use rustc::ty::TyCtxt;
+
+pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<ForeignModule> {
+    let mut collector = Collector {
+        tcx,
+        modules: Vec::new(),
+    };
+    tcx.hir.krate().visit_all_item_likes(&mut collector);
+    return collector.modules
+}
+
+struct Collector<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    modules: Vec<ForeignModule>,
+}
+
+impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> {
+    fn visit_item(&mut self, it: &'tcx hir::Item) {
+        let fm = match it.node {
+            hir::ItemForeignMod(ref fm) => fm,
+            _ => return,
+        };
+
+        let foreign_items = fm.items.iter()
+            .map(|it| self.tcx.hir.local_def_id(it.id))
+            .collect();
+        self.modules.push(ForeignModule {
+            foreign_items,
+            def_id: self.tcx.hir.local_def_id(it.id),
+        });
+    }
+
+    fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem) {}
+    fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem) {}
+}
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index f77c22bd89544..4af5ec9ae08ea 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -14,9 +14,9 @@
 #![deny(warnings)]
 
 #![feature(box_patterns)]
-#![feature(conservative_impl_trait)]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
 #![feature(fs_read_write)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(libc)]
 #![feature(macro_lifetime_matcher)]
 #![feature(proc_macro_internals)]
@@ -56,6 +56,7 @@ mod isolated_encoder;
 mod schema;
 mod native_libs;
 mod link_args;
+mod foreign_modules;
 
 pub mod creader;
 pub mod cstore;
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index c56674bd6c5a9..41e10b4755d01 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -233,7 +233,7 @@ use rustc::util::nodemap::FxHashMap;
 use errors::DiagnosticBuilder;
 use syntax::symbol::Symbol;
 use syntax_pos::Span;
-use rustc_back::target::Target;
+use rustc_back::target::{Target, TargetTriple};
 
 use std::cmp;
 use std::fmt;
@@ -258,7 +258,7 @@ pub struct Context<'a> {
     pub hash: Option<&'a Svh>,
     // points to either self.sess.target.target or self.sess.host, must match triple
     pub target: &'a Target,
-    pub triple: &'a str,
+    pub triple: &'a TargetTriple,
     pub filesearch: FileSearch<'a>,
     pub root: &'a Option<CratePaths>,
     pub rejected_via_hash: Vec<CrateMismatch>,
@@ -394,7 +394,7 @@ impl<'a> Context<'a> {
                                            add);
 
             if (self.ident == "std" || self.ident == "core")
-                && self.triple != config::host_triple() {
+                && self.triple != &TargetTriple::from_triple(config::host_triple()) {
                 err.note(&format!("the `{}` target may not be installed", self.triple));
             }
             err.span_label(self.span, "can't find crate");
@@ -698,13 +698,13 @@ impl<'a> Context<'a> {
             }
         }
 
-        if root.triple != self.triple {
+        if &root.triple != self.triple {
             info!("Rejecting via crate triple: expected {} got {}",
                   self.triple,
                   root.triple);
             self.rejected_via_triple.push(CrateMismatch {
                 path: libpath.to_path_buf(),
-                got: root.triple,
+                got: format!("{}", root.triple),
             });
             return None;
         }
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index 2504f8dc251f9..4bb6d8fb87cf5 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -105,14 +105,11 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> {
             } else {
                 None
             };
-            let foreign_items = fm.items.iter()
-                .map(|it| self.tcx.hir.local_def_id(it.id))
-                .collect();
             let lib = NativeLibrary {
                 name: n,
                 kind,
                 cfg,
-                foreign_items,
+                foreign_module: Some(self.tcx.hir.local_def_id(it.id)),
             };
             self.register_native_lib(Some(m.span), lib);
         }
@@ -218,7 +215,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> {
                     name: Symbol::intern(new_name.unwrap_or(name)),
                     kind: if let Some(k) = kind { k } else { cstore::NativeUnknown },
                     cfg: None,
-                    foreign_items: Vec::new(),
+                    foreign_module: None,
                 };
                 self.register_native_lib(None, lib);
             }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 593f08e90bb3b..d04a4001c5023 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -15,13 +15,14 @@ use rustc::hir;
 use rustc::hir::def::{self, CtorKind};
 use rustc::hir::def_id::{DefIndex, DefId, CrateNum};
 use rustc::ich::StableHashingContext;
-use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary};
 use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
+use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary, ForeignModule};
 use rustc::middle::lang_items;
 use rustc::mir;
 use rustc::session::CrateDisambiguator;
 use rustc::ty::{self, Ty, ReprOptions};
 use rustc_back::PanicStrategy;
+use rustc_back::target::TargetTriple;
 
 use rustc_serialize as serialize;
 use syntax::{ast, attr};
@@ -186,7 +187,7 @@ pub enum LazyState {
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct CrateRoot {
     pub name: Symbol,
-    pub triple: String,
+    pub triple: TargetTriple,
     pub hash: hir::svh::Svh,
     pub disambiguator: CrateDisambiguator,
     pub panic_strategy: PanicStrategy,
@@ -200,10 +201,12 @@ pub struct CrateRoot {
     pub lang_items: LazySeq<(DefIndex, usize)>,
     pub lang_items_missing: LazySeq<lang_items::LangItem>,
     pub native_libraries: LazySeq<NativeLibrary>,
+    pub foreign_modules: LazySeq<ForeignModule>,
     pub codemap: LazySeq<syntax_pos::FileMap>,
     pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
     pub impls: LazySeq<TraitImpls>,
     pub exported_symbols: LazySeq<(ExportedSymbol, SymbolExportLevel)>,
+    pub wasm_custom_sections: LazySeq<DefIndex>,
 
     pub index: LazySeq<index::Index>,
 }
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 6e1a798910dc6..305df37466d02 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -392,11 +392,13 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
                 // ignored when consuming results (update to
                 // flow_state already handled).
             }
-            StatementKind::Nop | StatementKind::Validate(..) | StatementKind::StorageLive(..) => {
-                // `Nop`, `Validate`, and `StorageLive` are irrelevant
+            StatementKind::Nop |
+            StatementKind::UserAssertTy(..) |
+            StatementKind::Validate(..) |
+            StatementKind::StorageLive(..) => {
+                // `Nop`, `UserAssertTy`, `Validate`, and `StorageLive` are irrelevant
                 // to borrow check.
             }
-
             StatementKind::StorageDead(local) => {
                 self.access_place(
                     ContextKind::StorageDead.new(location),
diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
index 3a39eb5c908de..afaedecdf0abe 100644
--- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs
+++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
@@ -12,10 +12,10 @@ use rustc::hir;
 use rustc::mir::{BasicBlock, BasicBlockData, Location, Place, Mir, Rvalue};
 use rustc::mir::visit::Visitor;
 use rustc::mir::Place::Projection;
-use rustc::mir::{PlaceProjection, ProjectionElem};
+use rustc::mir::{Local, PlaceProjection, ProjectionElem};
 use rustc::mir::visit::TyContext;
 use rustc::infer::InferCtxt;
-use rustc::ty::{self, ClosureSubsts};
+use rustc::ty::{self, CanonicalTy, ClosureSubsts};
 use rustc::ty::subst::Substs;
 use rustc::ty::fold::TypeFoldable;
 
@@ -106,6 +106,9 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
 
         self.super_rvalue(rvalue, location);
     }
+
+    fn visit_user_assert_ty(&mut self, _c_ty: &CanonicalTy<'tcx>,
+                            _local: &Local, _location: Location) { }
 }
 
 impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> {
diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs
index c54acda8a6252..04c206b5c0c40 100644
--- a/src/librustc_mir/borrow_check/nll/renumber.rs
+++ b/src/librustc_mir/borrow_check/nll/renumber.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 use rustc::ty::subst::Substs;
-use rustc::ty::{self, ClosureSubsts, GeneratorInterior, Ty, TypeFoldable};
-use rustc::mir::{BasicBlock, Location, Mir, Statement, StatementKind};
+use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorInterior, Ty, TypeFoldable};
+use rustc::mir::{BasicBlock, Local, Location, Mir, Statement, StatementKind};
 use rustc::mir::visit::{MutVisitor, TyContext};
 use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
 
@@ -118,6 +118,14 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
         debug!("visit_closure_substs: substs={:?}", substs);
     }
 
+    fn visit_user_assert_ty(&mut self, _c_ty: &mut CanonicalTy<'tcx>, _local: &mut Local,
+                            _location: Location) {
+        // User-assert-ty statements represent types that the user added explicitly.
+        // We don't want to erase the regions from these types: rather, we want to
+        // add them as constraints at type-check time.
+        debug!("visit_user_assert_ty: skipping renumber");
+    }
+
     fn visit_statement(
         &mut self,
         block: BasicBlock,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 022831b5a9259..544cb5eefc886 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -20,7 +20,7 @@ use dataflow::move_paths::MoveData;
 use rustc::hir::def_id::DefId;
 use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult};
 use rustc::infer::region_constraints::{GenericKind, RegionConstraintData};
-use rustc::traits::{self, Normalized, FulfillmentContext};
+use rustc::traits::{self, Normalized, TraitEngine};
 use rustc::traits::query::NoSolution;
 use rustc::ty::error::TypeError;
 use rustc::ty::fold::TypeFoldable;
@@ -662,7 +662,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
     where
         OP: FnOnce(&mut Self) -> InferResult<'tcx, R>,
     {
-        let mut fulfill_cx = FulfillmentContext::new();
+        let mut fulfill_cx = TraitEngine::new(self.infcx.tcx);
         let InferOk { value, obligations } = self.infcx.commit_if_ok(|_| op(self))?;
         fulfill_cx.register_predicate_obligations(self.infcx, obligations);
         if let Err(e) = fulfill_cx.select_all_or_error(self.infcx) {
@@ -761,6 +761,22 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                     );
                 };
             }
+            StatementKind::UserAssertTy(ref c_ty, ref local) => {
+                let local_ty = mir.local_decls()[*local].ty;
+                let (ty, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(
+                    stmt.source_info.span, c_ty);
+                debug!("check_stmt: user_assert_ty ty={:?} local_ty={:?}", ty, local_ty);
+                if let Err(terr) = self.eq_types(ty, local_ty, location.at_self()) {
+                    span_mirbug!(
+                        self,
+                        stmt,
+                        "bad type assert ({:?} = {:?}): {:?}",
+                        ty,
+                        local_ty,
+                        terr
+                    );
+                }
+            }
             StatementKind::StorageLive(_)
             | StatementKind::StorageDead(_)
             | StatementKind::InlineAsm { .. }
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index afd338581392d..39dc29ba18b64 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -777,6 +777,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'gcx, 'tcx> {
     where
         T: TypeFoldable<'tcx>,
     {
+        debug!(
+            "replace_bound_regions_with_nll_infer_vars(value={:?}, all_outlive_scope={:?})",
+            value,
+            all_outlive_scope,
+        );
         let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| {
             let liberated_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
                 scope: all_outlive_scope,
@@ -784,6 +789,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'gcx, 'tcx> {
             }));
             let region_vid = self.next_nll_region_var(origin);
             indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid());
+            debug!("liberated_region={:?} => {:?}", liberated_region, region_vid);
             region_vid
         });
         value
diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs
index ef30b1e452230..94702927d2600 100644
--- a/src/librustc_mir/build/block.rs
+++ b/src/librustc_mir/build/block.rs
@@ -102,6 +102,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                     remainder_scope,
                     init_scope,
                     pattern,
+                    ty,
                     initializer,
                     lint_level
                 } => {
@@ -117,14 +118,22 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                     // Evaluate the initializer, if present.
                     if let Some(init) = initializer {
                         unpack!(block = this.in_opt_scope(
-                            opt_destruction_scope.map(|de|(de, source_info)), block, move |this| {
+                            opt_destruction_scope.map(|de|(de, source_info)), block, |this| {
                                 let scope = (init_scope, source_info);
-                                this.in_scope(scope, lint_level, block, move |this| {
-                                    // FIXME #30046                             ^~~~
-                                    this.expr_into_pattern(block, pattern, init)
+                                this.in_scope(scope, lint_level, block, |this| {
+                                    this.expr_into_pattern(block, ty, pattern, init)
                                 })
                             }));
                     } else {
+                        // FIXME(#47184): We currently only insert `UserAssertTy` statements for
+                        // patterns that are bindings, this is as we do not want to deconstruct
+                        // the type being assertion to match the pattern.
+                        if let PatternKind::Binding { var, .. } = *pattern.kind {
+                            if let Some(ty) = ty {
+                                this.user_assert_ty(block, ty, var, span);
+                            }
+                        }
+
                         this.visit_bindings(&pattern, &mut |this, _, _, node, span, _| {
                             this.storage_live_binding(block, node, span);
                             this.schedule_drop_for_binding(node, span);
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 229e33dcd7862..7eb52a3cdee93 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -145,8 +145,26 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         end_block.unit()
     }
 
+    pub fn user_assert_ty(&mut self, block: BasicBlock, hir_id: hir::HirId,
+                          var: NodeId, span: Span) {
+        if self.hir.tcx().sess.opts.debugging_opts.disable_nll_user_type_assert { return; }
+
+        let local_id = self.var_indices[&var];
+        let source_info = self.source_info(span);
+
+        debug!("user_assert_ty: local_id={:?}", hir_id.local_id);
+        if let Some(c_ty) = self.hir.tables.user_provided_tys().get(hir_id) {
+            debug!("user_assert_ty: c_ty={:?}", c_ty);
+            self.cfg.push(block, Statement {
+                source_info,
+                kind: StatementKind::UserAssertTy(*c_ty, local_id),
+            });
+        }
+    }
+
     pub fn expr_into_pattern(&mut self,
                              mut block: BasicBlock,
+                             ty: Option<hir::HirId>,
                              irrefutable_pat: Pattern<'tcx>,
                              initializer: ExprRef<'tcx>)
                              -> BlockAnd<()> {
@@ -156,6 +174,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                                    var,
                                    subpattern: None, .. } => {
                 let place = self.storage_live_binding(block, var, irrefutable_pat.span);
+
+                if let Some(ty) = ty {
+                    self.user_assert_ty(block, ty, var, irrefutable_pat.span);
+                }
+
                 unpack!(block = self.into(&place, block, initializer));
                 self.schedule_drop_for_binding(var, irrefutable_pat.span);
                 block.unit()
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 23c5499bb6396..8494c043f90fc 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -422,7 +422,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
             builder.args_and_body(block, &arguments, arg_scope, &body.value)
         }));
         // Attribute epilogue to function's closing brace
-        let fn_end = span.with_lo(span.hi());
+        let fn_end = span.shrink_to_hi();
         let source_info = builder.source_info(fn_end);
         let return_block = builder.return_block();
         builder.cfg.terminate(block, source_info,
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index 499ed55fad41f..fb3042014df6a 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -678,6 +678,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
             mir::StatementKind::SetDiscriminant { .. } |
             mir::StatementKind::StorageLive(..) |
             mir::StatementKind::Validate(..) |
+            mir::StatementKind::UserAssertTy(..) |
             mir::StatementKind::Nop => {}
 
         }
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index d6f419f6cfb41..cbf4c822769c6 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -298,6 +298,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
             }
             StatementKind::EndRegion(_) |
             StatementKind::Validate(..) |
+            StatementKind::UserAssertTy(..) |
             StatementKind::Nop => {}
         }
     }
diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs
index 2000ebea25d7e..4f36c3888b961 100644
--- a/src/librustc_mir/diagnostics.rs
+++ b/src/librustc_mir/diagnostics.rs
@@ -2247,7 +2247,7 @@ let mut b = || {
     yield (); // ...is still in scope here, when the yield occurs.
     println!("{}", a);
 };
-b.resume();
+unsafe { b.resume() };
 ```
 
 At present, it is not permitted to have a yield that occurs while a
@@ -2265,7 +2265,7 @@ let mut b = || {
     yield ();
     println!("{}", a);
 };
-b.resume();
+unsafe { b.resume() };
 ```
 
 This is a very simple case, of course. In more complex cases, we may
@@ -2283,7 +2283,7 @@ let mut b = || {
     yield x; // ...when this yield occurs.
   }
 };
-b.resume();
+unsafe { b.resume() };
 ```
 
 Such cases can sometimes be resolved by iterating "by value" (or using
@@ -2298,7 +2298,7 @@ let mut b = || {
     yield x; // <-- Now yield is OK.
   }
 };
-b.resume();
+unsafe { b.resume() };
 ```
 
 If taking ownership is not an option, using indices can work too:
@@ -2314,7 +2314,7 @@ let mut b = || {
     yield x; // <-- Now yield is OK.
   }
 };
-b.resume();
+unsafe { b.resume() };
 
 // (*) -- Unfortunately, these temporaries are currently required.
 // See <https://github.com/rust-lang/rust/issues/43122>.
diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs
index 6f6258f52f794..14aa307f0ae1f 100644
--- a/src/librustc_mir/hair/cx/block.rs
+++ b/src/librustc_mir/hair/cx/block.rs
@@ -76,12 +76,14 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                             first_statement_index: region::FirstStatementIndex::new(index),
                         });
 
+                        let ty = local.ty.clone().map(|ty| ty.hir_id);
                         let pattern = cx.pattern_from_hir(&local.pat);
                         result.push(StmtRef::Mirror(Box::new(Stmt {
                             kind: StmtKind::Let {
                                 remainder_scope: remainder_scope,
                                 init_scope: region::Scope::Node(hir_id.local_id),
                                 pattern,
+                                ty,
                                 initializer: local.init.to_ref(),
                                 lint_level: cx.lint_level_of(local.id),
                             },
diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs
index 5f60a134fb130..fe82b8158f76d 100644
--- a/src/librustc_mir/hair/mod.rs
+++ b/src/librustc_mir/hair/mod.rs
@@ -93,10 +93,13 @@ pub enum StmtKind<'tcx> {
         /// lifetime of temporaries
         init_scope: region::Scope,
 
-        /// let <PAT> = ...
+        /// let <PAT>: ty = ...
         pattern: Pattern<'tcx>,
 
-        /// let pat = <INIT> ...
+        /// let pat: <TY> = init ...
+        ty: Option<hir::HirId>,
+
+        /// let pat: ty = <INIT> ...
         initializer: Option<ExprRef<'tcx>>,
 
         /// the lint level for this let-statement
diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs
index 82eb28287b033..87219511e6ff3 100644
--- a/src/librustc_mir/interpret/const_eval.rs
+++ b/src/librustc_mir/interpret/const_eval.rs
@@ -14,7 +14,7 @@ use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory};
 
 use std::fmt;
 use std::error::Error;
-use std::rc::Rc;
+use rustc_data_structures::sync::Lrc;
 
 pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -339,6 +339,14 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator {
         ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
         cid: GlobalId<'tcx>,
     ) -> EvalResult<'tcx, AllocId> {
+        let alloc = ecx
+                    .tcx
+                    .interpret_interner
+                    .get_cached(cid.instance.def_id());
+        // Don't evaluate when already cached to prevent cycles
+        if let Some(alloc) = alloc {
+            return Ok(alloc)
+        }
         // ensure the static is computed
         ecx.const_eval(cid)?;
         Ok(ecx
@@ -477,7 +485,7 @@ pub fn const_eval_provider<'a, 'tcx>(
         // Do match-check before building MIR
         if tcx.check_match(def_id).is_err() {
             return Err(ConstEvalErr {
-                kind: Rc::new(CheckMatchError),
+                kind: Lrc::new(CheckMatchError),
                 span,
             });
         }
@@ -489,7 +497,7 @@ pub fn const_eval_provider<'a, 'tcx>(
         // Do not continue into miri if typeck errors occurred; it will fail horribly
         if tables.tainted_by_errors {
             return Err(ConstEvalErr {
-                kind: Rc::new(TypeckError),
+                kind: Lrc::new(TypeckError),
                 span,
             });
         }
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index c236ce2abc5f0..b8bfcd756cd23 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -1,7 +1,7 @@
-use std::collections::HashSet;
 use std::fmt::Write;
 
 use rustc::hir::def_id::DefId;
+use rustc::hir::def::Def;
 use rustc::hir::map::definitions::DefPathData;
 use rustc::middle::const_val::{ConstVal, ErrKind};
 use rustc::mir;
@@ -9,7 +9,7 @@ use rustc::ty::layout::{self, Size, Align, HasDataLayout, LayoutOf, TyLayout};
 use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::maps::TyCtxtAt;
-use rustc_data_structures::indexed_vec::Idx;
+use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc::middle::const_val::FrameInfo;
 use syntax::codemap::{self, Span};
 use syntax::ast::Mutability;
@@ -17,6 +17,7 @@ use rustc::mir::interpret::{
     GlobalId, Value, Pointer, PrimVal, PrimValKind,
     EvalError, EvalResult, EvalErrorKind, MemoryPointer,
 };
+use std::mem;
 
 use super::{Place, PlaceExtra, Memory,
             HasMemory, MemoryKind,
@@ -71,12 +72,12 @@ pub struct Frame<'mir, 'tcx: 'mir> {
     pub return_place: Place,
 
     /// The list of locals for this stack frame, stored in order as
-    /// `[arguments..., variables..., temporaries...]`. The locals are stored as `Option<Value>`s.
+    /// `[return_ptr, arguments..., variables..., temporaries...]`. The locals are stored as `Option<Value>`s.
     /// `None` represents a local that is currently dead, while a live local
     /// can either directly contain `PrimVal` or refer to some part of an `Allocation`.
     ///
     /// Before being initialized, arguments are `Value::ByVal(PrimVal::Undef)` and other locals are `None`.
-    pub locals: Vec<Option<Value>>,
+    pub locals: IndexVec<mir::Local, Option<Value>>,
 
     ////////////////////////////////////////////////////////////////////////////////
     // Current position within the function
@@ -383,39 +384,29 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
     ) -> EvalResult<'tcx> {
         ::log_settings::settings().indentation += 1;
 
-        /// Return the set of locals that have a storage annotation anywhere
-        fn collect_storage_annotations<'mir, 'tcx>(mir: &'mir mir::Mir<'tcx>) -> HashSet<mir::Local> {
-            use rustc::mir::StatementKind::*;
-
-            let mut set = HashSet::new();
-            for block in mir.basic_blocks() {
-                for stmt in block.statements.iter() {
-                    match stmt.kind {
-                        StorageLive(local) |
-                        StorageDead(local) => {
-                            set.insert(local);
+        let locals = if mir.local_decls.len() > 1 {
+            let mut locals = IndexVec::from_elem(Some(Value::ByVal(PrimVal::Undef)), &mir.local_decls);
+            match self.tcx.describe_def(instance.def_id()) {
+                // statics and constants don't have `Storage*` statements, no need to look for them
+                Some(Def::Static(..)) | Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {},
+                _ => {
+                    trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len());
+                    for block in mir.basic_blocks() {
+                        for stmt in block.statements.iter() {
+                            use rustc::mir::StatementKind::{StorageDead, StorageLive};
+                            match stmt.kind {
+                                StorageLive(local) |
+                                StorageDead(local) => locals[local] = None,
+                                _ => {}
+                            }
                         }
-                        _ => {}
                     }
-                }
-            }
-            set
-        }
-
-        // Subtract 1 because `local_decls` includes the ReturnMemoryPointer, but we don't store a local
-        // `Value` for that.
-        let num_locals = mir.local_decls.len() - 1;
-
-        let locals = {
-            let annotated_locals = collect_storage_annotations(mir);
-            let mut locals = vec![None; num_locals];
-            for i in 0..num_locals {
-                let local = mir::Local::new(i + 1);
-                if !annotated_locals.contains(&local) {
-                    locals[i] = Some(Value::ByVal(PrimVal::Undef));
-                }
+                },
             }
             locals
+        } else {
+            // don't allocate at all for trivial constants
+            IndexVec::new()
         };
 
         self.stack.push(Frame {
@@ -973,8 +964,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
     pub fn force_allocation(&mut self, place: Place) -> EvalResult<'tcx, Place> {
         let new_place = match place {
             Place::Local { frame, local } => {
-                // -1 since we don't store the return value
-                match self.stack[frame].locals[local.index() - 1] {
+                match self.stack[frame].locals[local] {
                     None => return err!(DeadLocal),
                     Some(Value::ByRef(ptr, align)) => {
                         Place::Ptr {
@@ -988,7 +978,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
                         let ty = self.monomorphize(ty, self.stack[frame].instance.substs);
                         let layout = self.layout_of(ty)?;
                         let ptr = self.alloc_ptr(ty)?;
-                        self.stack[frame].locals[local.index() - 1] =
+                        self.stack[frame].locals[local] =
                             Some(Value::ByRef(ptr.into(), layout.align)); // it stays live
                         let place = Place::from_ptr(ptr, layout.align);
                         self.write_value(ValTy { value: val, ty }, place)?;
@@ -1702,13 +1692,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
 
 impl<'mir, 'tcx> Frame<'mir, 'tcx> {
     pub fn get_local(&self, local: mir::Local) -> EvalResult<'tcx, Value> {
-        // Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
-        self.locals[local.index() - 1].ok_or(EvalErrorKind::DeadLocal.into())
+        self.locals[local].ok_or(EvalErrorKind::DeadLocal.into())
     }
 
     fn set_local(&mut self, local: mir::Local, value: Value) -> EvalResult<'tcx> {
-        // Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
-        match self.locals[local.index() - 1] {
+        match self.locals[local] {
             None => err!(DeadLocal),
             Some(ref mut local) => {
                 *local = value;
@@ -1717,20 +1705,17 @@ impl<'mir, 'tcx> Frame<'mir, 'tcx> {
         }
     }
 
-    pub fn storage_live(&mut self, local: mir::Local) -> EvalResult<'tcx, Option<Value>> {
+    pub fn storage_live(&mut self, local: mir::Local) -> Option<Value> {
         trace!("{:?} is now live", local);
 
-        let old = self.locals[local.index() - 1];
-        self.locals[local.index() - 1] = Some(Value::ByVal(PrimVal::Undef)); // StorageLive *always* kills the value that's currently stored
-        return Ok(old);
+        // StorageLive *always* kills the value that's currently stored
+        mem::replace(&mut self.locals[local], Some(Value::ByVal(PrimVal::Undef)))
     }
 
     /// Returns the old value of the local
-    pub fn storage_dead(&mut self, local: mir::Local) -> EvalResult<'tcx, Option<Value>> {
+    pub fn storage_dead(&mut self, local: mir::Local) -> Option<Value> {
         trace!("{:?} is now dead", local);
 
-        let old = self.locals[local.index() - 1];
-        self.locals[local.index() - 1] = None;
-        return Ok(old);
+        self.locals[local].take()
     }
 }
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index b369f80e849b0..4026f52e9620d 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -1,5 +1,5 @@
 use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian, BigEndian};
-use std::collections::{btree_map, BTreeMap, HashMap, HashSet, VecDeque};
+use std::collections::{btree_map, BTreeMap, VecDeque};
 use std::{ptr, io};
 
 use rustc::ty::Instance;
@@ -7,6 +7,7 @@ use rustc::ty::maps::TyCtxtAt;
 use rustc::ty::layout::{self, Align, TargetDataLayout};
 use syntax::ast::Mutability;
 
+use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use rustc::mir::interpret::{MemoryPointer, AllocId, Allocation, AccessKind, UndefMask, Value, Pointer,
                             EvalResult, PrimVal, EvalErrorKind};
 
@@ -33,15 +34,15 @@ pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
     pub data: M::MemoryData,
 
     /// Helps guarantee that stack allocations aren't deallocated via `rust_deallocate`
-    alloc_kind: HashMap<AllocId, MemoryKind<M::MemoryKinds>>,
+    alloc_kind: FxHashMap<AllocId, MemoryKind<M::MemoryKinds>>,
 
     /// Actual memory allocations (arbitrary bytes, may contain pointers into other allocations).
-    alloc_map: HashMap<AllocId, Allocation>,
+    alloc_map: FxHashMap<AllocId, Allocation>,
 
     /// Actual memory allocations (arbitrary bytes, may contain pointers into other allocations).
     ///
     /// Stores statics while they are being processed, before they are interned and thus frozen
-    uninitialized_statics: HashMap<AllocId, Allocation>,
+    uninitialized_statics: FxHashMap<AllocId, Allocation>,
 
     /// The current stack frame.  Used to check accesses against locks.
     pub cur_frame: usize,
@@ -53,9 +54,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
     pub fn new(tcx: TyCtxtAt<'a, 'tcx, 'tcx>, data: M::MemoryData) -> Self {
         Memory {
             data,
-            alloc_kind: HashMap::new(),
-            alloc_map: HashMap::new(),
-            uninitialized_statics: HashMap::new(),
+            alloc_kind: FxHashMap::default(),
+            alloc_map: FxHashMap::default(),
+            uninitialized_statics: FxHashMap::default(),
             tcx,
             cur_frame: usize::max_value(),
         }
@@ -338,7 +339,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
         allocs.sort();
         allocs.dedup();
         let mut allocs_to_print = VecDeque::from(allocs);
-        let mut allocs_seen = HashSet::new();
+        let mut allocs_seen = FxHashSet::default();
 
         while let Some(id) = allocs_to_print.pop_front() {
             let mut msg = format!("Alloc {:<5} ", format!("{}:", id));
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index d27de3ef6bfc4..456f5fd75db09 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -197,29 +197,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
             },
 
             Static(ref static_) => {
-                let alloc = self
-                    .tcx
-                    .interpret_interner
-                    .get_cached(static_.def_id);
                 let layout = self.layout_of(self.place_ty(mir_place))?;
-                if let Some(alloc) = alloc {
-                    Place::Ptr {
-                        ptr: MemoryPointer::new(alloc, 0).into(),
-                        align: layout.align,
-                        extra: PlaceExtra::None,
-                    }
-                } else {
-                    let instance = ty::Instance::mono(*self.tcx, static_.def_id);
-                    let cid = GlobalId {
-                        instance,
-                        promoted: None
-                    };
-                    let alloc = Machine::init_static(self, cid)?;
-                    Place::Ptr {
-                        ptr: MemoryPointer::new(alloc, 0).into(),
-                        align: layout.align,
-                        extra: PlaceExtra::None,
-                    }
+                let instance = ty::Instance::mono(*self.tcx, static_.def_id);
+                let cid = GlobalId {
+                    instance,
+                    promoted: None
+                };
+                let alloc = Machine::init_static(self, cid)?;
+                Place::Ptr {
+                    ptr: MemoryPointer::new(alloc, 0).into(),
+                    align: layout.align,
+                    extra: PlaceExtra::None,
                 }
             }
 
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 4e1750caf26ba..a22572ec687c3 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -69,13 +69,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
 
             // Mark locals as alive
             StorageLive(local) => {
-                let old_val = self.frame_mut().storage_live(local)?;
+                let old_val = self.frame_mut().storage_live(local);
                 self.deallocate_local(old_val)?;
             }
 
             // Mark locals as dead
             StorageDead(local) => {
-                let old_val = self.frame_mut().storage_dead(local)?;
+                let old_val = self.frame_mut().storage_dead(local);
                 self.deallocate_local(old_val)?;
             }
 
@@ -89,6 +89,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                 M::end_region(self, Some(ce))?;
             }
 
+            UserAssertTy(..) => {}
+
             // Defined to do nothing. These are added by optimization passes, to avoid changing the
             // size of MIR constantly.
             Nop => {}
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index ff35412ea5bab..262e5f608ca64 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -21,16 +21,16 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(catch_expr)]
-#![feature(conservative_impl_trait)]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
 #![feature(decl_macro)]
 #![feature(dyn_trait)]
 #![feature(fs_read_write)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![cfg_attr(stage0, feature(inclusive_range_syntax))]
 #![feature(macro_vis_matcher)]
-#![feature(match_default_bindings)]
+#![cfg_attr(stage0, feature(match_default_bindings))]
 #![feature(exhaustive_patterns)]
 #![feature(range_contains)]
 #![feature(rustc_diagnostic_macros)]
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 86d08dec2b9c3..31af7c2185794 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -105,6 +105,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
             StatementKind::StorageDead(..) |
             StatementKind::EndRegion(..) |
             StatementKind::Validate(..) |
+            StatementKind::UserAssertTy(..) |
             StatementKind::Nop => {
                 // safe (at least as emitted during MIR construction)
             }
@@ -125,21 +126,13 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                 &AggregateKind::Array(..) |
                 &AggregateKind::Tuple |
                 &AggregateKind::Adt(..) => {}
-                &AggregateKind::Closure(def_id, _) => {
+                &AggregateKind::Closure(def_id, _) |
+                &AggregateKind::Generator(def_id, _, _) => {
                     let UnsafetyCheckResult {
                         violations, unsafe_blocks
                     } = self.tcx.unsafety_check_result(def_id);
                     self.register_violations(&violations, &unsafe_blocks);
                 }
-                &AggregateKind::Generator(def_id, _, interior) => {
-                    let UnsafetyCheckResult {
-                        violations, unsafe_blocks
-                    } = self.tcx.unsafety_check_result(def_id);
-                    self.register_violations(&violations, &unsafe_blocks);
-                    if !interior.movable {
-                        self.require_unsafe("construction of immovable generator")
-                    }
-                }
             }
         }
         self.super_rvalue(rvalue, location);
diff --git a/src/librustc_mir/transform/clean_end_regions.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs
similarity index 65%
rename from src/librustc_mir/transform/clean_end_regions.rs
rename to src/librustc_mir/transform/cleanup_post_borrowck.rs
index 6e8985d99d287..256b1fd66e9a7 100644
--- a/src/librustc_mir/transform/clean_end_regions.rs
+++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs
@@ -8,16 +8,27 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! This module provides one pass, `CleanEndRegions`, that reduces the
-//! set of `EndRegion` statements in the MIR.
+//! This module provides two passes:
 //!
-//! The "pass" is actually implemented as two traversals (aka visits)
-//! of the input MIR. The first traversal, `GatherBorrowedRegions`,
-//! finds all of the regions in the MIR that are involved in a borrow.
+//!   - `CleanEndRegions`, that reduces the set of `EndRegion` statements
+//!     in the MIR.
+//!   - `CleanUserAssertTy`, that replaces all `UserAssertTy` statements
+//!     with `Nop`.
+//!
+//! The `CleanEndRegions` "pass" is actually implemented as two
+//! traversals (aka visits) of the input MIR. The first traversal,
+//! `GatherBorrowedRegions`, finds all of the regions in the MIR
+//! that are involved in a borrow.
 //!
 //! The second traversal, `DeleteTrivialEndRegions`, walks over the
 //! MIR and removes any `EndRegion` that is applied to a region that
 //! was not seen in the previous pass.
+//!
+//! The `CleanUserAssertTy` pass runs at a distinct time from the
+//! `CleanEndRegions` pass. It is important that the `CleanUserAssertTy`
+//! pass runs after the MIR borrowck so that the NLL type checker can
+//! perform the type assertion when it encounters the `UserAssertTy`
+//! statements.
 
 use rustc_data_structures::fx::FxHashSet;
 
@@ -93,7 +104,33 @@ impl<'a, 'tcx> MutVisitor<'tcx> for DeleteTrivialEndRegions<'a> {
         }
 
         if delete_it {
-            statement.kind = StatementKind::Nop;
+            statement.make_nop();
+        }
+        self.super_statement(block, statement, location);
+    }
+}
+
+pub struct CleanUserAssertTy;
+
+pub struct DeleteUserAssertTy;
+
+impl MirPass for CleanUserAssertTy {
+    fn run_pass<'a, 'tcx>(&self,
+                          _tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                          _source: MirSource,
+                          mir: &mut Mir<'tcx>) {
+        let mut delete = DeleteUserAssertTy;
+        delete.visit_mir(mir);
+    }
+}
+
+impl<'tcx> MutVisitor<'tcx> for DeleteUserAssertTy {
+    fn visit_statement(&mut self,
+                       block: BasicBlock,
+                       statement: &mut Statement<'tcx>,
+                       location: Location) {
+        if let StatementKind::UserAssertTy(..) = statement.kind {
+            statement.make_nop();
         }
         self.super_statement(block, statement, location);
     }
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 81b740c917b5e..63ca35aa0e7b2 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -25,7 +25,7 @@ use syntax_pos::Span;
 
 pub mod add_validation;
 pub mod add_moves_for_packed_drops;
-pub mod clean_end_regions;
+pub mod cleanup_post_borrowck;
 pub mod check_unsafety;
 pub mod simplify_branches;
 pub mod simplify;
@@ -193,7 +193,7 @@ fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea
     let mut mir = tcx.mir_built(def_id).steal();
     run_passes![tcx, mir, def_id, 0;
         // Remove all `EndRegion` statements that are not involved in borrows.
-        clean_end_regions::CleanEndRegions,
+        cleanup_post_borrowck::CleanEndRegions,
 
         // What we need to do constant evaluation.
         simplify::SimplifyCfg::new("initial"),
@@ -234,6 +234,8 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
         simplify_branches::SimplifyBranches::new("initial"),
         remove_noop_landing_pads::RemoveNoopLandingPads,
         simplify::SimplifyCfg::new("early-opt"),
+        // Remove all `UserAssertTy` statements.
+        cleanup_post_borrowck::CleanUserAssertTy,
 
         // These next passes must be executed together
         add_call_guards::CriticalCallEdges,
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 59a872a23b060..aeefd5ab1d5ac 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -21,7 +21,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::middle::const_val::ConstVal;
-use rustc::traits;
+use rustc::traits::{self, TraitEngine};
 use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
 use rustc::ty::cast::CastTy;
 use rustc::ty::maps::Providers;
@@ -1099,6 +1099,7 @@ This does not pose a problem by itself because they can't be accessed directly."
                 StatementKind::InlineAsm {..} |
                 StatementKind::EndRegion(_) |
                 StatementKind::Validate(..) |
+                StatementKind::UserAssertTy(..) |
                 StatementKind::Nop => {}
             }
         });
diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs
index cd80d25c410f1..6d365012525f6 100644
--- a/src/librustc_mir/transform/remove_noop_landing_pads.rs
+++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs
@@ -50,6 +50,7 @@ impl RemoveNoopLandingPads {
                 StatementKind::StorageLive(_) |
                 StatementKind::StorageDead(_) |
                 StatementKind::EndRegion(_) |
+                StatementKind::UserAssertTy(..) |
                 StatementKind::Nop => {
                     // These are all nops in a landing pad (there's some
                     // borrowck interaction between EndRegion and storage
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 76283edac7284..45e7a0d3f4c5a 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -163,6 +163,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             mir::StatementKind::InlineAsm { .. } |
             mir::StatementKind::EndRegion(_) |
             mir::StatementKind::Validate(..) |
+            mir::StatementKind::UserAssertTy(..) |
             mir::StatementKind::Nop => continue,
             mir::StatementKind::SetDiscriminant{ .. } =>
                 span_bug!(stmt.source_info.span,
diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs
index 89242ca32bcbf..5e15348de5e71 100644
--- a/src/librustc_mir/util/borrowck_errors.rs
+++ b/src/librustc_mir/util/borrowck_errors.rs
@@ -52,30 +52,30 @@ impl Origin {
     }
 }
 
-pub trait BorrowckErrors {
-    fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
-                                                         sp: S,
-                                                         msg: &str,
-                                                         code: DiagnosticId)
-                                                         -> DiagnosticBuilder<'a>;
-
-    fn struct_span_err<'a, S: Into<MultiSpan>>(&'a self,
-                                               sp: S,
-                                               msg: &str)
-                                               -> DiagnosticBuilder<'a>;
+pub trait BorrowckErrors<'cx>: Sized + Copy {
+    fn struct_span_err_with_code<S: Into<MultiSpan>>(self,
+                                                     sp: S,
+                                                     msg: &str,
+                                                     code: DiagnosticId)
+                                                     -> DiagnosticBuilder<'cx>;
+
+    fn struct_span_err<S: Into<MultiSpan>>(self,
+                                           sp: S,
+                                           msg: &str)
+                                           -> DiagnosticBuilder<'cx>;
 
     /// Cancels the given error if we shouldn't emit errors for a given
     /// origin in the current mode.
     ///
     /// Always make sure that the error gets passed through this function
     /// before you return it.
-    fn cancel_if_wrong_origin<'a>(&'a self,
-                                diag: DiagnosticBuilder<'a>,
-                                o: Origin)
-                                -> DiagnosticBuilder<'a>;
+    fn cancel_if_wrong_origin(self,
+                              diag: DiagnosticBuilder<'cx>,
+                              o: Origin)
+                              -> DiagnosticBuilder<'cx>;
 
-    fn cannot_move_when_borrowed(&self, span: Span, desc: &str, o: Origin)
-                                 -> DiagnosticBuilder<'_>
+    fn cannot_move_when_borrowed(self, span: Span, desc: &str, o: Origin)
+                                 -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self, span, E0505,
                                    "cannot move out of `{}` because it is borrowed{OGN}",
@@ -83,13 +83,13 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_use_when_mutably_borrowed(&self,
+    fn cannot_use_when_mutably_borrowed(self,
                                         span: Span,
                                         desc: &str,
                                         borrow_span: Span,
                                         borrow_desc: &str,
                                         o: Origin)
-                                        -> DiagnosticBuilder<'_>
+                                        -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, span, E0503,
                          "cannot use `{}` because it was mutably borrowed{OGN}",
@@ -101,12 +101,12 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_act_on_uninitialized_variable(&self,
+    fn cannot_act_on_uninitialized_variable(self,
                                             span: Span,
                                             verb: &str,
                                             desc: &str,
                                             o: Origin)
-                                            -> DiagnosticBuilder
+                                            -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self, span, E0381,
                                    "{} of possibly uninitialized variable: `{}`{OGN}",
@@ -114,7 +114,7 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_mutably_borrow_multiply(&self,
+    fn cannot_mutably_borrow_multiply(self,
                                       new_loan_span: Span,
                                       desc: &str,
                                       opt_via: &str,
@@ -122,7 +122,7 @@ pub trait BorrowckErrors {
                                       old_opt_via: &str,
                                       old_load_end_span: Option<Span>,
                                       o: Origin)
-                                      -> DiagnosticBuilder
+                                      -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, new_loan_span, E0499,
                          "cannot borrow `{}`{} as mutable more than once at a time{OGN}",
@@ -148,13 +148,13 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_uniquely_borrow_by_two_closures(&self,
+    fn cannot_uniquely_borrow_by_two_closures(self,
                                               new_loan_span: Span,
                                               desc: &str,
                                               old_loan_span: Span,
                                               old_load_end_span: Option<Span>,
                                               o: Origin)
-                                              -> DiagnosticBuilder
+                                              -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, new_loan_span, E0524,
                          "two closures require unique access to `{}` at the same time{OGN}",
@@ -173,7 +173,7 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_uniquely_borrow_by_one_closure(&self,
+    fn cannot_uniquely_borrow_by_one_closure(self,
                                              new_loan_span: Span,
                                              desc_new: &str,
                                              opt_via: &str,
@@ -182,7 +182,7 @@ pub trait BorrowckErrors {
                                              old_opt_via: &str,
                                              previous_end_span: Option<Span>,
                                              o: Origin)
-                                             -> DiagnosticBuilder
+                                             -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, new_loan_span, E0500,
                          "closure requires unique access to `{}` but {} is already borrowed{}{OGN}",
@@ -197,7 +197,7 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_reborrow_already_uniquely_borrowed(&self,
+    fn cannot_reborrow_already_uniquely_borrowed(self,
                                                  new_loan_span: Span,
                                                  desc_new: &str,
                                                  opt_via: &str,
@@ -206,7 +206,7 @@ pub trait BorrowckErrors {
                                                  old_opt_via: &str,
                                                  previous_end_span: Option<Span>,
                                                  o: Origin)
-                                                 -> DiagnosticBuilder
+                                                 -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, new_loan_span, E0501,
                          "cannot borrow `{}`{} as {} because previous closure \
@@ -222,7 +222,7 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_reborrow_already_borrowed(&self,
+    fn cannot_reborrow_already_borrowed(self,
                                         span: Span,
                                         desc_new: &str,
                                         msg_new: &str,
@@ -233,7 +233,7 @@ pub trait BorrowckErrors {
                                         msg_old: &str,
                                         old_load_end_span: Option<Span>,
                                         o: Origin)
-                                        -> DiagnosticBuilder
+                                        -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, span, E0502,
                          "cannot borrow `{}`{} as {} because {} is also borrowed as {}{}{OGN}",
@@ -246,8 +246,8 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_assign_to_borrowed(&self, span: Span, borrow_span: Span, desc: &str, o: Origin)
-                                 -> DiagnosticBuilder
+    fn cannot_assign_to_borrowed(self, span: Span, borrow_span: Span, desc: &str, o: Origin)
+                                 -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, span, E0506,
                          "cannot assign to `{}` because it is borrowed{OGN}",
@@ -259,8 +259,8 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_move_into_closure(&self, span: Span, desc: &str, o: Origin)
-                                -> DiagnosticBuilder
+    fn cannot_move_into_closure(self, span: Span, desc: &str, o: Origin)
+                                -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self, span, E0504,
                                    "cannot move `{}` into closure because it is borrowed{OGN}",
@@ -269,8 +269,8 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_reassign_immutable(&self, span: Span, desc: &str, is_arg: bool, o: Origin)
-                                 -> DiagnosticBuilder
+    fn cannot_reassign_immutable(self, span: Span, desc: &str, is_arg: bool, o: Origin)
+                                 -> DiagnosticBuilder<'cx>
     {
         let msg = if is_arg {
             "to immutable argument"
@@ -284,7 +284,7 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_assign(&self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder
+    fn cannot_assign(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self, span, E0594,
                                   "cannot assign to {}{OGN}",
@@ -292,14 +292,14 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_assign_static(&self, span: Span, desc: &str, o: Origin)
-                            -> DiagnosticBuilder
+    fn cannot_assign_static(self, span: Span, desc: &str, o: Origin)
+                            -> DiagnosticBuilder<'cx>
     {
         self.cannot_assign(span, &format!("immutable static item `{}`", desc), o)
     }
 
-    fn cannot_move_out_of(&self, move_from_span: Span, move_from_desc: &str, o: Origin)
-                          -> DiagnosticBuilder
+    fn cannot_move_out_of(self, move_from_span: Span, move_from_desc: &str, o: Origin)
+                          -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, move_from_span, E0507,
                                        "cannot move out of {}{OGN}",
@@ -311,12 +311,12 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_move_out_of_interior_noncopy(&self,
+    fn cannot_move_out_of_interior_noncopy(self,
                                            move_from_span: Span,
                                            ty: ty::Ty,
                                            is_index: bool,
                                            o: Origin)
-                                           -> DiagnosticBuilder
+                                           -> DiagnosticBuilder<'cx>
     {
         let type_name = match (&ty.sty, is_index) {
             (&ty::TyArray(_, _), true) => "array",
@@ -332,11 +332,11 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_move_out_of_interior_of_drop(&self,
+    fn cannot_move_out_of_interior_of_drop(self,
                                            move_from_span: Span,
                                            container_ty: ty::Ty,
                                            o: Origin)
-                                           -> DiagnosticBuilder
+                                           -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, move_from_span, E0509,
                                        "cannot move out of type `{}`, \
@@ -347,13 +347,13 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_act_on_moved_value(&self,
+    fn cannot_act_on_moved_value(self,
                                  use_span: Span,
                                  verb: &str,
                                  optional_adverb_for_moved: &str,
                                  moved_path: &str,
                                  o: Origin)
-                                 -> DiagnosticBuilder
+                                 -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self, use_span, E0382,
                                    "{} of {}moved value: `{}`{OGN}",
@@ -362,11 +362,11 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_partially_reinit_an_uninit_struct(&self,
+    fn cannot_partially_reinit_an_uninit_struct(self,
                                                 span: Span,
                                                 uninit_path: &str,
                                                 o: Origin)
-                                                -> DiagnosticBuilder
+                                                -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self,
                                    span,
@@ -377,11 +377,11 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn closure_cannot_assign_to_borrowed(&self,
+    fn closure_cannot_assign_to_borrowed(self,
                                          span: Span,
                                          descr: &str,
                                          o: Origin)
-                                         -> DiagnosticBuilder
+                                         -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self, span, E0595, "closure cannot assign to {}{OGN}",
                                    descr, OGN=o);
@@ -389,11 +389,11 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_borrow_path_as_mutable(&self,
+    fn cannot_borrow_path_as_mutable(self,
                                      span: Span,
                                      path: &str,
                                      o: Origin)
-                                     -> DiagnosticBuilder
+                                     -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{OGN}",
                                    path, OGN=o);
@@ -401,11 +401,11 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_borrow_across_generator_yield(&self,
+    fn cannot_borrow_across_generator_yield(self,
                                             span: Span,
                                             yield_span: Span,
                                             o: Origin)
-                                            -> DiagnosticBuilder
+                                            -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self,
                                        span,
@@ -417,11 +417,11 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn path_does_not_live_long_enough(&self,
+    fn path_does_not_live_long_enough(self,
                                       span: Span,
                                       path: &str,
                                       o: Origin)
-                                      -> DiagnosticBuilder
+                                      -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self, span, E0597, "{} does not live long enough{OGN}",
                                    path, OGN=o);
@@ -429,11 +429,11 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn lifetime_too_short_for_reborrow(&self,
+    fn lifetime_too_short_for_reborrow(self,
                                        span: Span,
                                        path: &str,
                                        o: Origin)
-                                       -> DiagnosticBuilder
+                                       -> DiagnosticBuilder<'cx>
     {
         let err = struct_span_err!(self, span, E0598,
                                    "lifetime of {} is too short to guarantee \
@@ -443,12 +443,12 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_act_on_capture_in_sharable_fn(&self,
+    fn cannot_act_on_capture_in_sharable_fn(self,
                                             span: Span,
                                             bad_thing: &str,
                                             help: (Span, &str),
                                             o: Origin)
-                                            -> DiagnosticBuilder
+                                            -> DiagnosticBuilder<'cx>
     {
         let (help_span, help_msg) = help;
         let mut err = struct_span_err!(self, span, E0387,
@@ -459,11 +459,11 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_assign_into_immutable_reference(&self,
+    fn cannot_assign_into_immutable_reference(self,
                                               span: Span,
                                               bad_thing: &str,
                                               o: Origin)
-                                              -> DiagnosticBuilder
+                                              -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, span, E0389, "{} in a `&` reference{OGN}",
                                        bad_thing, OGN=o);
@@ -472,12 +472,12 @@ pub trait BorrowckErrors {
         self.cancel_if_wrong_origin(err, o)
     }
 
-    fn cannot_capture_in_long_lived_closure(&self,
+    fn cannot_capture_in_long_lived_closure(self,
                                             closure_span: Span,
                                             borrowed_path: &str,
                                             capture_span: Span,
                                             o: Origin)
-                                            -> DiagnosticBuilder
+                                            -> DiagnosticBuilder<'cx>
     {
         let mut err = struct_span_err!(self, closure_span, E0373,
                                        "closure may outlive the current function, \
@@ -491,28 +491,28 @@ pub trait BorrowckErrors {
     }
 }
 
-impl<'b, 'gcx, 'tcx> BorrowckErrors for TyCtxt<'b, 'gcx, 'tcx> {
-    fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
-                                                         sp: S,
-                                                         msg: &str,
-                                                         code: DiagnosticId)
-                                                         -> DiagnosticBuilder<'a>
+impl<'cx, 'gcx, 'tcx> BorrowckErrors<'cx> for TyCtxt<'cx, 'gcx, 'tcx> {
+    fn struct_span_err_with_code<S: Into<MultiSpan>>(self,
+                                                     sp: S,
+                                                     msg: &str,
+                                                     code: DiagnosticId)
+                                                     -> DiagnosticBuilder<'cx>
     {
         self.sess.struct_span_err_with_code(sp, msg, code)
     }
 
-    fn struct_span_err<'a, S: Into<MultiSpan>>(&'a self,
-                                               sp: S,
-                                               msg: &str)
-                                               -> DiagnosticBuilder<'a>
+    fn struct_span_err<S: Into<MultiSpan>>(self,
+                                           sp: S,
+                                           msg: &str)
+                                           -> DiagnosticBuilder<'cx>
     {
         self.sess.struct_span_err(sp, msg)
     }
 
-    fn cancel_if_wrong_origin<'a>(&'a self,
-                                mut diag: DiagnosticBuilder<'a>,
-                                o: Origin)
-                                -> DiagnosticBuilder<'a>
+    fn cancel_if_wrong_origin(self,
+                              mut diag: DiagnosticBuilder<'cx>,
+                              o: Origin)
+                              -> DiagnosticBuilder<'cx>
     {
         if !o.should_emit_errors(self.borrowck_mode()) {
             self.sess.diagnostic().cancel(&mut diag);
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index e95126c8a1a0f..19f33ef5d45a8 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -177,7 +177,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
                 });
             }
             DropStyle::Conditional => {
-                let unwind = self.unwind; // FIXME(#6393)
+                let unwind = self.unwind; // FIXME(#43234)
                 let succ = self.succ;
                 let drop_bb = self.complete_drop(Some(DropFlagMode::Deep), succ, unwind);
                 self.elaborator.patch().patch_terminator(bb, TerminatorKind::Goto {
@@ -268,7 +268,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
         // Clear the "master" drop flag at the end. This is needed
         // because the "master" drop protects the ADT's discriminant,
         // which is invalidated after the ADT is dropped.
-        let (succ, unwind) = (self.succ, self.unwind); // FIXME(#6393)
+        let (succ, unwind) = (self.succ, self.unwind); // FIXME(#43234)
         (
             self.drop_flag_reset_block(DropFlagMode::Shallow, succ, unwind),
             unwind.map(|unwind| {
@@ -344,7 +344,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
         let interior = self.place.clone().deref();
         let interior_path = self.elaborator.deref_subpath(self.path);
 
-        let succ = self.succ; // FIXME(#6393)
+        let succ = self.succ; // FIXME(#43234)
         let unwind = self.unwind;
         let succ = self.box_free_block(ty, succ, unwind);
         let unwind_succ = self.unwind.map(|unwind| {
@@ -717,7 +717,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
                            ptr_based)
         });
 
-        let succ = self.succ; // FIXME(#6393)
+        let succ = self.succ; // FIXME(#43234)
         let loop_block = self.drop_loop(
             succ,
             cur,
@@ -798,7 +798,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
                 self.open_drop_for_adt(def, substs)
             }
             ty::TyDynamic(..) => {
-                let unwind = self.unwind; // FIXME(#6393)
+                let unwind = self.unwind; // FIXME(#43234)
                 let succ = self.succ;
                 self.complete_drop(Some(DropFlagMode::Deep), succ, unwind)
             }
@@ -849,7 +849,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
 
     fn elaborated_drop_block<'a>(&mut self) -> BasicBlock {
         debug!("elaborated_drop_block({:?})", self);
-        let unwind = self.unwind; // FIXME(#6393)
+        let unwind = self.unwind; // FIXME(#43234)
         let succ = self.succ;
         let blk = self.drop_block(succ, unwind);
         self.elaborate_drop(blk);
@@ -882,7 +882,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
             args: vec![Operand::Move(self.place.clone())],
             destination: Some((unit_temp, target)),
             cleanup: None
-        }; // FIXME(#6393)
+        }; // FIXME(#43234)
         let free_block = self.new_block(unwind, call);
 
         let block_start = Location { block: free_block, statement_index: 0 };
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 55d00f92e4dac..37274d1fc4479 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -37,15 +37,17 @@ impl<'a> AstValidator<'a> {
     }
 
     fn check_lifetime(&self, lifetime: &Lifetime) {
-        let valid_names = [keywords::StaticLifetime.name(), keywords::Invalid.name()];
+        let valid_names = [keywords::UnderscoreLifetime.name(),
+                           keywords::StaticLifetime.name(),
+                           keywords::Invalid.name()];
         if !valid_names.contains(&lifetime.ident.name) &&
-            token::Ident(lifetime.ident.without_first_quote()).is_reserved_ident() {
+            token::is_reserved_ident(lifetime.ident.without_first_quote()) {
             self.err_handler().span_err(lifetime.span, "lifetimes cannot use keyword names");
         }
     }
 
     fn check_label(&self, label: Ident, span: Span) {
-        if token::Ident(label.without_first_quote()).is_reserved_ident() || label.name == "'_" {
+        if token::is_reserved_ident(label.without_first_quote()) {
             self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name));
         }
     }
@@ -65,7 +67,7 @@ impl<'a> AstValidator<'a> {
                                            E0449,
                                            "unnecessary visibility qualifier");
             if vis.node == VisibilityKind::Public {
-                err.span_label(vis.span, "`pub` not needed here");
+                err.span_label(vis.span, "`pub` not permitted here because it's implied");
             }
             if let Some(note) = note {
                 err.note(note);
diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs
index 4a4ce63cc1d4e..a4e056c6b589e 100644
--- a/src/librustc_passes/mir_stats.rs
+++ b/src/librustc_passes/mir_stats.rs
@@ -90,6 +90,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
             StatementKind::StorageLive(..) => "StatementKind::StorageLive",
             StatementKind::StorageDead(..) => "StatementKind::StorageDead",
             StatementKind::InlineAsm { .. } => "StatementKind::InlineAsm",
+            StatementKind::UserAssertTy(..) => "StatementKind::UserAssertTy",
             StatementKind::Nop => "StatementKind::Nop",
         }, &statement.kind);
         self.super_statement(block, statement, location);
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 356ad9ec11bb7..76cbc67096988 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -373,10 +373,14 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
             }
         }
         hir::ExprMethodCall(..) => {
-            let def_id = v.tables.type_dependent_defs()[e.hir_id].def_id();
-            match v.tcx.associated_item(def_id).container {
-                ty::ImplContainer(_) => v.handle_const_fn_call(def_id, node_ty),
-                ty::TraitContainer(_) => v.promotable = false
+            if let Some(def) = v.tables.type_dependent_defs().get(e.hir_id) {
+                let def_id = def.def_id();
+                match v.tcx.associated_item(def_id).container {
+                    ty::ImplContainer(_) => v.handle_const_fn_call(def_id, node_ty),
+                    ty::TraitContainer(_) => v.promotable = false
+                }
+            } else {
+                v.tcx.sess.delay_span_bug(e.span, "no type-dependent def for method call");
             }
         }
         hir::ExprStruct(..) => {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index bf7b81c4d0e42..c192f349c2019 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -119,7 +119,8 @@ impl<'a> Resolver<'a> {
             .collect();
 
         match use_tree.kind {
-            ast::UseTreeKind::Simple(mut ident) => {
+            ast::UseTreeKind::Simple(rename) => {
+                let mut ident = use_tree.ident();
                 let mut source = module_path.pop().unwrap().node;
                 let mut type_ns_only = false;
 
@@ -142,7 +143,7 @@ impl<'a> Resolver<'a> {
                         // Replace `use foo::self;` with `use foo;`
                         let _ = module_path.pop();
                         source = last_segment.node;
-                        if ident.name == keywords::SelfValue.name() {
+                        if rename.is_none() {
                             ident = last_segment.node;
                         }
                     }
@@ -162,7 +163,7 @@ impl<'a> Resolver<'a> {
                             ModuleKind::Block(..) => unreachable!(),
                         };
                         source.name = crate_name;
-                        if ident.name == keywords::DollarCrate.name() {
+                        if rename.is_none() {
                             ident.name = crate_name;
                         }
 
@@ -206,8 +207,8 @@ impl<'a> Resolver<'a> {
 
                 // Ensure there is at most one `self` in the list
                 let self_spans = items.iter().filter_map(|&(ref use_tree, _)| {
-                    if let ast::UseTreeKind::Simple(ident) = use_tree.kind {
-                        if ident.name == keywords::SelfValue.name() {
+                    if let ast::UseTreeKind::Simple(..) = use_tree.kind {
+                        if use_tree.ident().name == keywords::SelfValue.name() {
                             return Some(use_tree.span);
                         }
                     }
@@ -244,9 +245,9 @@ impl<'a> Resolver<'a> {
 
         match item.node {
             ItemKind::Use(ref use_tree) => {
-                // Just an empty prefix to start out
+                // Imports are resolved as global by default, add starting root segment.
                 let prefix = ast::Path {
-                    segments: vec![],
+                    segments: use_tree.prefix.make_root().into_iter().collect(),
                     span: use_tree.span,
                 };
 
@@ -255,7 +256,7 @@ impl<'a> Resolver<'a> {
                 );
             }
 
-            ItemKind::ExternCrate(as_name) => {
+            ItemKind::ExternCrate(orig_name) => {
                 self.crate_loader.process_item(item, &self.definitions);
 
                 // n.b. we don't need to look at the path option here, because cstore already did
@@ -274,7 +275,7 @@ impl<'a> Resolver<'a> {
                     id: item.id,
                     parent,
                     imported_module: Cell::new(Some(module)),
-                    subclass: ImportDirectiveSubclass::ExternCrate(as_name),
+                    subclass: ImportDirectiveSubclass::ExternCrate(orig_name),
                     span: item.span,
                     module_path: Vec::new(),
                     vis: Cell::new(vis),
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index c84caee13e82a..97dcf081f8c8d 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -57,7 +57,7 @@ use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParam, Generics};
 use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
 use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path};
 use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
-use syntax::feature_gate::{feature_err, emit_feature_err, GateIssue};
+use syntax::feature_gate::{feature_err, GateIssue};
 use syntax::parse::token;
 use syntax::ptr::P;
 
@@ -162,6 +162,10 @@ enum ResolutionError<'a> {
     ForwardDeclaredTyParam,
 }
 
+/// Combines an error with provided span and emits it
+///
+/// This takes the error provided, combines it with the span and any additional spans inside the
+/// error and emits it.
 fn resolve_error<'sess, 'a>(resolver: &'sess Resolver,
                             span: Span,
                             resolution_error: ResolutionError<'a>) {
@@ -486,7 +490,7 @@ struct BindingInfo {
     binding_mode: BindingMode,
 }
 
-// Map from the name in a pattern to its binding mode.
+/// Map from the name in a pattern to its binding mode.
 type BindingMap = FxHashMap<Ident, BindingInfo>;
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -681,6 +685,9 @@ impl<'a> PathSource<'a> {
     }
 }
 
+/// Different kinds of symbols don't influence each other.
+///
+/// Therefore, they have a separate universe (namespace).
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 pub enum Namespace {
     TypeNS,
@@ -688,6 +695,7 @@ pub enum Namespace {
     MacroNS,
 }
 
+/// Just a helper ‒ separate structure for each namespace.
 #[derive(Clone, Default, Debug)]
 pub struct PerNS<T> {
     value_ns: T,
@@ -756,7 +764,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
                     // don't suggest placing a use before the prelude
                     // import or other generated ones
                     if item.span.ctxt().outer().expn_info().is_none() {
-                        self.span = Some(item.span.with_hi(item.span.lo()));
+                        self.span = Some(item.span.shrink_to_lo());
                         self.found_use = true;
                         return;
                     }
@@ -768,12 +776,12 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
                     if item.span.ctxt().outer().expn_info().is_none() {
                         // don't insert between attributes and an item
                         if item.attrs.is_empty() {
-                            self.span = Some(item.span.with_hi(item.span.lo()));
+                            self.span = Some(item.span.shrink_to_lo());
                         } else {
                             // find the first attribute on the item
                             for attr in &item.attrs {
                                 if self.span.map_or(true, |span| attr.span < span) {
-                                    self.span = Some(attr.span.with_hi(attr.span.lo()));
+                                    self.span = Some(attr.span.shrink_to_lo());
                                 }
                             }
                         }
@@ -784,6 +792,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
     }
 }
 
+/// This thing walks the whole crate in DFS manner, visiting each item, resolving names as it goes.
 impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
     fn visit_item(&mut self, item: &'tcx Item) {
         self.resolve_item(item);
@@ -910,7 +919,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
     fn visit_generics(&mut self, generics: &'tcx Generics) {
         // For type parameter defaults, we have to ban access
         // to following type parameters, as the Substs can only
-        // provide previous type parameters as they're built.
+        // provide previous type parameters as they're built. We
+        // put all the parameters on the ban list and then remove
+        // them one by one as they are processed and become available.
         let mut default_ban_rib = Rib::new(ForwardTyParamBanRibKind);
         default_ban_rib.bindings.extend(generics.params.iter()
             .filter_map(|p| if let GenericParam::Type(ref tp) = *p { Some(tp) } else { None })
@@ -986,6 +997,17 @@ enum RibKind<'a> {
 }
 
 /// One local scope.
+///
+/// A rib represents a scope names can live in. Note that these appear in many places, not just
+/// around braces. At any place where the list of accessible names (of the given namespace)
+/// changes or a new restrictions on the name accessibility are introduced, a new rib is put onto a
+/// stack. This may be, for example, a `let` statement (because it introduces variables), a macro,
+/// etc.
+///
+/// Different [rib kinds](enum.RibKind) are transparent for different names.
+///
+/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
+/// resolving, the name is looked up from inside out.
 #[derive(Debug)]
 struct Rib<'a> {
     bindings: FxHashMap<Ident, Def>,
@@ -1001,6 +1023,11 @@ impl<'a> Rib<'a> {
     }
 }
 
+/// An intermediate resolution result.
+///
+/// This refers to the thing referred by a name. The difference between `Def` and `Item` is that
+/// items are visible in their whole block, while defs only from the place they are defined
+/// forward.
 enum LexicalScopeBinding<'a> {
     Item(&'a NameBinding<'a>),
     Def(Def),
@@ -1031,7 +1058,26 @@ enum PathResult<'a> {
 }
 
 enum ModuleKind {
+    /// An anonymous module, eg. just a block.
+    ///
+    /// ```
+    /// fn main() {
+    ///     fn f() {} // (1)
+    ///     { // This is an anonymous module
+    ///         f(); // This resolves to (2) as we are inside the block.
+    ///         fn f() {} // (2)
+    ///     }
+    ///     f(); // Resolves to (1)
+    /// }
+    /// ```
     Block(NodeId),
+    /// Any module with a name.
+    ///
+    /// This could be:
+    ///
+    /// * A normal module ‒ either `mod from_file;` or `mod from_block { }`.
+    /// * A trait or an enum (it implicitly contains associated types, methods and variant
+    ///   constructors).
     Def(Def, Name),
 }
 
@@ -1316,6 +1362,9 @@ impl<'a> NameBinding<'a> {
 }
 
 /// Interns the names of the primitive types.
+///
+/// All other types are defined somewhere and possibly imported, but the primitive ones need
+/// special handling, since they have no place of origin.
 struct PrimitiveTypeTable {
     primitive_types: FxHashMap<Name, PrimTy>,
 }
@@ -1350,6 +1399,8 @@ impl PrimitiveTypeTable {
 }
 
 /// The main resolver class.
+///
+/// This is the visitor that walks the whole crate.
 pub struct Resolver<'a> {
     session: &'a Session,
     cstore: &'a CrateStore,
@@ -1481,6 +1532,7 @@ pub struct Resolver<'a> {
     injected_crate: Option<Module<'a>>,
 }
 
+/// Nothing really interesting here, it just provides memory for the rest of the crate.
 pub struct ResolverArenas<'a> {
     modules: arena::TypedArena<ModuleData<'a>>,
     local_modules: RefCell<Vec<Module<'a>>>,
@@ -1526,10 +1578,12 @@ impl<'a, 'b: 'a> ty::DefIdTree for &'a Resolver<'b> {
         match id.krate {
             LOCAL_CRATE => self.definitions.def_key(id.index).parent,
             _ => self.cstore.def_key(id).parent,
-        }.map(|index| DefId { index: index, ..id })
+        }.map(|index| DefId { index, ..id })
     }
 }
 
+/// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that
+/// the resolver is no longer needed as all the relevant information is inline.
 impl<'a> hir::lowering::Resolver for Resolver<'a> {
     fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) {
         self.resolve_hir_path_cb(path, is_value,
@@ -1752,6 +1806,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
+    /// Runs the function on each namespace.
     fn per_ns<T, F: FnMut(&mut Self, Namespace) -> T>(&mut self, mut f: F) -> PerNS<T> {
         PerNS {
             type_ns: f(self, TypeNS),
@@ -2164,8 +2219,9 @@ impl<'a> Resolver<'a> {
             }
 
             ItemKind::Use(ref use_tree) => {
+                // Imports are resolved as global by default, add starting root segment.
                 let path = Path {
-                    segments: vec![],
+                    segments: use_tree.prefix.make_root().into_iter().collect(),
                     span: use_tree.span,
                 };
                 self.resolve_use_tree(item.id, use_tree, &path);
@@ -2300,7 +2356,6 @@ impl<'a> Resolver<'a> {
                 None,
                 &path,
                 trait_ref.path.span,
-                trait_ref.path.segments.last().unwrap().span,
                 PathSource::Trait(AliasPossibility::No)
             ).base_def();
             if def != Def::Err {
@@ -2731,8 +2786,7 @@ impl<'a> Resolver<'a> {
         let segments = &path.segments.iter()
             .map(|seg| respan(seg.span, seg.identifier))
             .collect::<Vec<_>>();
-        let ident_span = path.segments.last().map_or(path.span, |seg| seg.span);
-        self.smart_resolve_path_fragment(id, qself, segments, path.span, ident_span, source)
+        self.smart_resolve_path_fragment(id, qself, segments, path.span, source)
     }
 
     fn smart_resolve_path_fragment(&mut self,
@@ -2740,9 +2794,9 @@ impl<'a> Resolver<'a> {
                                    qself: Option<&QSelf>,
                                    path: &[SpannedIdent],
                                    span: Span,
-                                   ident_span: Span,
                                    source: PathSource)
                                    -> PathResolution {
+        let ident_span = path.last().map_or(span, |ident| ident.span);
         let ns = source.namespace();
         let is_expected = &|def| source.is_expected(def);
         let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false };
@@ -3090,7 +3144,7 @@ impl<'a> Resolver<'a> {
             // Make sure `A::B` in `<T as A>::B::C` is a trait item.
             let ns = if qself.position + 1 == path.len() { ns } else { TypeNS };
             let res = self.smart_resolve_path_fragment(id, None, &path[..qself.position + 1],
-                                                       span, span, PathSource::TraitItem(ns));
+                                                       span, PathSource::TraitItem(ns));
             return Some(PathResolution::with_unresolved_segments(
                 res.base_def(), res.unresolved_segments() + path.len() - qself.position - 1
             ));
@@ -3118,17 +3172,6 @@ impl<'a> Resolver<'a> {
                        self.primitive_type_table.primitive_types
                            .contains_key(&path[0].node.name) => {
                 let prim = self.primitive_type_table.primitive_types[&path[0].node.name];
-                match prim {
-                    TyUint(UintTy::U128) | TyInt(IntTy::I128) => {
-                        if !self.session.features_untracked().i128_type {
-                            emit_feature_err(&self.session.parse_sess,
-                                                "i128_type", span, GateIssue::Language,
-                                                "128-bit type is unstable");
-
-                        }
-                    }
-                    _ => {}
-                }
                 PathResolution::with_unresolved_segments(Def::PrimTy(prim), path.len() - 1)
             }
             PathResult::Module(module) => PathResolution::new(module.def().unwrap()),
@@ -3207,7 +3250,7 @@ impl<'a> Resolver<'a> {
                     // `$crate::a::b`
                     module = Some(self.resolve_crate_root(ident.node.ctxt, true));
                     continue
-                } else if i == 1 && !token::Ident(ident.node).is_path_segment_keyword() {
+                } else if i == 1 && !token::is_path_segment_keyword(ident.node) {
                     let prev_name = path[0].node.name;
                     if prev_name == keywords::Extern.name() ||
                        prev_name == keywords::CrateRoot.name() &&
@@ -3941,8 +3984,12 @@ impl<'a> Resolver<'a> {
                 ty::Visibility::Restricted(self.current_module.normal_ancestor_id)
             }
             ast::VisibilityKind::Restricted { ref path, id, .. } => {
-                let def = self.smart_resolve_path(id, None, path,
-                                                  PathSource::Visibility).base_def();
+                // Visibilities are resolved as global by default, add starting root segment.
+                let segments = path.make_root().iter().chain(path.segments.iter())
+                    .map(|seg| respan(seg.span, seg.identifier))
+                    .collect::<Vec<_>>();
+                let def = self.smart_resolve_path_fragment(id, None, &segments, path.span,
+                                                           PathSource::Visibility).base_def();
                 if def == Def::Err {
                     ty::Visibility::Public
                 } else {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 95fa0f3b52fef..0692a1e0d7f8a 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -268,7 +268,7 @@ impl<'a> base::Resolver for Resolver<'a> {
                                 if k > 0 {
                                     tokens.push(TokenTree::Token(path.span, Token::ModSep).into());
                                 }
-                                let tok = Token::Ident(segment.identifier);
+                                let tok = Token::from_ast_ident(segment.identifier);
                                 tokens.push(TokenTree::Token(path.span, tok).into());
                             }
                         }
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 01c1ded94578e..7036bdd0e2b07 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -625,7 +625,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
                         } else {
                             Some(self.resolve_crate_root(source.ctxt.modern(), false))
                         }
-                    } else if is_extern && !token::Ident(source).is_path_segment_keyword() {
+                    } else if is_extern && !token::is_path_segment_keyword(source) {
                         let crate_id =
                             self.crate_loader.resolve_crate_from_path(source.name, directive.span);
                         let crate_root =
@@ -667,11 +667,10 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
             }
             PathResult::Failed(span, msg, true) => {
                 let (mut self_path, mut self_result) = (module_path.clone(), None);
-                if !self_path.is_empty() &&
-                    !token::Ident(self_path[0].node).is_path_segment_keyword() &&
-                    !(self_path.len() > 1 &&
-                      token::Ident(self_path[1].node).is_path_segment_keyword())
-                {
+                let is_special = |ident| token::is_path_segment_keyword(ident) &&
+                                         ident.name != keywords::CrateRoot.name();
+                if !self_path.is_empty() && !is_special(self_path[0].node) &&
+                   !(self_path.len() > 1 && is_special(self_path[1].node)) {
                     self_path[0].node.name = keywords::SelfValue.name();
                     self_result = Some(self.resolve_path(&self_path, None, false, span));
                 }
@@ -1026,28 +1025,9 @@ fn import_path_to_string(names: &[SpannedIdent],
         if names.is_empty() {
             import_directive_subclass_to_string(subclass)
         } else {
-            // FIXME: Remove this entire logic after #48116 is fixed.
-            //
-            // Note that this code looks a little wonky, it's currently here to
-            // hopefully help debug #48116, but otherwise isn't intended to
-            // cause any problems.
-            let x = format!(
-                "{}::{}",
-                names_to_string(names),
-                import_directive_subclass_to_string(subclass),
-            );
-            if names.is_empty() || x.starts_with("::") {
-                span_bug!(
-                    span,
-                    "invalid name `{}` at {:?}; global = {}, names = {:?}, subclass = {:?}",
-                    x,
-                    span,
-                    global,
-                    names,
-                    subclass
-                );
-            }
-            return x
+            format!("{}::{}",
+                    names_to_string(names),
+                    import_directive_subclass_to_string(subclass))
         }
     }
 }
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index d92025a6787d6..3d4d8571c6e42 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -1209,7 +1209,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
 
     fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId) {
         self.process_macro_use(trait_item.span);
-        let vis_span = trait_item.span.empty();
+        let vis_span = trait_item.span.shrink_to_lo();
         match trait_item.node {
             ast::TraitItemKind::Const(ref ty, ref expr) => {
                 self.process_assoc_const(
@@ -1342,7 +1342,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
             .map(::id_from_def_id);
 
         match use_tree.kind {
-            ast::UseTreeKind::Simple(ident) => {
+            ast::UseTreeKind::Simple(..) => {
+                let ident = use_tree.ident();
                 let path = ast::Path {
                     segments: prefix.segments
                         .iter()
diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs
index 2a8cfe5cc06b3..1fe2f87128abd 100644
--- a/src/librustc_traits/dropck_outlives.rs
+++ b/src/librustc_traits/dropck_outlives.rs
@@ -16,14 +16,14 @@ use rustc::traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResu
 use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt};
 use rustc::ty::subst::Subst;
 use rustc::util::nodemap::FxHashSet;
-use std::rc::Rc;
+use rustc_data_structures::sync::Lrc;
 use syntax::codemap::{Span, DUMMY_SP};
 use util;
 
 crate fn dropck_outlives<'tcx>(
     tcx: TyCtxt<'_, 'tcx, 'tcx>,
     goal: CanonicalTyGoal<'tcx>,
-) -> Result<Rc<Canonical<'tcx, QueryResult<'tcx, DropckOutlivesResult<'tcx>>>>, NoSolution> {
+) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, DropckOutlivesResult<'tcx>>>>, NoSolution> {
     debug!("dropck_outlives(goal={:#?})", goal);
 
     tcx.infer_ctxt().enter(|ref infcx| {
diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs
index 45d23a2733a2a..0a21cc597e63b 100644
--- a/src/librustc_traits/lib.rs
+++ b/src/librustc_traits/lib.rs
@@ -14,7 +14,7 @@
 #![deny(warnings)]
 
 #![feature(crate_visibility_modifier)]
-#![feature(match_default_bindings)]
+#![cfg_attr(stage0, feature(match_default_bindings))]
 #![feature(underscore_lifetimes)]
 
 #[macro_use]
@@ -29,6 +29,7 @@ mod dropck_outlives;
 mod normalize_projection_ty;
 mod normalize_erasing_regions;
 mod util;
+pub mod lowering;
 
 use rustc::ty::maps::Providers;
 
@@ -39,6 +40,7 @@ pub fn provide(p: &mut Providers) {
         normalize_projection_ty: normalize_projection_ty::normalize_projection_ty,
         normalize_ty_after_erasing_regions:
             normalize_erasing_regions::normalize_ty_after_erasing_regions,
+        program_clauses_for: lowering::program_clauses_for,
         ..*p
     };
 }
diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs
new file mode 100644
index 0000000000000..1092e826a35f9
--- /dev/null
+++ b/src/librustc_traits/lowering.rs
@@ -0,0 +1,225 @@
+// Copyright 2018 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 rustc::hir::{self, ImplPolarity};
+use rustc::hir::def_id::DefId;
+use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
+use rustc::ty::{self, TyCtxt};
+use rustc::ty::subst::Substs;
+use rustc::traits::{QuantifierKind, Goal, DomainGoal, Clause, WhereClauseAtom};
+use syntax::ast;
+use rustc_data_structures::sync::Lrc;
+
+trait Lower<T> {
+    /// Lower a rustc construction (e.g. `ty::TraitPredicate`) to a chalk-like type.
+    fn lower(&self) -> T;
+}
+
+impl<T, U> Lower<Vec<U>> for Vec<T> where T: Lower<U> {
+    fn lower(&self) -> Vec<U> {
+        self.iter().map(|item| item.lower()).collect()
+    }
+}
+
+impl<'tcx> Lower<WhereClauseAtom<'tcx>> for ty::TraitPredicate<'tcx> {
+    fn lower(&self) -> WhereClauseAtom<'tcx> {
+        WhereClauseAtom::Implemented(*self)
+    }
+}
+
+impl<'tcx> Lower<WhereClauseAtom<'tcx>> for ty::ProjectionPredicate<'tcx> {
+    fn lower(&self) -> WhereClauseAtom<'tcx> {
+        WhereClauseAtom::ProjectionEq(*self)
+    }
+}
+
+impl<'tcx, T> Lower<DomainGoal<'tcx>> for T where T: Lower<WhereClauseAtom<'tcx>> {
+    fn lower(&self) -> DomainGoal<'tcx> {
+        DomainGoal::Holds(self.lower())
+    }
+}
+
+impl<'tcx> Lower<DomainGoal<'tcx>> for ty::RegionOutlivesPredicate<'tcx> {
+    fn lower(&self) -> DomainGoal<'tcx> {
+        DomainGoal::RegionOutlives(*self)
+    }
+}
+
+impl<'tcx> Lower<DomainGoal<'tcx>> for ty::TypeOutlivesPredicate<'tcx> {
+    fn lower(&self) -> DomainGoal<'tcx> {
+        DomainGoal::TypeOutlives(*self)
+    }
+}
+
+/// `ty::Binder` is used for wrapping a rustc construction possibly containing generic
+/// lifetimes, e.g. `for<'a> T: Fn(&'a i32)`. Instead of representing higher-ranked things
+/// in that leaf-form (i.e. `Holds(Implemented(Binder<TraitPredicate>))` in the previous
+/// example), we model them with quantified goals, e.g. as for the previous example:
+/// `forall<'a> { T: Fn(&'a i32) }` which corresponds to something like
+/// `Binder<Holds(Implemented(TraitPredicate))>`.
+///
+/// Also, if `self` does not contain generic lifetimes, we can safely drop the binder and we
+/// can directly lower to a leaf goal instead of a quantified goal.
+impl<'tcx, T> Lower<Goal<'tcx>> for ty::Binder<T>
+    where T: Lower<DomainGoal<'tcx>> + ty::fold::TypeFoldable<'tcx> + Copy
+{
+    fn lower(&self) -> Goal<'tcx> {
+        match self.no_late_bound_regions() {
+            Some(p) => p.lower().into(),
+            None => Goal::Quantified(
+                QuantifierKind::Universal,
+                Box::new(self.map_bound(|p| p.lower().into()))
+            ),
+        }
+    }
+}
+
+impl<'tcx> Lower<Goal<'tcx>> for ty::Predicate<'tcx> {
+    fn lower(&self) -> Goal<'tcx> {
+        use rustc::ty::Predicate::*;
+
+        match self {
+            Trait(predicate) => predicate.lower(),
+            RegionOutlives(predicate) => predicate.lower(),
+            TypeOutlives(predicate) => predicate.lower(),
+            Projection(predicate) => predicate.lower(),
+            WellFormed(ty) => DomainGoal::WellFormedTy(*ty).into(),
+            ObjectSafe(..) |
+            ClosureKind(..) |
+            Subtype(..) |
+            ConstEvaluatable(..) => unimplemented!(),
+        }
+    }
+}
+
+crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
+    -> Lrc<Vec<Clause<'tcx>>>
+{
+    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+    let item = tcx.hir.expect_item(node_id);
+    match item.node {
+        hir::ItemTrait(..) => program_clauses_for_trait(tcx, def_id),
+        hir::ItemImpl(..) => program_clauses_for_impl(tcx, def_id),
+
+        // FIXME: other constructions e.g. traits, associated types...
+        _ => Lrc::new(vec![]),
+    }
+}
+
+fn program_clauses_for_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
+    -> Lrc<Vec<Clause<'tcx>>>
+{
+    // Rule Implemented-From-Env (see rustc guide)
+    //
+    // `trait Trait<P1..Pn> where WC { .. } // P0 == Self`
+    //
+    // ```
+    // forall<Self, P1..Pn> {
+    //   Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)
+    // }
+    // ```
+
+    // `Self: Trait<P1..Pn>`
+    let trait_pred = ty::TraitPredicate {
+        trait_ref: ty::TraitRef {
+            def_id,
+            substs: Substs::identity_for_item(tcx, def_id)
+        }
+    };
+    // `FromEnv(Self: Trait<P1..Pn>)`
+    let from_env = Goal::DomainGoal(DomainGoal::FromEnv(trait_pred.lower()));
+    // `Implemented(Self: Trait<P1..Pn>)`
+    let impl_trait = DomainGoal::Holds(WhereClauseAtom::Implemented(trait_pred));
+
+    // `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
+    let clause = Clause::Implies(vec![from_env], impl_trait);
+    Lrc::new(vec![clause])
+}
+
+fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
+    -> Lrc<Vec<Clause<'tcx>>>
+{
+    if let ImplPolarity::Negative = tcx.impl_polarity(def_id) {
+        return Lrc::new(vec![]);
+    }
+
+    // Rule Implemented-From-Impl (see rustc guide)
+    //
+    // `impl<P0..Pn> Trait<A1..An> for A0 where WC { .. }`
+    //
+    // ```
+    // forall<P0..Pn> {
+    //   Implemented(A0: Trait<A1..An>) :- WC
+    // }
+    // ```
+
+    let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
+    // `Implemented(A0: Trait<A1..An>)`
+    let trait_pred = ty::TraitPredicate { trait_ref }.lower();
+     // `WC`
+    let where_clauses = tcx.predicates_of(def_id).predicates.lower();
+
+     // `Implemented(A0: Trait<A1..An>) :- WC`
+    let clause = Clause::Implies(where_clauses, trait_pred);
+    Lrc::new(vec![clause])
+}
+
+pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    if !tcx.features().rustc_attrs {
+        return;
+    }
+
+    let mut visitor = ClauseDumper { tcx };
+    tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
+}
+
+struct ClauseDumper<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+}
+
+impl <'a, 'tcx> ClauseDumper<'a, 'tcx > {
+    fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) {
+        let def_id = self.tcx.hir.local_def_id(node_id);
+        for attr in attrs {
+            if attr.check_name("rustc_dump_program_clauses") {
+                let clauses = self.tcx.program_clauses_for(def_id);
+                for clause in &*clauses {
+                    self.tcx.sess.struct_span_err(attr.span, &format!("{}", clause)).emit();
+                }
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx> Visitor<'tcx> for ClauseDumper<'a, 'tcx> {
+    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+    }
+
+    fn visit_item(&mut self, item: &'tcx hir::Item) {
+        self.process_attrs(item.id, &item.attrs);
+        intravisit::walk_item(self, item);
+    }
+
+    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
+        self.process_attrs(trait_item.id, &trait_item.attrs);
+        intravisit::walk_trait_item(self, trait_item);
+    }
+
+    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
+        self.process_attrs(impl_item.id, &impl_item.attrs);
+        intravisit::walk_impl_item(self, impl_item);
+    }
+
+    fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
+        self.process_attrs(s.id, &s.attrs);
+        intravisit::walk_struct_field(self, s);
+    }
+}
diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs
index 55785d9586cc3..62d5ef11551c0 100644
--- a/src/librustc_traits/normalize_projection_ty.rs
+++ b/src/librustc_traits/normalize_projection_ty.rs
@@ -14,7 +14,7 @@ use rustc::traits::{self, FulfillmentContext, Normalized, ObligationCause,
 use rustc::traits::query::{CanonicalProjectionGoal, NoSolution, normalize::NormalizationResult};
 use rustc::ty::{ParamEnvAnd, TyCtxt};
 use rustc::util::common::CellUsizeExt;
-use std::rc::Rc;
+use rustc_data_structures::sync::Lrc;
 use syntax::ast::DUMMY_NODE_ID;
 use syntax_pos::DUMMY_SP;
 use util;
@@ -22,7 +22,7 @@ use util;
 crate fn normalize_projection_ty<'tcx>(
     tcx: TyCtxt<'_, 'tcx, 'tcx>,
     goal: CanonicalProjectionGoal<'tcx>,
-) -> Result<Rc<Canonical<'tcx, QueryResult<'tcx, NormalizationResult<'tcx>>>>, NoSolution> {
+) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, NormalizationResult<'tcx>>>>, NoSolution> {
     debug!("normalize_provider(goal={:#?})", goal);
 
     tcx.sess.perf_stats.normalize_projection_ty.increment();
diff --git a/src/librustc_traits/util.rs b/src/librustc_traits/util.rs
index 976eb442a0d13..bff070ab73de3 100644
--- a/src/librustc_traits/util.rs
+++ b/src/librustc_traits/util.rs
@@ -12,7 +12,7 @@ use rustc::infer::InferCtxt;
 use rustc::infer::canonical::{CanonicalVarValues, Canonicalize, Certainty, QueryRegionConstraints,
                               QueryResult};
 use rustc::infer::region_constraints::{Constraint, RegionConstraintData};
-use rustc::traits::FulfillmentContext;
+use rustc::traits::{FulfillmentContext, TraitEngine};
 use rustc::traits::query::NoSolution;
 use rustc::ty;
 use std::fmt::Debug;
diff --git a/src/librustc_trans/README.md b/src/librustc_trans/README.md
index b69d632a6a0df..d1868ba2abb17 100644
--- a/src/librustc_trans/README.md
+++ b/src/librustc_trans/README.md
@@ -1,7 +1,7 @@
-NB: This crate is part of the Rust compiler. For an overview of the
-compiler as a whole, see
-[the README.md file found in `librustc`](../librustc/README.md).
-
 The `trans` crate contains the code to convert from MIR into LLVM IR,
 and then from LLVM IR into machine code. In general it contains code
 that runs towards the end of the compilation process.
+
+For more information about how trans works, see the [rustc guide].
+
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trans.html
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs
index 44c18c371a40f..19ae1fa0478ea 100644
--- a/src/librustc_trans/abi.rs
+++ b/src/librustc_trans/abi.rs
@@ -779,7 +779,7 @@ impl<'a, 'tcx> FnType<'tcx> {
 
                     // HACK(eddyb) LLVM inserts `llvm.assume` calls when inlining functions
                     // with align attributes, and those calls later block optimizations.
-                    if !is_return {
+                    if !is_return && !cx.tcx.sess.opts.debugging_opts.arg_align_attributes {
                         attrs.pointee_align = None;
                     }
 
@@ -950,7 +950,7 @@ impl<'a, 'tcx> FnType<'tcx> {
             "s390x" => cabi_s390x::compute_abi_info(cx, self),
             "asmjs" => cabi_asmjs::compute_abi_info(cx, self),
             "wasm32" => {
-                if cx.sess().opts.target_triple.contains("emscripten") {
+                if cx.sess().opts.target_triple.triple().contains("emscripten") {
                     cabi_asmjs::compute_abi_info(cx, self)
                 } else {
                     cabi_wasm32::compute_abi_info(cx, self)
diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs
index d5ec8d1b55262..c968b8525a5b1 100644
--- a/src/librustc_trans/attributes.rs
+++ b/src/librustc_trans/attributes.rs
@@ -11,11 +11,14 @@
 
 use std::ffi::{CStr, CString};
 
-use rustc::hir::TransFnAttrFlags;
+use rustc::hir::{self, TransFnAttrFlags};
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::session::config::Sanitizer;
+use rustc::ty::TyCtxt;
 use rustc::ty::maps::Providers;
 use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::fx::FxHashMap;
 
 use llvm::{self, Attribute, ValueRef};
 use llvm::AttributePlace::Function;
@@ -89,6 +92,11 @@ pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) {
         _ => {}
     }
 
+    // probestack doesn't play nice either with pgo-gen.
+    if cx.sess().opts.debugging_opts.pgo_gen.is_some() {
+        return;
+    }
+
     // Flag our internal `__rust_probestack` function as the stack probe symbol.
     // This is defined in the `compiler-builtins` crate for each architecture.
     llvm::AddFunctionAttrStringValue(
@@ -139,6 +147,20 @@ pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) {
             llfn, llvm::AttributePlace::Function,
             cstr("target-features\0"), &val);
     }
+
+    // Note that currently the `wasm-import-module` doesn't do anything, but
+    // eventually LLVM 7 should read this and ferry the appropriate import
+    // module to the output file.
+    if cx.tcx.sess.target.target.arch == "wasm32" {
+        if let Some(module) = wasm_import_module(cx.tcx, id) {
+            llvm::AddFunctionAttrStringValue(
+                llfn,
+                llvm::AttributePlace::Function,
+                cstr("wasm-import-module\0"),
+                &module,
+            );
+        }
+    }
 }
 
 fn cstr(s: &'static str) -> &CStr {
@@ -148,9 +170,76 @@ fn cstr(s: &'static str) -> &CStr {
 pub fn provide(providers: &mut Providers) {
     providers.target_features_whitelist = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        Lrc::new(llvm_util::target_feature_whitelist(tcx.sess)
-            .iter()
-            .map(|c| c.to_string())
-            .collect())
+        if tcx.sess.opts.actually_rustdoc {
+            // rustdoc needs to be able to document functions that use all the features, so
+            // whitelist them all
+            Lrc::new(llvm_util::all_known_features()
+                .map(|c| c.to_string())
+                .collect())
+        } else {
+            Lrc::new(llvm_util::target_feature_whitelist(tcx.sess)
+                .iter()
+                .map(|c| c.to_string())
+                .collect())
+        }
+    };
+
+    providers.wasm_custom_sections = |tcx, cnum| {
+        assert_eq!(cnum, LOCAL_CRATE);
+        let mut finder = WasmSectionFinder { tcx, list: Vec::new() };
+        tcx.hir.krate().visit_all_item_likes(&mut finder);
+        Lrc::new(finder.list)
     };
+
+    provide_extern(providers);
+}
+
+struct WasmSectionFinder<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    list: Vec<DefId>,
+}
+
+impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for WasmSectionFinder<'a, 'tcx> {
+    fn visit_item(&mut self, i: &'tcx hir::Item) {
+        match i.node {
+            hir::ItemConst(..) => {}
+            _ => return,
+        }
+        if i.attrs.iter().any(|i| i.check_name("wasm_custom_section")) {
+            self.list.push(self.tcx.hir.local_def_id(i.id));
+        }
+    }
+
+    fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) {}
+
+    fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {}
+}
+
+pub fn provide_extern(providers: &mut Providers) {
+    providers.wasm_import_module_map = |tcx, cnum| {
+        let mut ret = FxHashMap();
+        for lib in tcx.foreign_modules(cnum).iter() {
+            let attrs = tcx.get_attrs(lib.def_id);
+            let mut module = None;
+            for attr in attrs.iter().filter(|a| a.check_name("wasm_import_module")) {
+                module = attr.value_str();
+            }
+            let module = match module {
+                Some(s) => s,
+                None => continue,
+            };
+            for id in lib.foreign_items.iter() {
+                assert_eq!(id.krate, cnum);
+                ret.insert(*id, module.to_string());
+            }
+        }
+
+        Lrc::new(ret)
+    }
+}
+
+fn wasm_import_module(tcx: TyCtxt, id: DefId) -> Option<CString> {
+    tcx.wasm_import_module_map(id.krate)
+        .get(&id)
+        .map(|s| CString::new(&s[..]).unwrap())
 }
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index bdda7741221f5..d19359578330d 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use back::wasm;
 use cc::windows_registry;
 use super::archive::{ArchiveBuilder, ArchiveConfig};
 use super::bytecode::RLIB_BYTECODE_EXTENSION;
@@ -30,6 +31,7 @@ use rustc::util::fs::fix_windows_verbatim_for_gcc;
 use rustc::hir::def_id::CrateNum;
 use tempdir::TempDir;
 use rustc_back::{PanicStrategy, RelroLevel};
+use rustc_back::target::TargetTriple;
 use context::get_reloc_model;
 use llvm;
 
@@ -80,7 +82,7 @@ pub fn get_linker(sess: &Session) -> (PathBuf, Command) {
         }
     };
 
-    let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple, "link.exe");
+    let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe");
 
     let linker_path = sess.opts.cg.linker.as_ref().map(|s| &**s)
         .or(sess.target.target.options.linker.as_ref().map(|s| s.as_ref()))
@@ -810,6 +812,12 @@ fn link_natively(sess: &Session,
             Err(e) => sess.fatal(&format!("failed to run dsymutil: {}", e)),
         }
     }
+
+    if sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown") {
+        wasm::rewrite_imports(&out_filename, &trans.crate_info.wasm_imports);
+        wasm::add_custom_sections(&out_filename,
+                                  &trans.crate_info.wasm_custom_sections);
+    }
 }
 
 fn exec_linker(sess: &Session, cmd: &mut Command, tmpdir: &Path)
@@ -1078,12 +1086,16 @@ fn link_args(cmd: &mut Linker,
         cmd.build_static_executable();
     }
 
+    if sess.opts.debugging_opts.pgo_gen.is_some() {
+        cmd.pgo_gen();
+    }
+
     // FIXME (#2397): At some point we want to rpath our guesses as to
     // where extern libraries might live, based on the
     // addl_lib_search_paths
     if sess.opts.cg.rpath {
         let sysroot = sess.sysroot();
-        let target_triple = &sess.opts.target_triple;
+        let target_triple = sess.opts.target_triple.triple();
         let mut get_install_prefix_lib_path = || {
             let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
             let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs
index 9bd7d83a19185..a9095a66aaa98 100644
--- a/src/librustc_trans/back/linker.rs
+++ b/src/librustc_trans/back/linker.rs
@@ -117,6 +117,7 @@ pub trait Linker {
     fn partial_relro(&mut self);
     fn no_relro(&mut self);
     fn optimize(&mut self);
+    fn pgo_gen(&mut self);
     fn debuginfo(&mut self);
     fn no_default_libraries(&mut self);
     fn build_dylib(&mut self, out_filename: &Path);
@@ -280,8 +281,37 @@ impl<'a> Linker for GccLinker<'a> {
         }
     }
 
+    fn pgo_gen(&mut self) {
+        if !self.sess.target.target.options.linker_is_gnu { return }
+
+        // If we're doing PGO generation stuff and on a GNU-like linker, use the
+        // "-u" flag to properly pull in the profiler runtime bits.
+        //
+        // This is because LLVM otherwise won't add the needed initialization
+        // for us on Linux (though the extra flag should be harmless if it
+        // does).
+        //
+        // See https://reviews.llvm.org/D14033 and https://reviews.llvm.org/D14030.
+        //
+        // Though it may be worth to try to revert those changes upstream, since
+        // the overhead of the initialization should be minor.
+        self.cmd.arg("-u");
+        self.cmd.arg("__llvm_profile_runtime");
+    }
+
     fn debuginfo(&mut self) {
-        // Don't do anything special here for GNU-style linkers.
+        match self.sess.opts.debuginfo {
+            DebugInfoLevel::NoDebugInfo => {
+                // If we are building without debuginfo enabled and we were called with
+                // `-Zstrip-debuginfo-if-disabled=yes`, tell the linker to strip any debuginfo
+                // found when linking to get rid of symbols from libstd.
+                match self.sess.opts.debugging_opts.strip_debuginfo_if_disabled {
+                    Some(true) => { self.linker_arg("-S"); },
+                    _ => {},
+                }
+            },
+            _ => {},
+        };
     }
 
     fn no_default_libraries(&mut self) {
@@ -509,6 +539,10 @@ impl<'a> Linker for MsvcLinker<'a> {
         // Needs more investigation of `/OPT` arguments
     }
 
+    fn pgo_gen(&mut self) {
+        // Nothing needed here.
+    }
+
     fn debuginfo(&mut self) {
         // This will cause the Microsoft linker to generate a PDB file
         // from the CodeView line tables in the object files.
@@ -712,6 +746,10 @@ impl<'a> Linker for EmLinker<'a> {
         self.cmd.args(&["--memory-init-file", "0"]);
     }
 
+    fn pgo_gen(&mut self) {
+        // noop, but maybe we need something like the gnu linker?
+    }
+
     fn debuginfo(&mut self) {
         // Preserve names or generate source maps depending on debug info
         self.cmd.arg(match self.sess.opts.debuginfo {
@@ -877,6 +915,9 @@ impl Linker for WasmLd {
     fn optimize(&mut self) {
     }
 
+    fn pgo_gen(&mut self) {
+    }
+
     fn debuginfo(&mut self) {
     }
 
diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs
index fd79ae7435ed1..d205e6ca4eda6 100644
--- a/src/librustc_trans/back/symbol_export.rs
+++ b/src/librustc_trans/back/symbol_export.rs
@@ -223,6 +223,20 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
     }
 
+    if tcx.sess.opts.debugging_opts.pgo_gen.is_some() {
+        // These are weak symbols that point to the profile version and the
+        // profile name, which need to be treated as exported so LTO doesn't nix
+        // them.
+        const PROFILER_WEAK_SYMBOLS: [&'static str; 2] = [
+            "__llvm_profile_raw_version",
+            "__llvm_profile_filename",
+        ];
+        for sym in &PROFILER_WEAK_SYMBOLS {
+            let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(sym));
+            symbols.push((exported_symbol, SymbolExportLevel::C));
+        }
+    }
+
     if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) {
         let symbol_name = metadata_symbol_name(tcx);
         let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(&symbol_name));
diff --git a/src/librustc_trans/back/wasm.rs b/src/librustc_trans/back/wasm.rs
new file mode 100644
index 0000000000000..d6d386c9fbe77
--- /dev/null
+++ b/src/librustc_trans/back/wasm.rs
@@ -0,0 +1,261 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::collections::BTreeMap;
+use std::fs;
+use std::path::Path;
+use std::str;
+
+use rustc_data_structures::fx::FxHashMap;
+use serialize::leb128;
+
+// https://webassembly.github.io/spec/core/binary/modules.html#binary-importsec
+const WASM_IMPORT_SECTION_ID: u8 = 2;
+
+const WASM_EXTERNAL_KIND_FUNCTION: u8 = 0;
+const WASM_EXTERNAL_KIND_TABLE: u8 = 1;
+const WASM_EXTERNAL_KIND_MEMORY: u8 = 2;
+const WASM_EXTERNAL_KIND_GLOBAL: u8 = 3;
+
+/// Append all the custom sections listed in `sections` to the wasm binary
+/// specified at `path`.
+///
+/// LLVM 6 which we're using right now doesn't have the ability to create custom
+/// sections in wasm files nor does LLD have the ability to merge these sections
+/// into one larger section when linking. It's expected that this will
+/// eventually get implemented, however!
+///
+/// Until that time though this is a custom implementation in rustc to append
+/// all sections to a wasm file to the finished product that LLD produces.
+///
+/// Support for this is landing in LLVM in https://reviews.llvm.org/D43097,
+/// although after that support will need to be in LLD as well.
+pub fn add_custom_sections(path: &Path, sections: &BTreeMap<String, Vec<u8>>) {
+    if sections.len() == 0 {
+        return
+    }
+
+    let wasm = fs::read(path).expect("failed to read wasm output");
+
+    // see https://webassembly.github.io/spec/core/binary/modules.html#custom-section
+    let mut wasm = WasmEncoder { data: wasm };
+    for (section, bytes) in sections {
+        // write the `id` identifier, 0 for a custom section
+        wasm.byte(0);
+
+        // figure out how long our name descriptor will be
+        let mut name = WasmEncoder::new();
+        name.str(section);
+
+        // write the length of the payload followed by all its contents
+        wasm.u32((bytes.len() + name.data.len()) as u32);
+        wasm.data.extend_from_slice(&name.data);
+        wasm.data.extend_from_slice(bytes);
+    }
+
+    fs::write(path, &wasm.data).expect("failed to write wasm output");
+}
+
+/// Rewrite the module imports are listed from in a wasm module given the field
+/// name to module name mapping in `import_map`.
+///
+/// LLVM 6 which we're using right now doesn't have the ability to configure the
+/// module a wasm symbol is import from. Rather all imported symbols come from
+/// the bland `"env"` module unconditionally. Furthermore we'd *also* need
+/// support in LLD for preserving these import modules, which it unfortunately
+/// currently does not.
+///
+/// This function is intended as a hack for now where we manually rewrite the
+/// wasm output by LLVM to have the correct import modules listed. The
+/// `#[wasm_import_module]` attribute in Rust translates to the module that each
+/// symbol is imported from, so here we manually go through the wasm file,
+/// decode it, rewrite imports, and then rewrite the wasm module.
+///
+/// Support for this was added to LLVM in
+/// https://github.com/llvm-mirror/llvm/commit/0f32e1365, although support still
+/// needs to be added (AFAIK at the time of this writing) to LLD
+pub fn rewrite_imports(path: &Path, import_map: &FxHashMap<String, String>) {
+    if import_map.len() == 0 {
+        return
+    }
+
+    let wasm = fs::read(path).expect("failed to read wasm output");
+    let mut ret = WasmEncoder::new();
+    ret.data.extend(&wasm[..8]);
+
+    // skip the 8 byte wasm/version header
+    for (id, raw) in WasmSections(WasmDecoder::new(&wasm[8..])) {
+        ret.byte(id);
+        if id == WASM_IMPORT_SECTION_ID {
+            info!("rewriting import section");
+            let data = rewrite_import_section(
+                &mut WasmDecoder::new(raw),
+                import_map,
+            );
+            ret.bytes(&data);
+        } else {
+            info!("carry forward section {}, {} bytes long", id, raw.len());
+            ret.bytes(raw);
+        }
+    }
+
+    fs::write(path, &ret.data).expect("failed to write wasm output");
+
+    fn rewrite_import_section(
+        wasm: &mut WasmDecoder,
+        import_map: &FxHashMap<String, String>,
+    )
+        -> Vec<u8>
+    {
+        let mut dst = WasmEncoder::new();
+        let n = wasm.u32();
+        dst.u32(n);
+        info!("rewriting {} imports", n);
+        for _ in 0..n {
+            rewrite_import_entry(wasm, &mut dst, import_map);
+        }
+        return dst.data
+    }
+
+    fn rewrite_import_entry(wasm: &mut WasmDecoder,
+                            dst: &mut WasmEncoder,
+                            import_map: &FxHashMap<String, String>) {
+        // More info about the binary format here is available at:
+        // https://webassembly.github.io/spec/core/binary/modules.html#import-section
+        //
+        // Note that you can also find the whole point of existence of this
+        // function here, where we map the `module` name to a different one if
+        // we've got one listed.
+        let module = wasm.str();
+        let field = wasm.str();
+        let new_module = if module == "env" {
+            import_map.get(field).map(|s| &**s).unwrap_or(module)
+        } else {
+            module
+        };
+        info!("import rewrite ({} => {}) / {}", module, new_module, field);
+        dst.str(new_module);
+        dst.str(field);
+        let kind = wasm.byte();
+        dst.byte(kind);
+        match kind {
+            WASM_EXTERNAL_KIND_FUNCTION => dst.u32(wasm.u32()),
+            WASM_EXTERNAL_KIND_TABLE => {
+                dst.byte(wasm.byte()); // element_type
+                dst.limits(wasm.limits());
+            }
+            WASM_EXTERNAL_KIND_MEMORY => dst.limits(wasm.limits()),
+            WASM_EXTERNAL_KIND_GLOBAL => {
+                dst.byte(wasm.byte()); // content_type
+                dst.bool(wasm.bool()); // mutable
+            }
+            b => panic!("unknown kind: {}", b),
+        }
+    }
+}
+
+struct WasmSections<'a>(WasmDecoder<'a>);
+
+impl<'a> Iterator for WasmSections<'a> {
+    type Item = (u8, &'a [u8]);
+
+    fn next(&mut self) -> Option<(u8, &'a [u8])> {
+        if self.0.data.len() == 0 {
+            return None
+        }
+
+        // see https://webassembly.github.io/spec/core/binary/modules.html#sections
+        let id = self.0.byte();
+        let section_len = self.0.u32();
+        info!("new section {} / {} bytes", id, section_len);
+        let section = self.0.skip(section_len as usize);
+        Some((id, section))
+    }
+}
+
+struct WasmDecoder<'a> {
+    data: &'a [u8],
+}
+
+impl<'a> WasmDecoder<'a> {
+    fn new(data: &'a [u8]) -> WasmDecoder<'a> {
+        WasmDecoder { data }
+    }
+
+    fn byte(&mut self) -> u8 {
+        self.skip(1)[0]
+    }
+
+    fn u32(&mut self) -> u32 {
+        let (n, l1) = leb128::read_u32_leb128(self.data);
+        self.data = &self.data[l1..];
+        return n
+    }
+
+    fn skip(&mut self, amt: usize) -> &'a [u8] {
+        let (data, rest) = self.data.split_at(amt);
+        self.data = rest;
+        data
+    }
+
+    fn str(&mut self) -> &'a str {
+        let len = self.u32();
+        str::from_utf8(self.skip(len as usize)).unwrap()
+    }
+
+    fn bool(&mut self) -> bool {
+        self.byte() == 1
+    }
+
+    fn limits(&mut self) -> (u32, Option<u32>) {
+        let has_max = self.bool();
+        (self.u32(), if has_max { Some(self.u32()) } else { None })
+    }
+}
+
+struct WasmEncoder {
+    data: Vec<u8>,
+}
+
+impl WasmEncoder {
+    fn new() -> WasmEncoder {
+        WasmEncoder { data: Vec::new() }
+    }
+
+    fn u32(&mut self, val: u32) {
+        let at = self.data.len();
+        leb128::write_u32_leb128(&mut self.data, at, val);
+    }
+
+    fn byte(&mut self, val: u8) {
+        self.data.push(val);
+    }
+
+    fn bytes(&mut self, val: &[u8]) {
+        self.u32(val.len() as u32);
+        self.data.extend_from_slice(val);
+    }
+
+    fn str(&mut self, val: &str) {
+        self.bytes(val.as_bytes())
+    }
+
+    fn bool(&mut self, b: bool) {
+        self.byte(b as u8);
+    }
+
+    fn limits(&mut self, limits: (u32, Option<u32>)) {
+        self.bool(limits.1.is_some());
+        self.u32(limits.0);
+        if let Some(c) = limits.1 {
+            self.u32(c);
+        }
+    }
+}
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 3e7422557e9b6..fc699f7569f1c 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -240,6 +240,9 @@ pub struct ModuleConfig {
     /// Some(level) to optimize binary size, or None to not affect program size.
     opt_size: Option<llvm::CodeGenOptSize>,
 
+    pgo_gen: Option<String>,
+    pgo_use: String,
+
     // Flags indicating which outputs to produce.
     emit_no_opt_bc: bool,
     emit_bc: bool,
@@ -274,6 +277,9 @@ impl ModuleConfig {
             opt_level: None,
             opt_size: None,
 
+            pgo_gen: None,
+            pgo_use: String::new(),
+
             emit_no_opt_bc: false,
             emit_bc: false,
             emit_bc_compressed: false,
@@ -492,8 +498,13 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
                                                 opt.message));
             }
         }
-
-        _ => (),
+        llvm::diagnostic::PGO(diagnostic_ref) => {
+            let msg = llvm::build_string(|s| {
+                llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s)
+            }).expect("non-UTF8 PGO diagnostic");
+            diag_handler.warn(&msg);
+        }
+        llvm::diagnostic::UnknownDiagnostic(..) => {},
     }
 }
 
@@ -848,7 +859,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
         "rustc.embedded.module\0".as_ptr() as *const _,
     );
     llvm::LLVMSetInitializer(llglobal, llconst);
-    let section = if cgcx.opts.target_triple.contains("-ios") {
+    let section = if cgcx.opts.target_triple.triple().contains("-ios") {
         "__LLVM,__bitcode\0"
     } else {
         ".llvmbc\0"
@@ -863,7 +874,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
         "rustc.embedded.cmdline\0".as_ptr() as *const _,
     );
     llvm::LLVMSetInitializer(llglobal, llconst);
-    let section = if cgcx.opts.target_triple.contains("-ios") {
+    let section = if cgcx.opts.target_triple.triple().contains("-ios") {
         "__LLVM,__cmdline\0"
     } else {
         ".llvmcmd\0"
@@ -932,6 +943,9 @@ pub fn start_async_translation(tcx: TyCtxt,
         modules_config.passes.push("insert-gcov-profiling".to_owned())
     }
 
+    modules_config.pgo_gen = sess.opts.debugging_opts.pgo_gen.clone();
+    modules_config.pgo_use = sess.opts.debugging_opts.pgo_use.clone();
+
     modules_config.opt_level = Some(get_llvm_opt_level(sess.opts.optimize));
     modules_config.opt_size = Some(get_llvm_opt_size(sess.opts.optimize));
 
@@ -2046,6 +2060,8 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
                             config: &ModuleConfig,
                             opt_level: llvm::CodeGenOptLevel,
                             f: &mut FnMut(llvm::PassManagerBuilderRef)) {
+    use std::ptr;
+
     // Create the PassManagerBuilder for LLVM. We configure it with
     // reasonable defaults and prepare it to actually populate the pass
     // manager.
@@ -2053,11 +2069,27 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
     let opt_size = config.opt_size.unwrap_or(llvm::CodeGenOptSizeNone);
     let inline_threshold = config.inline_threshold;
 
-    llvm::LLVMRustConfigurePassManagerBuilder(builder,
-                                              opt_level,
-                                              config.merge_functions,
-                                              config.vectorize_slp,
-                                              config.vectorize_loop);
+    let pgo_gen_path = config.pgo_gen.as_ref().map(|s| {
+        let s = if s.is_empty() { "default_%m.profraw" } else { s };
+        CString::new(s.as_bytes()).unwrap()
+    });
+
+    let pgo_use_path = if config.pgo_use.is_empty() {
+        None
+    } else {
+        Some(CString::new(config.pgo_use.as_bytes()).unwrap())
+    };
+
+    llvm::LLVMRustConfigurePassManagerBuilder(
+        builder,
+        opt_level,
+        config.merge_functions,
+        config.vectorize_slp,
+        config.vectorize_loop,
+        pgo_gen_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
+        pgo_use_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
+    );
+
     llvm::LLVMPassManagerBuilderSetSizeLevel(builder, opt_size as u32);
 
     if opt_size != llvm::CodeGenOptSizeNone {
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 4da082e9d50f1..3ab33c4134697 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -72,8 +72,11 @@ use type_::Type;
 use type_of::LayoutLlvmExt;
 use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet};
 use CrateInfo;
+use rustc_data_structures::sync::Lrc;
+use rustc_back::target::TargetTriple;
 
 use std::any::Any;
+use std::collections::BTreeMap;
 use std::ffi::CString;
 use std::str;
 use std::sync::Arc;
@@ -706,6 +709,13 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
     }
 
+    if (tcx.sess.opts.debugging_opts.pgo_gen.is_some() ||
+        !tcx.sess.opts.debugging_opts.pgo_use.is_empty()) &&
+        unsafe { !llvm::LLVMRustPGOAvailable() }
+    {
+        tcx.sess.fatal("this compiler's LLVM does not support PGO");
+    }
+
     let crate_hash = tcx.crate_hash(LOCAL_CRATE);
     let link_meta = link::build_link_meta(crate_hash);
 
@@ -1070,8 +1080,26 @@ impl CrateInfo {
             used_crates_dynamic: cstore::used_crates(tcx, LinkagePreference::RequireDynamic),
             used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic),
             used_crate_source: FxHashMap(),
+            wasm_custom_sections: BTreeMap::new(),
+            wasm_imports: FxHashMap(),
         };
 
+        let load_wasm_items = tcx.sess.crate_types.borrow()
+            .iter()
+            .any(|c| *c != config::CrateTypeRlib) &&
+            tcx.sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown");
+
+        if load_wasm_items {
+            info!("attempting to load all wasm sections");
+            for &id in tcx.wasm_custom_sections(LOCAL_CRATE).iter() {
+                let (name, contents) = fetch_wasm_section(tcx, id);
+                info.wasm_custom_sections.entry(name)
+                    .or_insert(Vec::new())
+                    .extend(contents);
+            }
+            info.load_wasm_imports(tcx, LOCAL_CRATE);
+        }
+
         for &cnum in tcx.crates().iter() {
             info.native_libraries.insert(cnum, tcx.native_libraries(cnum));
             info.crate_name.insert(cnum, tcx.crate_name(cnum).to_string());
@@ -1091,11 +1119,27 @@ impl CrateInfo {
             if tcx.is_no_builtins(cnum) {
                 info.is_no_builtins.insert(cnum);
             }
+            if load_wasm_items {
+                for &id in tcx.wasm_custom_sections(cnum).iter() {
+                    let (name, contents) = fetch_wasm_section(tcx, id);
+                    info.wasm_custom_sections.entry(name)
+                        .or_insert(Vec::new())
+                        .extend(contents);
+                }
+                info.load_wasm_imports(tcx, cnum);
+            }
         }
 
-
         return info
     }
+
+    fn load_wasm_imports(&mut self, tcx: TyCtxt, cnum: CrateNum) {
+        for (&id, module) in tcx.wasm_import_module_map(cnum).iter() {
+            let instance = Instance::mono(tcx, id);
+            let import_name = tcx.symbol_name(instance);
+            self.wasm_imports.insert(import_name.to_string(), module.clone());
+        }
+    }
 }
 
 fn is_translated_item(tcx: TyCtxt, id: DefId) -> bool {
@@ -1223,6 +1267,39 @@ pub fn provide(providers: &mut Providers) {
             .expect(&format!("failed to find cgu with name {:?}", name))
     };
     providers.compile_codegen_unit = compile_codegen_unit;
+
+    provide_extern(providers);
+}
+
+pub fn provide_extern(providers: &mut Providers) {
+    providers.dllimport_foreign_items = |tcx, krate| {
+        let module_map = tcx.foreign_modules(krate);
+        let module_map = module_map.iter()
+            .map(|lib| (lib.def_id, lib))
+            .collect::<FxHashMap<_, _>>();
+
+        let dllimports = tcx.native_libraries(krate)
+            .iter()
+            .filter(|lib| {
+                if lib.kind != cstore::NativeLibraryKind::NativeUnknown {
+                    return false
+                }
+                let cfg = match lib.cfg {
+                    Some(ref cfg) => cfg,
+                    None => return true,
+                };
+                attr::cfg_matches(cfg, &tcx.sess.parse_sess, None)
+            })
+            .filter_map(|lib| lib.foreign_module)
+            .map(|id| &module_map[&id])
+            .flat_map(|module| module.foreign_items.iter().cloned())
+            .collect();
+        Lrc::new(dllimports)
+    };
+
+    providers.is_dllimport_foreign_item = |tcx, def_id| {
+        tcx.dllimport_foreign_items(def_id.krate).contains(&def_id)
+    };
 }
 
 pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
@@ -1270,3 +1347,44 @@ mod temp_stable_hash_impls {
         }
     }
 }
+
+fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec<u8>) {
+    use rustc::mir::interpret::{GlobalId, Value, PrimVal};
+    use rustc::middle::const_val::ConstVal;
+
+    info!("loading wasm section {:?}", id);
+
+    let section = tcx.get_attrs(id)
+        .iter()
+        .find(|a| a.check_name("wasm_custom_section"))
+        .expect("missing #[wasm_custom_section] attribute")
+        .value_str()
+        .expect("malformed #[wasm_custom_section] attribute");
+
+    let instance = ty::Instance::mono(tcx, id);
+    let cid = GlobalId {
+        instance,
+        promoted: None
+    };
+    let param_env = ty::ParamEnv::reveal_all();
+    let val = tcx.const_eval(param_env.and(cid)).unwrap();
+
+    let val = match val.val {
+        ConstVal::Value(val) => val,
+        ConstVal::Unevaluated(..) => bug!("should be evaluated"),
+    };
+    let val = match val {
+        Value::ByRef(ptr, _align) => ptr.into_inner_primval(),
+        ref v => bug!("should be ByRef, was {:?}", v),
+    };
+    let mem = match val {
+        PrimVal::Ptr(mem) => mem,
+        ref v => bug!("should be Ptr, was {:?}", v),
+    };
+    assert_eq!(mem.offset, 0);
+    let alloc = tcx
+        .interpret_interner
+        .get_alloc(mem.alloc_id)
+        .expect("miri allocation never successfully created");
+    (section.to_string(), alloc.bytes.clone())
+}
diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs
index 3f5a9a54ff1ea..db803ca8209d9 100644
--- a/src/librustc_trans/builder.rs
+++ b/src/librustc_trans/builder.rs
@@ -344,6 +344,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
+    pub fn exactudiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+        self.count_insn("exactudiv");
+        unsafe {
+            llvm::LLVMBuildExactUDiv(self.llbuilder, lhs, rhs, noname())
+        }
+    }
+
     pub fn sdiv(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
         self.count_insn("sdiv");
         unsafe {
@@ -910,6 +917,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
+    pub fn minnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+        self.count_insn("minnum");
+        unsafe {
+            let instr = llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs);
+            if instr.is_null() {
+                bug!("LLVMRustBuildMinNum is not available in LLVM version < 6.0");
+            }
+            instr
+        }
+    }
+    pub fn maxnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+        self.count_insn("maxnum");
+        unsafe {
+            let instr = llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs);
+            if instr.is_null() {
+                bug!("LLVMRustBuildMaxNum is not available in LLVM version < 6.0");
+            }
+            instr
+        }
+    }
+
     pub fn select(&self, cond: ValueRef, then_val: ValueRef, else_val: ValueRef) -> ValueRef {
         self.count_insn("select");
         unsafe {
@@ -1036,7 +1064,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     pub fn vector_reduce_fmin(&self, src: ValueRef) -> ValueRef {
         self.count_insn("vector.reduce.fmin");
         unsafe {
-            let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, true);
+            let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false);
             if instr.is_null() {
                 bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0");
             }
@@ -1046,7 +1074,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     pub fn vector_reduce_fmax(&self, src: ValueRef) -> ValueRef {
         self.count_insn("vector.reduce.fmax");
         unsafe {
-            let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, true);
+            let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false);
             if instr.is_null() {
                 bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0");
             }
@@ -1056,7 +1084,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     pub fn vector_reduce_fmin_fast(&self, src: ValueRef) -> ValueRef {
         self.count_insn("vector.reduce.fmin_fast");
         unsafe {
-            let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, false);
+            let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true);
             if instr.is_null() {
                 bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0");
             }
@@ -1067,7 +1095,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     pub fn vector_reduce_fmax_fast(&self, src: ValueRef) -> ValueRef {
         self.count_insn("vector.reduce.fmax_fast");
         unsafe {
-            let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, false);
+            let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true);
             if instr.is_null() {
                 bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0");
             }
diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs
index c3de9e0ffcce2..5c67f8091141b 100644
--- a/src/librustc_trans/intrinsic.rs
+++ b/src/librustc_trans/intrinsic.rs
@@ -289,7 +289,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
         "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
         "bitreverse" | "add_with_overflow" | "sub_with_overflow" |
         "mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
-        "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" => {
+        "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "exact_div" => {
             let ty = arg_tys[0];
             match int_type_width_signed(ty, cx) {
                 Some((width, signed)) =>
@@ -343,6 +343,12 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
                         "overflowing_add" => bx.add(args[0].immediate(), args[1].immediate()),
                         "overflowing_sub" => bx.sub(args[0].immediate(), args[1].immediate()),
                         "overflowing_mul" => bx.mul(args[0].immediate(), args[1].immediate()),
+                        "exact_div" =>
+                            if signed {
+                                bx.exactsdiv(args[0].immediate(), args[1].immediate())
+                            } else {
+                                bx.exactudiv(args[0].immediate(), args[1].immediate())
+                            },
                         "unchecked_div" =>
                             if signed {
                                 bx.sdiv(args[0].immediate(), args[1].immediate())
@@ -1153,6 +1159,27 @@ fn generic_simd_intrinsic<'a, 'tcx>(
         return Ok(bx.extract_element(args[0].immediate(), args[1].immediate()))
     }
 
+    if name == "simd_select" {
+        let m_elem_ty = in_elem;
+        let m_len = in_len;
+        let v_len = arg_tys[1].simd_size(tcx);
+        require!(m_len == v_len,
+                 "mismatched lengths: mask length `{}` != other vector length `{}`",
+                 m_len, v_len
+        );
+        match m_elem_ty.sty {
+            ty::TyInt(_) => {},
+            _ => {
+                return_error!("mask element type is `{}`, expected `i_`", m_elem_ty);
+            }
+        }
+        // truncate the mask to a vector of i1s
+        let i1 = Type::i1(bx.cx);
+        let i1xn = Type::vector(&i1, m_len as u64);
+        let m_i1s = bx.trunc(args[0].immediate(), i1xn);
+        return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
+    }
+
     macro_rules! arith_red {
         ($name:tt : $integer_reduce:ident, $float_reduce:ident, $ordered:expr) => {
             if name == $name {
@@ -1405,6 +1432,8 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
         simd_and: TyUint, TyInt => and;
         simd_or: TyUint, TyInt => or;
         simd_xor: TyUint, TyInt => xor;
+        simd_fmax: TyFloat => maxnum;
+        simd_fmin: TyFloat => minnum;
     }
     span_bug!(span, "unknown SIMD intrinsic");
 }
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 3645e72884208..bd33707b1c6f7 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -24,14 +24,13 @@
 #![feature(custom_attribute)]
 #![feature(fs_read_write)]
 #![allow(unused_attributes)]
-#![feature(i128_type)]
-#![feature(i128)]
+#![cfg_attr(stage0, feature(i128_type, i128))]
 #![cfg_attr(stage0, feature(inclusive_range_syntax))]
 #![feature(libc)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
-#![feature(slice_patterns)]
-#![feature(conservative_impl_trait)]
+#![cfg_attr(stage0, feature(slice_patterns))]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
 #![feature(optin_builtin_traits)]
 #![feature(inclusive_range_fields)]
 
@@ -72,6 +71,7 @@ pub use llvm_util::target_features;
 use std::any::Any;
 use std::path::PathBuf;
 use std::sync::mpsc;
+use std::collections::BTreeMap;
 use rustc_data_structures::sync::Lrc;
 
 use rustc::dep_graph::DepGraph;
@@ -98,6 +98,7 @@ mod back {
     pub mod symbol_export;
     pub mod write;
     mod rpath;
+    mod wasm;
 }
 
 mod abi;
@@ -214,6 +215,8 @@ impl TransCrate for LlvmTransCrate {
 
     fn provide_extern(&self, providers: &mut ty::maps::Providers) {
         back::symbol_export::provide_extern(providers);
+        base::provide_extern(providers);
+        attributes::provide_extern(providers);
     }
 
     fn trans_crate<'a, 'tcx>(
@@ -400,6 +403,8 @@ struct CrateInfo {
     used_crate_source: FxHashMap<CrateNum, Lrc<CrateSource>>,
     used_crates_static: Vec<(CrateNum, LibSource)>,
     used_crates_dynamic: Vec<(CrateNum, LibSource)>,
+    wasm_custom_sections: BTreeMap<String, Vec<u8>>,
+    wasm_imports: FxHashMap<String, String>,
 }
 
 __build_diagnostic_array! { librustc_trans, DIAGNOSTICS }
diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs
index dd8b44c96b90c..1c8f09ce7b3f1 100644
--- a/src/librustc_trans/llvm_util.rs
+++ b/src/librustc_trans/llvm_util.rs
@@ -61,6 +61,9 @@ unsafe fn configure_llvm(sess: &Session) {
         add("rustc"); // fake program name
         if sess.time_llvm_passes() { add("-time-passes"); }
         if sess.print_llvm_passes() { add("-debug-pass=Structure"); }
+        if sess.opts.debugging_opts.disable_instrumentation_preinliner {
+            add("-disable-preinline");
+        }
 
         for arg in &sess.opts.cg.llvm_args {
             add(&(*arg));
@@ -107,6 +110,20 @@ const POWERPC_WHITELIST: &'static [&'static str] = &["altivec",
 
 const MIPS_WHITELIST: &'static [&'static str] = &["fp64", "msa"];
 
+/// When rustdoc is running, provide a list of all known features so that all their respective
+/// primtives may be documented.
+///
+/// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this
+/// iterator!
+pub fn all_known_features() -> impl Iterator<Item=&'static str> {
+    ARM_WHITELIST.iter().cloned()
+        .chain(AARCH64_WHITELIST.iter().cloned())
+        .chain(X86_WHITELIST.iter().cloned())
+        .chain(HEXAGON_WHITELIST.iter().cloned())
+        .chain(POWERPC_WHITELIST.iter().cloned())
+        .chain(MIPS_WHITELIST.iter().cloned())
+}
+
 pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str {
     let arch = if sess.target.target.arch == "x86_64" {
         "x86"
diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs
index b5b7484940192..579b07929a2f2 100644
--- a/src/librustc_trans/mir/statement.rs
+++ b/src/librustc_trans/mir/statement.rs
@@ -84,6 +84,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
             }
             mir::StatementKind::EndRegion(_) |
             mir::StatementKind::Validate(..) |
+            mir::StatementKind::UserAssertTy(..) |
             mir::StatementKind::Nop => bx,
         }
     }
diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs
index 6a3fd21f3a771..99de124c6e1ad 100644
--- a/src/librustc_trans_utils/lib.rs
+++ b/src/librustc_trans_utils/lib.rs
@@ -21,11 +21,10 @@
 #![feature(box_syntax)]
 #![feature(custom_attribute)]
 #![allow(unused_attributes)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
-#![feature(slice_patterns)]
-#![feature(conservative_impl_trait)]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
 
 extern crate ar;
 extern crate flate2;
diff --git a/src/librustc_trans_utils/symbol_names_test.rs b/src/librustc_trans_utils/symbol_names_test.rs
index 267c8d2bd03c8..47bbd67fb5c70 100644
--- a/src/librustc_trans_utils/symbol_names_test.rs
+++ b/src/librustc_trans_utils/symbol_names_test.rs
@@ -15,7 +15,6 @@
 //! paths etc in all kinds of annoying scenarios.
 
 use rustc::hir;
-use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::ty::TyCtxt;
 use syntax::ast;
 
@@ -34,8 +33,7 @@ pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
 
     tcx.dep_graph.with_ignore(|| {
         let mut visitor = SymbolNamesTest { tcx: tcx };
-        // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like
-        tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
+        tcx.hir.krate().visit_all_item_likes(&mut visitor);
     })
 }
 
@@ -66,23 +64,16 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SymbolNamesTest<'a, 'tcx> {
-    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::None
-    }
-
+impl<'a, 'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for SymbolNamesTest<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         self.process_attrs(item.id);
-        intravisit::walk_item(self, item);
     }
 
-    fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
-        self.process_attrs(ti.id);
-        intravisit::walk_trait_item(self, ti)
+    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
+        self.process_attrs(trait_item.id);
     }
 
-    fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
-        self.process_attrs(ii.id);
-        intravisit::walk_impl_item(self, ii)
+    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
+        self.process_attrs(impl_item.id);
     }
 }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 827ca79334cbe..0e93277983f8d 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -27,6 +27,7 @@ use std::slice;
 use require_c_abi_if_variadic;
 use util::common::ErrorReported;
 use util::nodemap::FxHashSet;
+use errors::FatalError;
 
 use std::iter;
 use syntax::{abi, ast};
@@ -337,7 +338,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
             Def::Trait(trait_def_id) => trait_def_id,
             Def::TraitAlias(alias_def_id) => alias_def_id,
             Def::Err => {
-                self.tcx().sess.fatal("cannot continue compilation due to previous error");
+                FatalError.raise();
             }
             _ => unreachable!(),
         }
@@ -530,7 +531,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
             let msg = format!("associated type `{}` is private", binding.item_name);
             tcx.sess.span_err(binding.span, &msg);
         }
-        tcx.check_stability(assoc_ty.def_id, ref_id, binding.span);
+        tcx.check_stability(assoc_ty.def_id, Some(ref_id), binding.span);
 
         Ok(candidate.map_bound(|trait_ref| {
             ty::ProjectionPredicate {
@@ -868,7 +869,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
             let msg = format!("{} `{}` is private", def.kind_name(), assoc_name);
             tcx.sess.span_err(span, &msg);
         }
-        tcx.check_stability(item.def_id, ref_id, span);
+        tcx.check_stability(item.def_id, Some(ref_id), span);
 
         (ty, def)
     }
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 379fd93ba2bd6..43ff925e422f1 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -23,7 +23,6 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::cmp;
 use syntax::ast;
 use syntax::codemap::Spanned;
-use syntax::feature_gate;
 use syntax::ptr::P;
 use syntax_pos::Span;
 
@@ -114,42 +113,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 }
             };
             if pat_adjustments.len() > 0 {
-                if tcx.features().match_default_bindings {
-                    debug!("default binding mode is now {:?}", def_bm);
-                    self.inh.tables.borrow_mut()
-                        .pat_adjustments_mut()
-                        .insert(pat.hir_id, pat_adjustments);
-                } else {
-                    let mut ref_sp = pat.span;
-                    let mut id = pat.id;
-                    loop {  // make span include all enclosing `&` to avoid confusing diag output
-                        id = tcx.hir.get_parent_node(id);
-                        let node = tcx.hir.find(id);
-                        if let Some(hir::map::NodePat(pat)) = node {
-                            if let hir::PatKind::Ref(..) = pat.node {
-                                ref_sp = pat.span;
-                            } else {
-                                break;
-                            }
-                        } else {
-                            break;
-                        }
-                    }
-                    let sp = ref_sp.to(pat.span);
-                    let mut err = feature_gate::feature_err(
-                        &tcx.sess.parse_sess,
-                        "match_default_bindings",
-                        sp,
-                        feature_gate::GateIssue::Language,
-                        "non-reference pattern used to match a reference",
-                    );
-                    if let Ok(snippet) = tcx.sess.codemap().span_to_snippet(sp) {
-                        err.span_suggestion(sp,
-                                            "consider using a reference",
-                                            format!("&{}", &snippet));
-                    }
-                    err.emit();
-                }
+                debug!("default binding mode is now {:?}", def_bm);
+                self.inh.tables.borrow_mut()
+                    .pat_adjustments_mut()
+                    .insert(pat.hir_id, pat_adjustments);
             }
         } else if let PatKind::Ref(..) = pat.node {
             // When you encounter a `&pat` pattern, reset to "by
@@ -861,7 +828,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
                 self.check_pat_walk(&subpat, field_ty, def_bm, true);
 
-                self.tcx.check_stability(variant.fields[i].did, pat.id, subpat.span);
+                self.tcx.check_stability(variant.fields[i].did, Some(pat.id), subpat.span);
             }
         } else {
             let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
@@ -904,6 +871,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
         // Keep track of which fields have already appeared in the pattern.
         let mut used_fields = FxHashMap();
 
+        let mut inexistent_fields = vec![];
         // Typecheck each field.
         for &Spanned { node: ref field, span } in fields {
             let field_ty = match used_fields.entry(field.name) {
@@ -922,39 +890,12 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                     vacant.insert(span);
                     field_map.get(&field.name)
                         .map(|f| {
-                            self.tcx.check_stability(f.did, pat_id, span);
+                            self.tcx.check_stability(f.did, Some(pat_id), span);
 
                             self.field_ty(span, f, substs)
                         })
                         .unwrap_or_else(|| {
-                            let mut err = struct_span_err!(
-                                tcx.sess,
-                                span,
-                                E0026,
-                                "{} `{}` does not have a field named `{}`",
-                                kind_name,
-                                tcx.item_path_str(variant.did),
-                                field.name
-                            );
-                            err.span_label(span,
-                                           format!("{} `{}` does not have field `{}`",
-                                                   kind_name,
-                                                   tcx.item_path_str(variant.did),
-                                                   field.name));
-                            if tcx.sess.teach(&err.get_code().unwrap()) {
-                                err.note(
-                                    "This error indicates that a struct pattern attempted to \
-                                     extract a non-existent field from a struct. Struct fields \
-                                     are identified by the name used before the colon : so struct \
-                                     patterns should resemble the declaration of the struct type \
-                                     being matched.\n\n\
-                                     If you are using shorthand field patterns but want to refer \
-                                     to the struct field by a different name, you should rename \
-                                     it explicitly."
-                                );
-                            }
-                            err.emit();
-
+                            inexistent_fields.push((span, field.name));
                             tcx.types.err
                         })
                 }
@@ -963,6 +904,47 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
             self.check_pat_walk(&field.pat, field_ty, def_bm, true);
         }
 
+        if inexistent_fields.len() > 0 {
+            let (field_names, t, plural) = if inexistent_fields.len() == 1 {
+                (format!("a field named `{}`", inexistent_fields[0].1), "this", "")
+            } else {
+                (format!("fields named {}",
+                         inexistent_fields.iter()
+                            .map(|(_, name)| format!("`{}`", name))
+                            .collect::<Vec<String>>()
+                            .join(", ")), "these", "s")
+            };
+            let spans = inexistent_fields.iter().map(|(span, _)| *span).collect::<Vec<_>>();
+            let mut err = struct_span_err!(tcx.sess,
+                                           spans,
+                                           E0026,
+                                           "{} `{}` does not have {}",
+                                           kind_name,
+                                           tcx.item_path_str(variant.did),
+                                           field_names);
+            if let Some((span, _)) = inexistent_fields.last() {
+                err.span_label(*span,
+                               format!("{} `{}` does not have {} field{}",
+                                       kind_name,
+                                       tcx.item_path_str(variant.did),
+                                       t,
+                                       plural));
+            }
+            if tcx.sess.teach(&err.get_code().unwrap()) {
+                err.note(
+                    "This error indicates that a struct pattern attempted to \
+                     extract a non-existent field from a struct. Struct fields \
+                     are identified by the name used before the colon : so struct \
+                     patterns should resemble the declaration of the struct type \
+                     being matched.\n\n\
+                     If you are using shorthand field patterns but want to refer \
+                     to the struct field by a different name, you should rename \
+                     it explicitly."
+                );
+            }
+            err.emit();
+        }
+
         // Require `..` if struct has non_exhaustive attribute.
         if adt.is_struct() && adt.is_non_exhaustive() && !adt.did.is_local() && !etc {
             span_err!(tcx.sess, span, E0638,
@@ -979,13 +961,25 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                 tcx.sess.span_err(span, "`..` cannot be used in union patterns");
             }
         } else if !etc {
-            for field in variant.fields
+            let unmentioned_fields = variant.fields
                 .iter()
-                .filter(|field| !used_fields.contains_key(&field.name)) {
+                .map(|field| field.name)
+                .filter(|field| !used_fields.contains_key(&field))
+                .collect::<Vec<_>>();
+            if unmentioned_fields.len() > 0 {
+                let field_names = if unmentioned_fields.len() == 1 {
+                    format!("field `{}`", unmentioned_fields[0])
+                } else {
+                    format!("fields {}",
+                            unmentioned_fields.iter()
+                                .map(|name| format!("`{}`", name))
+                                .collect::<Vec<String>>()
+                                .join(", "))
+                };
                 let mut diag = struct_span_err!(tcx.sess, span, E0027,
-                                                "pattern does not mention field `{}`",
-                                                field.name);
-                diag.span_label(span, format!("missing field `{}`", field.name));
+                                                "pattern does not mention {}",
+                                                field_names);
+                diag.span_label(span, format!("missing {}", field_names));
                 if variant.ctor_kind == CtorKind::Fn {
                     diag.note("trying to match a tuple variant with a struct variant pattern");
                 }
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 634a7ee569917..e8b953d40d7a1 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -16,10 +16,11 @@ use rustc::traits::ObligationCause;
 
 use syntax::ast;
 use syntax::util::parser::PREC_POSTFIX;
-use syntax_pos::{self, Span};
+use syntax_pos::Span;
 use rustc::hir;
-use rustc::hir::print;
 use rustc::hir::def::Def;
+use rustc::hir::map::NodeItem;
+use rustc::hir::{Item, ItemConst, print};
 use rustc::ty::{self, Ty, AssociatedItem};
 use errors::{DiagnosticBuilder, CodeMapper};
 
@@ -139,7 +140,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         if let Some((msg, suggestion)) = self.check_ref(expr, checked_ty, expected) {
             err.span_suggestion(expr.span, msg, suggestion);
         } else if !self.check_for_cast(&mut err, expr, expr_ty, expected) {
-            let methods = self.get_conversion_methods(expected, checked_ty);
+            let methods = self.get_conversion_methods(expr.span, expected, checked_ty);
             if let Ok(expr_text) = self.tcx.sess.codemap().span_to_snippet(expr.span) {
                 let suggestions = iter::repeat(expr_text).zip(methods.iter())
                     .map(|(receiver, method)| format!("{}.{}()", receiver, method.name))
@@ -154,9 +155,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         (expected, Some(err))
     }
 
-    fn get_conversion_methods(&self, expected: Ty<'tcx>, checked_ty: Ty<'tcx>)
+    fn get_conversion_methods(&self, span: Span, expected: Ty<'tcx>, checked_ty: Ty<'tcx>)
                               -> Vec<AssociatedItem> {
-        let mut methods = self.probe_for_return_type(syntax_pos::DUMMY_SP,
+        let mut methods = self.probe_for_return_type(span,
                                                      probe::Mode::MethodCall,
                                                      expected,
                                                      checked_ty,
@@ -318,6 +319,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                       checked_ty: Ty<'tcx>,
                       expected_ty: Ty<'tcx>)
                       -> bool {
+        let parent_id = self.tcx.hir.get_parent_node(expr.id);
+        match self.tcx.hir.find(parent_id) {
+            Some(parent) => {
+                // Shouldn't suggest `.into()` on `const`s.
+                if let NodeItem(Item { node: ItemConst(_, _), .. }) = parent {
+                    // FIXME(estebank): modify once we decide to suggest `as` casts
+                    return false;
+                }
+            }
+            None => {}
+        };
+
         let will_truncate = "will truncate the source value";
         let depending_on_isize = "will truncate or zero-extend depending on the bit width of \
                                   `isize`";
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index 596381d7ea676..d508b6df924c2 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -16,7 +16,7 @@ use rustc::infer::outlives::env::OutlivesEnvironment;
 use rustc::middle::region;
 use rustc::ty::subst::{Subst, Substs, UnpackedKind};
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::traits::{self, ObligationCause};
+use rustc::traits::{ObligationCause, TraitEngine};
 use util::common::ErrorReported;
 
 use syntax::ast;
@@ -84,7 +84,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
     tcx.infer_ctxt().enter(|ref infcx| {
         let impl_param_env = tcx.param_env(self_type_did);
         let tcx = infcx.tcx;
-        let mut fulfillment_cx = traits::FulfillmentContext::new();
+        let mut fulfillment_cx = TraitEngine::new(tcx);
 
         let named_type = tcx.type_of(self_type_did);
 
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 99707a4a3c0e5..377e3a891840f 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -283,7 +283,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 (1, vec![param(0), param(0)],
                 tcx.intern_tup(&[param(0), tcx.types.bool])),
 
-            "unchecked_div" | "unchecked_rem" =>
+            "unchecked_div" | "unchecked_rem" | "exact_div" =>
                 (1, vec![param(0), param(0)], param(0)),
             "unchecked_shl" | "unchecked_shr" =>
                 (1, vec![param(0), param(0)], param(0)),
@@ -355,12 +355,14 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
         "simd_add" | "simd_sub" | "simd_mul" | "simd_rem" |
         "simd_div" | "simd_shl" | "simd_shr" |
-        "simd_and" | "simd_or" | "simd_xor" => {
+        "simd_and" | "simd_or" | "simd_xor" |
+        "simd_fmin" | "simd_fmax" => {
             (1, vec![param(0), param(0)], param(0))
         }
         "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
         "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)),
         "simd_cast" => (2, vec![param(0)], param(1)),
+        "simd_select" => (2, vec![param(0), param(1), param(1)], param(1)),
         "simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool),
         "simd_reduce_add_ordered" | "simd_reduce_mul_ordered"
             => (2, vec![param(0), param(1)], param(1)),
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 1664f46464d15..54f41e65d06a0 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -171,7 +171,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                         .unwrap().insert(import_def_id);
         }
 
-        self.tcx.check_stability(pick.item.def_id, call_expr.id, span);
+        self.tcx.check_stability(pick.item.def_id, Some(call_expr.id), span);
 
         let result = self.confirm_method(span,
                                          self_expr,
@@ -371,7 +371,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         }
 
         let def = pick.item.def();
-        self.tcx.check_stability(def.def_id(), expr_id, span);
+        self.tcx.check_stability(def.def_id(), Some(expr_id), span);
 
         Ok(def)
     }
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 4d344eb279903..136eb91e2abe6 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -23,9 +23,10 @@ use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TraitRef, TypeFoldable};
 use rustc::infer::type_variable::TypeVariableOrigin;
 use rustc::util::nodemap::FxHashSet;
 use rustc::infer::{self, InferOk};
+use rustc::middle::stability;
 use syntax::ast;
 use syntax::util::lev_distance::{lev_distance, find_best_match_for_name};
-use syntax_pos::Span;
+use syntax_pos::{Span, symbol::Symbol};
 use rustc::hir;
 use rustc::lint;
 use std::mem;
@@ -38,6 +39,7 @@ pub use self::PickKind::*;
 
 /// Boolean flag used to indicate if this search is for a suggestion
 /// or not.  If true, we can allow ambiguity and so forth.
+#[derive(Clone, Copy)]
 pub struct IsSuggestion(pub bool);
 
 struct ProbeContext<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
@@ -65,6 +67,8 @@ struct ProbeContext<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
     /// for error reporting
     unsatisfied_predicates: Vec<TraitRef<'tcx>>,
+
+    is_suggestion: IsSuggestion,
 }
 
 impl<'a, 'gcx, 'tcx> Deref for ProbeContext<'a, 'gcx, 'tcx> {
@@ -276,8 +280,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // this creates one big transaction so that all type variables etc
         // that we create during the probe process are removed later
         self.probe(|_| {
-            let mut probe_cx =
-                ProbeContext::new(self, span, mode, method_name, return_type, Rc::new(steps));
+            let mut probe_cx = ProbeContext::new(
+                self, span, mode, method_name, return_type, Rc::new(steps), is_suggestion,
+            );
 
             probe_cx.assemble_inherent_candidates();
             match scope {
@@ -326,7 +331,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     if reached_raw_pointer
                     && !self.tcx.features().arbitrary_self_types {
                         // this case used to be allowed by the compiler,
-                        // so we do a future-compat lint here for the 2015 epoch
+                        // so we do a future-compat lint here for the 2015 edition
                         // (see https://github.com/rust-lang/rust/issues/46906)
                         if self.tcx.sess.rust_2018() {
                           span_err!(self.tcx.sess, span, E0908,
@@ -378,7 +383,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
            mode: Mode,
            method_name: Option<ast::Name>,
            return_type: Option<Ty<'tcx>>,
-           steps: Rc<Vec<CandidateStep<'tcx>>>)
+           steps: Rc<Vec<CandidateStep<'tcx>>>,
+           is_suggestion: IsSuggestion)
            -> ProbeContext<'a, 'gcx, 'tcx> {
         ProbeContext {
             fcx,
@@ -394,6 +400,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
             allow_similar_names: false,
             private_candidate: None,
             unsatisfied_predicates: Vec::new(),
+            is_suggestion,
         }
     }
 
@@ -937,30 +944,57 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
         debug!("pick_method(self_ty={})", self.ty_to_string(self_ty));
 
         let mut possibly_unsatisfied_predicates = Vec::new();
-
-        debug!("searching inherent candidates");
-        if let Some(pick) = self.consider_candidates(self_ty,
-                                                     &self.inherent_candidates,
-                                                     &mut possibly_unsatisfied_predicates) {
-            return Some(pick);
+        let mut unstable_candidates = Vec::new();
+
+        for (kind, candidates) in &[
+            ("inherent", &self.inherent_candidates),
+            ("extension", &self.extension_candidates),
+        ] {
+            debug!("searching {} candidates", kind);
+            let res = self.consider_candidates(
+                self_ty,
+                candidates.iter(),
+                &mut possibly_unsatisfied_predicates,
+                Some(&mut unstable_candidates),
+            );
+            if let Some(pick) = res {
+                if !self.is_suggestion.0 && !unstable_candidates.is_empty() {
+                    if let Ok(p) = &pick {
+                        // Emit a lint if there are unstable candidates alongside the stable ones.
+                        //
+                        // We suppress warning if we're picking the method only because it is a
+                        // suggestion.
+                        self.emit_unstable_name_collision_hint(p, &unstable_candidates);
+                    }
+                }
+                return Some(pick);
+            }
         }
 
-        debug!("searching extension candidates");
-        let res = self.consider_candidates(self_ty,
-                                           &self.extension_candidates,
-                                           &mut possibly_unsatisfied_predicates);
-        if let None = res {
+        debug!("searching unstable candidates");
+        let res = self.consider_candidates(
+            self_ty,
+            unstable_candidates.into_iter().map(|(c, _)| c),
+            &mut possibly_unsatisfied_predicates,
+            None,
+        );
+        if res.is_none() {
             self.unsatisfied_predicates.extend(possibly_unsatisfied_predicates);
         }
         res
     }
 
-    fn consider_candidates(&self,
-                           self_ty: Ty<'tcx>,
-                           probes: &[Candidate<'tcx>],
-                           possibly_unsatisfied_predicates: &mut Vec<TraitRef<'tcx>>)
-                           -> Option<PickResult<'tcx>> {
-        let mut applicable_candidates: Vec<_> = probes.iter()
+    fn consider_candidates<'b, ProbesIter>(
+        &self,
+        self_ty: Ty<'tcx>,
+        probes: ProbesIter,
+        possibly_unsatisfied_predicates: &mut Vec<TraitRef<'tcx>>,
+        unstable_candidates: Option<&mut Vec<(&'b Candidate<'tcx>, Symbol)>>,
+    ) -> Option<PickResult<'tcx>>
+    where
+        ProbesIter: Iterator<Item = &'b Candidate<'tcx>> + Clone,
+    {
+        let mut applicable_candidates: Vec<_> = probes.clone()
             .map(|probe| {
                 (probe, self.consider_probe(self_ty, probe, possibly_unsatisfied_predicates))
             })
@@ -975,8 +1009,20 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
             }
         }
 
+        if let Some(uc) = unstable_candidates {
+            applicable_candidates.retain(|&(p, _)| {
+                if let stability::EvalResult::Deny { feature, .. } =
+                    self.tcx.eval_stability(p.item.def_id, None, self.span)
+                {
+                    uc.push((p, feature));
+                    return false;
+                }
+                true
+            });
+        }
+
         if applicable_candidates.len() > 1 {
-            let sources = probes.iter()
+            let sources = probes
                 .map(|p| self.candidate_source(p, self_ty))
                 .collect();
             return Some(Err(MethodError::Ambiguity(sources)));
@@ -991,6 +1037,39 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
         })
     }
 
+    fn emit_unstable_name_collision_hint(
+        &self,
+        stable_pick: &Pick,
+        unstable_candidates: &[(&Candidate<'tcx>, Symbol)],
+    ) {
+        let mut diag = self.tcx.struct_span_lint_node(
+            lint::builtin::UNSTABLE_NAME_COLLISION,
+            self.fcx.body_id,
+            self.span,
+            "a method with this name may be added to the standard library in the future",
+        );
+
+        // FIXME: This should be a `span_suggestion` instead of `help`. However `self.span` only
+        // highlights the method name, so we can't use it. Also consider reusing the code from
+        // `report_method_error()`.
+        diag.help(&format!(
+            "call with fully qualified syntax `{}(...)` to keep using the current method",
+            self.tcx.item_path_str(stable_pick.item.def_id),
+        ));
+
+        if ::rustc::session::config::nightly_options::is_nightly_build() {
+            for (candidate, feature) in unstable_candidates {
+                diag.note(&format!(
+                    "add #![feature({})] to the crate attributes to enable `{}`",
+                    feature,
+                    self.tcx.item_path_str(candidate.item.def_id),
+                ));
+            }
+        }
+
+        diag.emit();
+    }
+
     fn select_trait_candidate(&self, trait_ref: ty::TraitRef<'tcx>)
                               -> traits::SelectionResult<'tcx, traits::Selection<'tcx>>
     {
@@ -1190,7 +1269,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
         let steps = self.steps.clone();
         self.probe(|_| {
             let mut pcx = ProbeContext::new(self.fcx, self.span, self.mode, self.method_name,
-                                            self.return_type, steps);
+                                            self.return_type, steps, IsSuggestion(true));
             pcx.allow_similar_names = true;
             pcx.assemble_inherent_candidates();
             pcx.assemble_extension_candidates_for_traits_in_scope(ast::DUMMY_NODE_ID)?;
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 5c20490f82303..06bec8f6ff659 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -22,12 +22,14 @@ use rustc::traits::{Obligation, SelectionContext};
 use util::nodemap::FxHashSet;
 
 use syntax::ast;
+use syntax::util::lev_distance::find_best_match_for_name;
 use errors::DiagnosticBuilder;
 use syntax_pos::Span;
 
 use rustc::hir;
 use rustc::hir::print;
 use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::ty::TyAdt;
 
 use std::cell;
 use std::cmp::Ordering;
@@ -179,9 +181,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 let actual = self.resolve_type_vars_if_possible(&rcvr_ty);
                 let ty_string = self.ty_to_string(actual);
                 let is_method = mode == Mode::MethodCall;
+                let mut suggestion = None;
                 let type_str = if is_method {
                     "method"
                 } else if actual.is_enum() {
+                    if let TyAdt(ref adt_def, _) = actual.sty {
+                        let names = adt_def.variants.iter().map(|s| &s.name);
+                        suggestion = find_best_match_for_name(names,
+                                                              &item_name.as_str(),
+                                                              None);
+                    }
                     "variant"
                 } else {
                     match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
@@ -256,7 +265,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         err.emit();
                         return;
                     } else {
-                        struct_span_err!(
+                        let mut err = struct_span_err!(
                             tcx.sess,
                             span,
                             E0599,
@@ -264,7 +273,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             type_str,
                             item_name,
                             ty_string
-                        )
+                        );
+                        if let Some(suggestion) = suggestion {
+                            err.note(&format!("did you mean `{}::{}`?", type_str, suggestion));
+                        }
+                        err
                     }
                 } else {
                     tcx.sess.diagnostic().struct_dummy()
@@ -767,7 +780,7 @@ impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, '
                     // don't suggest placing a use before the prelude
                     // import or other generated ones
                     if item.span.ctxt().outer().expn_info().is_none() {
-                        self.span = Some(item.span.with_hi(item.span.lo()));
+                        self.span = Some(item.span.shrink_to_lo());
                         self.found_use = true;
                         return;
                     }
@@ -779,12 +792,12 @@ impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, '
                     if item.span.ctxt().outer().expn_info().is_none() {
                         // don't insert between attributes and an item
                         if item.attrs.is_empty() {
-                            self.span = Some(item.span.with_hi(item.span.lo()));
+                            self.span = Some(item.span.shrink_to_lo());
                         } else {
                             // find the first attribute on the item
                             for attr in &item.attrs {
                                 if self.span.map_or(true, |span| attr.span < span) {
-                                    self.span = Some(attr.span.with_hi(attr.span.lo()));
+                                    self.span = Some(attr.span.shrink_to_lo());
                                 }
                             }
                         }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index dc9455487ede7..0f0f59c28f825 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -95,7 +95,7 @@ use rustc::infer::type_variable::{TypeVariableOrigin};
 use rustc::middle::region;
 use rustc::mir::interpret::{GlobalId};
 use rustc::ty::subst::{Kind, Subst, Substs};
-use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
+use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
 use rustc::ty::{self, Ty, TyCtxt, Visibility, ToPredicate};
 use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::fold::TypeFoldable;
@@ -195,7 +195,7 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
 
     locals: RefCell<NodeMap<Ty<'tcx>>>,
 
-    fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
+    fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
 
     // When we process a call like `c()` where `c` is a closure type,
     // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
@@ -634,7 +634,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
                 maybe_tables: infcx.in_progress_tables,
             },
             infcx,
-            fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
+            fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
             locals: RefCell::new(NodeMap()),
             deferred_call_resolutions: RefCell::new(DefIdMap()),
             deferred_cast_checks: RefCell::new(Vec::new()),
@@ -718,6 +718,18 @@ fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum
     })?)
 }
 
+fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
+    wfcheck::check_item_well_formed(tcx, def_id);
+}
+
+fn check_trait_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
+    wfcheck::check_trait_item(tcx, def_id);
+}
+
+fn check_impl_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
+    wfcheck::check_impl_item(tcx, def_id);
+}
+
 pub fn provide(providers: &mut Providers) {
     *providers = Providers {
         typeck_item_bodies,
@@ -725,6 +737,9 @@ pub fn provide(providers: &mut Providers) {
         has_typeck_tables,
         adt_destructor,
         used_trait_imports,
+        check_item_well_formed,
+        check_trait_item_well_formed,
+        check_impl_item_well_formed,
         ..*providers
     };
 }
@@ -945,10 +960,19 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
     // Add explicitly-declared locals.
     fn visit_local(&mut self, local: &'gcx hir::Local) {
         let o_ty = match local.ty {
-            Some(ref ty) => Some(self.fcx.to_ty(&ty)),
-            None => None
+            Some(ref ty) => {
+                let o_ty = self.fcx.to_ty(&ty);
+
+                let (c_ty, _orig_values) = self.fcx.inh.infcx.canonicalize_response(&o_ty);
+                debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty);
+                self.fcx.tables.borrow_mut().user_provided_tys_mut().insert(ty.hir_id, c_ty);
+
+                Some(o_ty)
+            },
+            None => None,
         };
         self.assign(local.span, local.id, o_ty);
+
         debug!("Local variable {:?} is assigned type {}",
                local.pat,
                self.fcx.ty_to_string(
@@ -1106,25 +1130,23 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     }
     fcx.demand_suptype(span, ret_ty, actual_return_ty);
 
-    if fcx.tcx.features().termination_trait {
-        // If the termination trait language item is activated, check that the main return type
-        // implements the termination trait.
-        if let Some(term_id) = fcx.tcx.lang_items().termination() {
-            if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() {
-                if id == fn_id {
-                    match fcx.sess().entry_type.get() {
-                        Some(config::EntryMain) => {
-                            let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty)));
-                            let trait_ref = ty::TraitRef::new(term_id, substs);
-                            let cause = traits::ObligationCause::new(
-                                span, fn_id, ObligationCauseCode::MainFunctionType);
-
-                            inherited.register_predicate(
-                                traits::Obligation::new(
-                                    cause, param_env, trait_ref.to_predicate()));
-                        },
-                        _ => {},
-                    }
+    // Check that the main return type implements the termination trait.
+    if let Some(term_id) = fcx.tcx.lang_items().termination() {
+        if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() {
+            if id == fn_id {
+                match fcx.sess().entry_type.get() {
+                    Some(config::EntryMain) => {
+                        let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty)));
+                        let trait_ref = ty::TraitRef::new(term_id, substs);
+                        let return_ty_span = decl.output.span();
+                        let cause = traits::ObligationCause::new(
+                            return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
+
+                        inherited.register_predicate(
+                            traits::Obligation::new(
+                                cause, param_env, trait_ref.to_predicate()));
+                    },
+                    _ => {},
                 }
             }
         }
@@ -1167,9 +1189,15 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item
     let _indenter = indenter();
     match it.node {
       // Consts can play a role in type-checking, so they are included here.
-      hir::ItemStatic(..) |
+      hir::ItemStatic(..) => {
+        tcx.typeck_tables_of(tcx.hir.local_def_id(it.id));
+      }
       hir::ItemConst(..) => {
         tcx.typeck_tables_of(tcx.hir.local_def_id(it.id));
+        if it.attrs.iter().any(|a| a.check_name("wasm_custom_section")) {
+            let def_id = tcx.hir.local_def_id(it.id);
+            check_const_is_u8_array(tcx, def_id, it.span);
+        }
       }
       hir::ItemEnum(ref enum_definition, _) => {
         check_enum(tcx,
@@ -1241,6 +1269,21 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item
     }
 }
 
+fn check_const_is_u8_array<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                     def_id: DefId,
+                                     span: Span) {
+    match tcx.type_of(def_id).sty {
+        ty::TyArray(t, _) => {
+            match t.sty {
+                ty::TyUint(ast::UintTy::U8) => return,
+                _ => {}
+            }
+        }
+        _ => {}
+    }
+    tcx.sess.span_err(span, "must be an array of bytes like `[u8; N]`");
+}
+
 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                     trait_def_id: DefId,
                                     item: &hir::Item) {
@@ -2520,7 +2563,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             if sugg_unit {
                 let sugg_span = sess.codemap().end_point(expr_sp);
                 // remove closing `)` from the span
-                let sugg_span = sugg_span.with_hi(sugg_span.lo());
+                let sugg_span = sugg_span.shrink_to_lo();
                 err.span_suggestion(
                     sugg_span,
                     "expected the unit value `()`; create it with empty parentheses",
@@ -2867,9 +2910,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 // is polymorphic) and the expected return type.
                 // No argument expectations are produced if unification fails.
                 let origin = self.misc(call_span);
-                let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret);
+                let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
 
-                // FIXME(#15760) can't use try! here, FromError doesn't default
+                // FIXME(#27336) can't use ? here, Try::from_error doesn't default
                 // to identity so the resulting type is not constrained.
                 match ures {
                     Ok(ok) => {
@@ -2877,19 +2920,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         // we can.  We don't care if some things turn
                         // out unconstrained or ambiguous, as we're
                         // just trying to get hints here.
-                        let result = self.save_and_restore_in_snapshot_flag(|_| {
-                            let mut fulfill = FulfillmentContext::new();
-                            let ok = ok; // FIXME(#30046)
+                        self.save_and_restore_in_snapshot_flag(|_| {
+                            let mut fulfill = TraitEngine::new(self.tcx);
                             for obligation in ok.obligations {
                                 fulfill.register_predicate_obligation(self, obligation);
                             }
                             fulfill.select_where_possible(self)
-                        });
-
-                        match result {
-                            Ok(()) => { }
-                            Err(_) => return Err(()),
-                        }
+                        }).map_err(|_| ())?;
                     }
                     Err(_) => return Err(()),
                 }
@@ -3048,7 +3085,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             self.apply_adjustments(base, adjustments);
                             autoderef.finalize();
 
-                            self.tcx.check_stability(field.did, expr.id, expr.span);
+                            self.tcx.check_stability(field.did, Some(expr.id), expr.span);
 
                             return field_ty;
                         }
@@ -3189,7 +3226,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
                         let field_ty = self.field_ty(expr.span, field, substs);
                         if field.vis.is_accessible_from(def_scope, self.tcx) {
-                            self.tcx.check_stability(field.did, expr.id, expr.span);
+                            self.tcx.check_stability(field.did, Some(expr.id), expr.span);
                             Some(field_ty)
                         } else {
                             private_candidate = Some((base_def.did, field_ty));
@@ -3334,7 +3371,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 // struct-like enums (yet...), but it's definitely not
                 // a bug to have construct one.
                 if adt_kind != ty::AdtKind::Enum {
-                    tcx.check_stability(v_field.did, expr_id, field.span);
+                    tcx.check_stability(v_field.did, Some(expr_id), field.span);
                 }
 
                 self.field_ty(field.span, v_field, substs)
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index ab148afafbe09..4fc3344dab2a9 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -217,7 +217,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             .upvar_tys(closure_def_id, self.tcx)
             .zip(final_upvar_tys)
         {
-            self.demand_eqtype(span, final_upvar_ty, upvar_ty);
+            self.demand_suptype(span, upvar_ty, final_upvar_ty);
         }
 
         // If we are also inferred the closure kind here,
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index b94af0a1e0081..406ff9463a03c 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -26,17 +26,11 @@ use errors::{DiagnosticBuilder, DiagnosticId};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir;
 
-pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    code: ObligationCauseCode<'tcx>,
-}
-
 /// Helper type of a temporary returned by .for_item(...).
 /// Necessary because we can't write the following bound:
 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>).
 struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>,
-    code: ObligationCauseCode<'gcx>,
     id: ast::NodeId,
     span: Span,
     param_env: ty::ParamEnv<'tcx>,
@@ -45,585 +39,597 @@ struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
 impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
     fn with_fcx<F>(&'tcx mut self, f: F) where
         F: for<'b> FnOnce(&FnCtxt<'b, 'gcx, 'tcx>,
-                          &mut CheckTypeWellFormedVisitor<'b, 'gcx>) -> Vec<Ty<'tcx>>
+                         TyCtxt<'b, 'gcx, 'gcx>) -> Vec<Ty<'tcx>>
     {
-        let code = self.code.clone();
         let id = self.id;
         let span = self.span;
         let param_env = self.param_env;
         self.inherited.enter(|inh| {
             let fcx = FnCtxt::new(&inh, param_env, id);
-            let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor {
-                tcx: fcx.tcx.global_tcx(),
-                code,
-            });
+            let wf_tys = f(&fcx, fcx.tcx.global_tcx());
             fcx.select_all_obligations_or_error();
             fcx.regionck_item(id, span, &wf_tys);
         });
     }
 }
 
-impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
-    pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>)
-               -> CheckTypeWellFormedVisitor<'a, 'gcx> {
-        CheckTypeWellFormedVisitor {
-            tcx,
-            code: ObligationCauseCode::MiscObligation
-        }
-    }
-
-    /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
-    /// well-formed, meaning that they do not require any constraints not declared in the struct
-    /// definition itself. For example, this definition would be illegal:
-    ///
-    ///     struct Ref<'a, T> { x: &'a T }
-    ///
-    /// because the type did not declare that `T:'a`.
-    ///
-    /// We do this check as a pre-pass before checking fn bodies because if these constraints are
-    /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
-    /// the types first.
-    fn check_item_well_formed(&mut self, item: &hir::Item) {
-        let tcx = self.tcx;
-        debug!("check_item_well_formed(it.id={}, it.name={})",
-               item.id,
-               tcx.item_path_str(tcx.hir.local_def_id(item.id)));
-
-        match item.node {
-            // Right now we check that every default trait implementation
-            // has an implementation of itself. Basically, a case like:
-            //
-            // `impl Trait for T {}`
-            //
-            // has a requirement of `T: Trait` which was required for default
-            // method implementations. Although this could be improved now that
-            // there's a better infrastructure in place for this, it's being left
-            // for a follow-up work.
-            //
-            // Since there's such a requirement, we need to check *just* positive
-            // implementations, otherwise things like:
-            //
-            // impl !Send for T {}
-            //
-            // won't be allowed unless there's an *explicit* implementation of `Send`
-            // for `T`
-            hir::ItemImpl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => {
-                let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id))
-                                 .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
-                if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) {
-                    tcx.sess.span_err(item.span, "impls of auto traits cannot be default");
-                }
-                if polarity == hir::ImplPolarity::Positive {
-                    self.check_impl(item, self_ty, trait_ref);
-                } else {
-                    // FIXME(#27579) what amount of WF checking do we need for neg impls?
-                    if trait_ref.is_some() && !is_auto {
-                        span_err!(tcx.sess, item.span, E0192,
-                                  "negative impls are only allowed for \
-                                   auto traits (e.g., `Send` and `Sync`)")
-                    }
-                }
-            }
-            hir::ItemFn(..) => {
-                self.check_item_fn(item);
-            }
-            hir::ItemStatic(..) => {
-                self.check_item_type(item);
+/// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
+/// well-formed, meaning that they do not require any constraints not declared in the struct
+/// definition itself. For example, this definition would be illegal:
+///
+///     struct Ref<'a, T> { x: &'a T }
+///
+/// because the type did not declare that `T:'a`.
+///
+/// We do this check as a pre-pass before checking fn bodies because if these constraints are
+/// not included it frequently leads to confusing errors in fn bodies. So it's better to check
+/// the types first.
+pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
+    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+    let item = tcx.hir.expect_item(node_id);
+
+    debug!("check_item_well_formed(it.id={}, it.name={})",
+            item.id,
+            tcx.item_path_str(def_id));
+
+    match item.node {
+        // Right now we check that every default trait implementation
+        // has an implementation of itself. Basically, a case like:
+        //
+        // `impl Trait for T {}`
+        //
+        // has a requirement of `T: Trait` which was required for default
+        // method implementations. Although this could be improved now that
+        // there's a better infrastructure in place for this, it's being left
+        // for a follow-up work.
+        //
+        // Since there's such a requirement, we need to check *just* positive
+        // implementations, otherwise things like:
+        //
+        // impl !Send for T {}
+        //
+        // won't be allowed unless there's an *explicit* implementation of `Send`
+        // for `T`
+        hir::ItemImpl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => {
+            let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id))
+                                .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
+            if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) {
+                tcx.sess.span_err(item.span, "impls of auto traits cannot be default");
             }
-            hir::ItemConst(..) => {
-                self.check_item_type(item);
+            if polarity == hir::ImplPolarity::Positive {
+                check_impl(tcx, item, self_ty, trait_ref);
+            } else {
+                // FIXME(#27579) what amount of WF checking do we need for neg impls?
+                if trait_ref.is_some() && !is_auto {
+                    span_err!(tcx.sess, item.span, E0192,
+                                "negative impls are only allowed for \
+                                auto traits (e.g., `Send` and `Sync`)")
+                }
             }
-            hir::ItemStruct(ref struct_def, ref ast_generics) => {
-                self.check_type_defn(item, false, |fcx| {
-                    vec![fcx.non_enum_variant(struct_def)]
-                });
+        }
+        hir::ItemFn(..) => {
+            check_item_fn(tcx, item);
+        }
+        hir::ItemStatic(..) => {
+            check_item_type(tcx, item);
+        }
+        hir::ItemConst(..) => {
+            check_item_type(tcx, item);
+        }
+        hir::ItemStruct(ref struct_def, ref ast_generics) => {
+            check_type_defn(tcx, item, false, |fcx| {
+                vec![fcx.non_enum_variant(struct_def)]
+            });
 
-                self.check_variances_for_type_defn(item, ast_generics);
-            }
-            hir::ItemUnion(ref struct_def, ref ast_generics) => {
-                self.check_type_defn(item, true, |fcx| {
-                    vec![fcx.non_enum_variant(struct_def)]
-                });
+            check_variances_for_type_defn(tcx, item, ast_generics);
+        }
+        hir::ItemUnion(ref struct_def, ref ast_generics) => {
+            check_type_defn(tcx, item, true, |fcx| {
+                vec![fcx.non_enum_variant(struct_def)]
+            });
 
-                self.check_variances_for_type_defn(item, ast_generics);
-            }
-            hir::ItemEnum(ref enum_def, ref ast_generics) => {
-                self.check_type_defn(item, true, |fcx| {
-                    fcx.enum_variants(enum_def)
-                });
+            check_variances_for_type_defn(tcx, item, ast_generics);
+        }
+        hir::ItemEnum(ref enum_def, ref ast_generics) => {
+            check_type_defn(tcx, item, true, |fcx| {
+                fcx.enum_variants(enum_def)
+            });
 
-                self.check_variances_for_type_defn(item, ast_generics);
-            }
-            hir::ItemTrait(..) => {
-                self.check_trait(item);
-            }
-            _ => {}
+            check_variances_for_type_defn(tcx, item, ast_generics);
         }
+        hir::ItemTrait(..) => {
+            check_trait(tcx, item);
+        }
+        _ => {}
     }
+}
 
-    fn check_associated_item(&mut self,
-                             item_id: ast::NodeId,
-                             span: Span,
-                             sig_if_method: Option<&hir::MethodSig>) {
-        let code = self.code.clone();
-        self.for_id(item_id, span).with_fcx(|fcx, this| {
-            let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id));
-
-            let (mut implied_bounds, self_ty) = match item.container {
-                ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()),
-                ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span),
-                                              fcx.tcx.type_of(def_id))
-            };
+pub fn check_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
+    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+    let trait_item = tcx.hir.expect_trait_item(node_id);
+
+    let method_sig = match trait_item.node {
+        hir::TraitItemKind::Method(ref sig, _) => Some(sig),
+        _ => None
+    };
+    check_associated_item(tcx, trait_item.id, trait_item.span, method_sig);
+}
+
+pub fn check_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
+    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+    let impl_item = tcx.hir.expect_impl_item(node_id);
+
+    let method_sig = match impl_item.node {
+        hir::ImplItemKind::Method(ref sig, _) => Some(sig),
+        _ => None
+    };
+    check_associated_item(tcx, impl_item.id, impl_item.span, method_sig);
+}
+
+fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                            item_id: ast::NodeId,
+                            span: Span,
+                            sig_if_method: Option<&hir::MethodSig>) {
+    let code = ObligationCauseCode::MiscObligation;
+    for_id(tcx, item_id, span).with_fcx(|fcx, tcx| {
+        let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id));
+
+        let (mut implied_bounds, self_ty) = match item.container {
+            ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()),
+            ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span),
+                                            fcx.tcx.type_of(def_id))
+        };
 
-            match item.kind {
-                ty::AssociatedKind::Const => {
+        match item.kind {
+            ty::AssociatedKind::Const => {
+                let ty = fcx.tcx.type_of(item.def_id);
+                let ty = fcx.normalize_associated_types_in(span, &ty);
+                fcx.register_wf_obligation(ty, span, code.clone());
+            }
+            ty::AssociatedKind::Method => {
+                reject_shadowing_type_parameters(fcx.tcx, item.def_id);
+                let sig = fcx.tcx.fn_sig(item.def_id);
+                let sig = fcx.normalize_associated_types_in(span, &sig);
+                check_fn_or_method(tcx, fcx, span, sig,
+                                        item.def_id, &mut implied_bounds);
+                let sig_if_method = sig_if_method.expect("bad signature for method");
+                check_method_receiver(fcx, sig_if_method, &item, self_ty);
+            }
+            ty::AssociatedKind::Type => {
+                if item.defaultness.has_value() {
                     let ty = fcx.tcx.type_of(item.def_id);
                     let ty = fcx.normalize_associated_types_in(span, &ty);
                     fcx.register_wf_obligation(ty, span, code.clone());
                 }
-                ty::AssociatedKind::Method => {
-                    reject_shadowing_type_parameters(fcx.tcx, item.def_id);
-                    let sig = fcx.tcx.fn_sig(item.def_id);
-                    let sig = fcx.normalize_associated_types_in(span, &sig);
-                    this.check_fn_or_method(fcx, span, sig,
-                                            item.def_id, &mut implied_bounds);
-                    let sig_if_method = sig_if_method.expect("bad signature for method");
-                    this.check_method_receiver(fcx, sig_if_method, &item, self_ty);
-                }
-                ty::AssociatedKind::Type => {
-                    if item.defaultness.has_value() {
-                        let ty = fcx.tcx.type_of(item.def_id);
-                        let ty = fcx.normalize_associated_types_in(span, &ty);
-                        fcx.register_wf_obligation(ty, span, code.clone());
-                    }
-                }
             }
+        }
 
-            implied_bounds
-        })
-    }
-
-    fn for_item<'tcx>(&self, item: &hir::Item)
-                      -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
-        self.for_id(item.id, item.span)
-    }
+        implied_bounds
+    })
+}
 
-    fn for_id<'tcx>(&self, id: ast::NodeId, span: Span)
+fn for_item<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, item: &hir::Item)
                     -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
-        let def_id = self.tcx.hir.local_def_id(id);
-        CheckWfFcxBuilder {
-            inherited: Inherited::build(self.tcx, def_id),
-            code: self.code.clone(),
-            id,
-            span,
-            param_env: self.tcx.param_env(def_id),
-        }
+    for_id(tcx, item.id, item.span)
+}
+
+fn for_id<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId, span: Span)
+                -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
+    let def_id = tcx.hir.local_def_id(id);
+    CheckWfFcxBuilder {
+        inherited: Inherited::build(tcx, def_id),
+        id,
+        span,
+        param_env: tcx.param_env(def_id),
     }
+}
 
-    /// In a type definition, we check that to ensure that the types of the fields are well-formed.
-    fn check_type_defn<F>(&mut self, item: &hir::Item, all_sized: bool, mut lookup_fields: F)
-        where F: for<'fcx, 'tcx> FnMut(&FnCtxt<'fcx, 'gcx, 'tcx>) -> Vec<AdtVariant<'tcx>>
-    {
-        self.for_item(item).with_fcx(|fcx, this| {
-            let variants = lookup_fields(fcx);
-            let def_id = fcx.tcx.hir.local_def_id(item.id);
-            let packed = fcx.tcx.adt_def(def_id).repr.packed();
-
-            for variant in &variants {
-                // For DST, or when drop needs to copy things around, all
-                // intermediate types must be sized.
-                let needs_drop_copy = || {
-                    packed && {
-                        let ty = variant.fields.last().unwrap().ty;
-                        let ty = fcx.tcx.erase_regions(&ty).lift_to_tcx(this.tcx)
-                            .unwrap_or_else(|| {
-                                span_bug!(item.span, "inference variables in {:?}", ty)
-                            });
-                        ty.needs_drop(this.tcx, this.tcx.param_env(def_id))
-                    }
-                };
-                let unsized_len = if
-                    all_sized ||
-                    variant.fields.is_empty() ||
-                    needs_drop_copy()
-                {
-                    0
-                } else {
-                    1
-                };
-                for field in &variant.fields[..variant.fields.len() - unsized_len] {
-                    fcx.register_bound(
-                        field.ty,
-                        fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
-                        traits::ObligationCause::new(field.span,
-                                                     fcx.body_id,
-                                                     traits::FieldSized(match item.node.adt_kind() {
-                                                        Some(i) => i,
-                                                        None => bug!(),
-                                                     })));
+/// In a type definition, we check that to ensure that the types of the fields are well-formed.
+fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                item: &hir::Item, all_sized: bool, mut lookup_fields: F)
+    where F: for<'fcx, 'gcx, 'tcx2> FnMut(&FnCtxt<'fcx, 'gcx, 'tcx2>) -> Vec<AdtVariant<'tcx2>>
+{
+    for_item(tcx, item).with_fcx(|fcx, fcx_tcx| {
+        let variants = lookup_fields(fcx);
+        let def_id = fcx.tcx.hir.local_def_id(item.id);
+        let packed = fcx.tcx.adt_def(def_id).repr.packed();
+
+        for variant in &variants {
+            // For DST, or when drop needs to copy things around, all
+            // intermediate types must be sized.
+            let needs_drop_copy = || {
+                packed && {
+                    let ty = variant.fields.last().unwrap().ty;
+                    let ty = fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx)
+                        .unwrap_or_else(|| {
+                            span_bug!(item.span, "inference variables in {:?}", ty)
+                        });
+                    ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id))
                 }
+            };
+            let unsized_len = if
+                all_sized ||
+                variant.fields.is_empty() ||
+                needs_drop_copy()
+            {
+                0
+            } else {
+                1
+            };
+            for field in &variant.fields[..variant.fields.len() - unsized_len] {
+                fcx.register_bound(
+                    field.ty,
+                    fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
+                    traits::ObligationCause::new(field.span,
+                                                    fcx.body_id,
+                                                    traits::FieldSized(match item.node.adt_kind() {
+                                                    Some(i) => i,
+                                                    None => bug!(),
+                                                    })));
+            }
 
-                // All field types must be well-formed.
-                for field in &variant.fields {
-                    fcx.register_wf_obligation(field.ty, field.span, this.code.clone())
-                }
+            // All field types must be well-formed.
+            for field in &variant.fields {
+                fcx.register_wf_obligation(field.ty, field.span,
+                    ObligationCauseCode::MiscObligation)
             }
+        }
 
-            self.check_where_clauses(fcx, item.span, def_id);
+        check_where_clauses(tcx, fcx, item.span, def_id);
 
-            vec![] // no implied bounds in a struct def'n
-        });
-    }
+        vec![] // no implied bounds in a struct def'n
+    });
+}
 
-    fn check_trait(&mut self, item: &hir::Item) {
-        let trait_def_id = self.tcx.hir.local_def_id(item.id);
-        self.for_item(item).with_fcx(|fcx, _| {
-            self.check_where_clauses(fcx, item.span, trait_def_id);
-            vec![]
-        });
-    }
+fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
+    let trait_def_id = tcx.hir.local_def_id(item.id);
+    for_item(tcx, item).with_fcx(|fcx, _| {
+        check_where_clauses(tcx, fcx, item.span, trait_def_id);
+        vec![]
+    });
+}
 
-    fn check_item_fn(&mut self, item: &hir::Item) {
-        self.for_item(item).with_fcx(|fcx, this| {
-            let def_id = fcx.tcx.hir.local_def_id(item.id);
-            let sig = fcx.tcx.fn_sig(def_id);
-            let sig = fcx.normalize_associated_types_in(item.span, &sig);
-            let mut implied_bounds = vec![];
-            this.check_fn_or_method(fcx, item.span, sig,
-                                    def_id, &mut implied_bounds);
-            implied_bounds
-        })
-    }
+fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
+    for_item(tcx, item).with_fcx(|fcx, tcx| {
+        let def_id = fcx.tcx.hir.local_def_id(item.id);
+        let sig = fcx.tcx.fn_sig(def_id);
+        let sig = fcx.normalize_associated_types_in(item.span, &sig);
+        let mut implied_bounds = vec![];
+        check_fn_or_method(tcx, fcx, item.span, sig,
+                                def_id, &mut implied_bounds);
+        implied_bounds
+    })
+}
 
-    fn check_item_type(&mut self,
-                       item: &hir::Item)
-    {
-        debug!("check_item_type: {:?}", item);
+fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                    item: &hir::Item)
+{
+    debug!("check_item_type: {:?}", item);
 
-        self.for_item(item).with_fcx(|fcx, this| {
-            let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id));
-            let item_ty = fcx.normalize_associated_types_in(item.span, &ty);
+    for_item(tcx, item).with_fcx(|fcx, _this| {
+        let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id));
+        let item_ty = fcx.normalize_associated_types_in(item.span, &ty);
 
-            fcx.register_wf_obligation(item_ty, item.span, this.code.clone());
+        fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation);
 
-            vec![] // no implied bounds in a const etc
-        });
-    }
+        vec![] // no implied bounds in a const etc
+    });
+}
 
-    fn check_impl(&mut self,
-                  item: &hir::Item,
-                  ast_self_ty: &hir::Ty,
-                  ast_trait_ref: &Option<hir::TraitRef>)
-    {
-        debug!("check_impl: {:?}", item);
-
-        self.for_item(item).with_fcx(|fcx, this| {
-            let item_def_id = fcx.tcx.hir.local_def_id(item.id);
-
-            match *ast_trait_ref {
-                Some(ref ast_trait_ref) => {
-                    let trait_ref = fcx.tcx.impl_trait_ref(item_def_id).unwrap();
-                    let trait_ref =
-                        fcx.normalize_associated_types_in(
-                            ast_trait_ref.path.span, &trait_ref);
-                    let obligations =
-                        ty::wf::trait_obligations(fcx,
-                                                  fcx.param_env,
-                                                  fcx.body_id,
-                                                  &trait_ref,
-                                                  ast_trait_ref.path.span);
-                    for obligation in obligations {
-                        fcx.register_predicate(obligation);
-                    }
-                }
-                None => {
-                    let self_ty = fcx.tcx.type_of(item_def_id);
-                    let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty);
-                    fcx.register_wf_obligation(self_ty, ast_self_ty.span, this.code.clone());
+fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                item: &hir::Item,
+                ast_self_ty: &hir::Ty,
+                ast_trait_ref: &Option<hir::TraitRef>)
+{
+    debug!("check_impl: {:?}", item);
+
+    for_item(tcx, item).with_fcx(|fcx, tcx| {
+        let item_def_id = fcx.tcx.hir.local_def_id(item.id);
+
+        match *ast_trait_ref {
+            Some(ref ast_trait_ref) => {
+                let trait_ref = fcx.tcx.impl_trait_ref(item_def_id).unwrap();
+                let trait_ref =
+                    fcx.normalize_associated_types_in(
+                        ast_trait_ref.path.span, &trait_ref);
+                let obligations =
+                    ty::wf::trait_obligations(fcx,
+                                                fcx.param_env,
+                                                fcx.body_id,
+                                                &trait_ref,
+                                                ast_trait_ref.path.span);
+                for obligation in obligations {
+                    fcx.register_predicate(obligation);
                 }
             }
+            None => {
+                let self_ty = fcx.tcx.type_of(item_def_id);
+                let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty);
+                fcx.register_wf_obligation(self_ty, ast_self_ty.span,
+                    ObligationCauseCode::MiscObligation);
+            }
+        }
 
-            this.check_where_clauses(fcx, item.span, item_def_id);
+        check_where_clauses(tcx, fcx, item.span, item_def_id);
 
-            fcx.impl_implied_bounds(item_def_id, item.span)
-        });
-    }
+        fcx.impl_implied_bounds(item_def_id, item.span)
+    });
+}
 
-    /// Checks where clauses and inline bounds that are declared on def_id.
-    fn check_where_clauses<'fcx, 'tcx>(&mut self,
-                                       fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
-                                       span: Span,
-                                       def_id: DefId) {
-        use ty::subst::Subst;
-        use rustc::ty::TypeFoldable;
-
-        let mut predicates = fcx.tcx.predicates_of(def_id);
-        let mut substituted_predicates = Vec::new();
-
-        let generics = self.tcx.generics_of(def_id);
-        let is_our_default = |def: &ty::TypeParameterDef|
-                                def.has_default && def.index >= generics.parent_count() as u32;
-
-        // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
-        // For example this forbids the declaration:
-        // struct Foo<T = Vec<[u32]>> { .. }
-        // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
-        for d in generics.types.iter().cloned().filter(is_our_default).map(|p| p.def_id) {
-            let ty = fcx.tcx.type_of(d);
-            // ignore dependent defaults -- that is, where the default of one type
-            // parameter includes another (e.g., <T, U = T>). In those cases, we can't
-            // be sure if it will error or not as user might always specify the other.
-            if !ty.needs_subst() {
-                fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), self.code.clone());
-            }
+/// Checks where clauses and inline bounds that are declared on def_id.
+fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
+                                    fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
+                                    span: Span,
+                                    def_id: DefId) {
+    use ty::subst::Subst;
+    use rustc::ty::TypeFoldable;
+
+    let mut predicates = fcx.tcx.predicates_of(def_id);
+    let mut substituted_predicates = Vec::new();
+
+    let generics = tcx.generics_of(def_id);
+    let is_our_default = |def: &ty::TypeParameterDef|
+                            def.has_default && def.index >= generics.parent_count() as u32;
+
+    // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
+    // For example this forbids the declaration:
+    // struct Foo<T = Vec<[u32]>> { .. }
+    // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
+    for d in generics.types.iter().cloned().filter(is_our_default).map(|p| p.def_id) {
+        let ty = fcx.tcx.type_of(d);
+        // ignore dependent defaults -- that is, where the default of one type
+        // parameter includes another (e.g., <T, U = T>). In those cases, we can't
+        // be sure if it will error or not as user might always specify the other.
+        if !ty.needs_subst() {
+            fcx.register_wf_obligation(ty, fcx.tcx.def_span(d),
+                ObligationCauseCode::MiscObligation);
         }
+    }
 
-        // Check that trait predicates are WF when params are substituted by their defaults.
-        // We don't want to overly constrain the predicates that may be written but we want to
-        // catch cases where a default my never be applied such as `struct Foo<T: Copy = String>`.
-        // Therefore we check if a predicate which contains a single type param
-        // with a concrete default is WF with that default substituted.
-        // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
-        //
-        // First we build the defaulted substitution.
-        let substs = ty::subst::Substs::for_item(fcx.tcx, def_id, |def, _| {
-                // All regions are identity.
-                fcx.tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data()))
-            }, |def, _| {
-                // If the param has a default,
-                if is_our_default(def) {
-                    let default_ty = fcx.tcx.type_of(def.def_id);
-                    // and it's not a dependent default
-                    if !default_ty.needs_subst() {
-                        // then substitute with the default.
-                        return default_ty;
-                    }
+    // Check that trait predicates are WF when params are substituted by their defaults.
+    // We don't want to overly constrain the predicates that may be written but we want to
+    // catch cases where a default my never be applied such as `struct Foo<T: Copy = String>`.
+    // Therefore we check if a predicate which contains a single type param
+    // with a concrete default is WF with that default substituted.
+    // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
+    //
+    // First we build the defaulted substitution.
+    let substs = ty::subst::Substs::for_item(fcx.tcx, def_id, |def, _| {
+            // All regions are identity.
+            fcx.tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data()))
+        }, |def, _| {
+            // If the param has a default,
+            if is_our_default(def) {
+                let default_ty = fcx.tcx.type_of(def.def_id);
+                // and it's not a dependent default
+                if !default_ty.needs_subst() {
+                    // then substitute with the default.
+                    return default_ty;
                 }
-                // Mark unwanted params as err.
-                fcx.tcx.types.err
-            });
-        // Now we build the substituted predicates.
-        for &pred in predicates.predicates.iter() {
-            struct CountParams { params: FxHashSet<u32> }
-            impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams {
-                fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
-                    match t.sty {
-                        ty::TyParam(p) => {
-                            self.params.insert(p.idx);
-                            t.super_visit_with(self)
-                        }
-                        _ => t.super_visit_with(self)
+            }
+            // Mark unwanted params as err.
+            fcx.tcx.types.err
+        });
+    // Now we build the substituted predicates.
+    for &pred in predicates.predicates.iter() {
+        struct CountParams { params: FxHashSet<u32> }
+        impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams {
+            fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
+                match t.sty {
+                    ty::TyParam(p) => {
+                        self.params.insert(p.idx);
+                        t.super_visit_with(self)
                     }
+                    _ => t.super_visit_with(self)
                 }
             }
-            let mut param_count = CountParams { params: FxHashSet() };
-            pred.visit_with(&mut param_count);
-            let substituted_pred = pred.subst(fcx.tcx, substs);
-            // Don't check non-defaulted params, dependent defaults or preds with multiple params.
-            if substituted_pred.references_error() || param_count.params.len() > 1 {
-                continue;
-            }
-            // Avoid duplication of predicates that contain no parameters, for example.
-            if !predicates.predicates.contains(&substituted_pred) {
-                substituted_predicates.push(substituted_pred);
-            }
         }
-
-        predicates.predicates.extend(substituted_predicates);
-        let predicates = predicates.instantiate_identity(fcx.tcx);
-        let predicates = fcx.normalize_associated_types_in(span, &predicates);
-
-        let obligations =
-            predicates.predicates
-                      .iter()
-                      .flat_map(|p| ty::wf::predicate_obligations(fcx,
-                                                                  fcx.param_env,
-                                                                  fcx.body_id,
-                                                                  p,
-                                                                  span));
-
-        for obligation in obligations {
-            fcx.register_predicate(obligation);
+        let mut param_count = CountParams { params: FxHashSet() };
+        pred.visit_with(&mut param_count);
+        let substituted_pred = pred.subst(fcx.tcx, substs);
+        // Don't check non-defaulted params, dependent defaults or preds with multiple params.
+        if substituted_pred.references_error() || param_count.params.len() > 1 {
+            continue;
+        }
+        // Avoid duplication of predicates that contain no parameters, for example.
+        if !predicates.predicates.contains(&substituted_pred) {
+            substituted_predicates.push(substituted_pred);
         }
     }
 
-    fn check_fn_or_method<'fcx, 'tcx>(&mut self,
-                                      fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
-                                      span: Span,
-                                      sig: ty::PolyFnSig<'tcx>,
-                                      def_id: DefId,
-                                      implied_bounds: &mut Vec<Ty<'tcx>>)
-    {
-        let sig = fcx.normalize_associated_types_in(span, &sig);
-        let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig);
-
-        for input_ty in sig.inputs() {
-            fcx.register_wf_obligation(&input_ty, span, self.code.clone());
-        }
-        implied_bounds.extend(sig.inputs());
+    predicates.predicates.extend(substituted_predicates);
+    let predicates = predicates.instantiate_identity(fcx.tcx);
+    let predicates = fcx.normalize_associated_types_in(span, &predicates);
+
+    let obligations =
+        predicates.predicates
+                    .iter()
+                    .flat_map(|p| ty::wf::predicate_obligations(fcx,
+                                                                fcx.param_env,
+                                                                fcx.body_id,
+                                                                p,
+                                                                span));
+
+    for obligation in obligations {
+        fcx.register_predicate(obligation);
+    }
+}
 
-        fcx.register_wf_obligation(sig.output(), span, self.code.clone());
+fn check_fn_or_method<'a, 'fcx, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
+                                    fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
+                                    span: Span,
+                                    sig: ty::PolyFnSig<'tcx>,
+                                    def_id: DefId,
+                                    implied_bounds: &mut Vec<Ty<'tcx>>)
+{
+    let sig = fcx.normalize_associated_types_in(span, &sig);
+    let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig);
+
+    for input_ty in sig.inputs() {
+        fcx.register_wf_obligation(&input_ty, span, ObligationCauseCode::MiscObligation);
+    }
+    implied_bounds.extend(sig.inputs());
 
-        // FIXME(#25759) return types should not be implied bounds
-        implied_bounds.push(sig.output());
+    fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation);
 
-        self.check_where_clauses(fcx, span, def_id);
-    }
+    // FIXME(#25759) return types should not be implied bounds
+    implied_bounds.push(sig.output());
 
-    fn check_method_receiver<'fcx, 'tcx>(&mut self,
-                                         fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
-                                         method_sig: &hir::MethodSig,
-                                         method: &ty::AssociatedItem,
-                                         self_ty: Ty<'tcx>)
-    {
-        // check that the method has a valid receiver type, given the type `Self`
-        debug!("check_method_receiver({:?}, self_ty={:?})",
-               method, self_ty);
+    check_where_clauses(tcx, fcx, span, def_id);
+}
 
-        if !method.method_has_self_argument {
-            return;
-        }
+fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
+                                           method_sig: &hir::MethodSig,
+                                           method: &ty::AssociatedItem,
+                                           self_ty: Ty<'tcx>)
+{
+    // check that the method has a valid receiver type, given the type `Self`
+    debug!("check_method_receiver({:?}, self_ty={:?})",
+            method, self_ty);
+
+    if !method.method_has_self_argument {
+        return;
+    }
 
-        let span = method_sig.decl.inputs[0].span;
+    let span = method_sig.decl.inputs[0].span;
 
-        let sig = fcx.tcx.fn_sig(method.def_id);
-        let sig = fcx.normalize_associated_types_in(span, &sig);
-        let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &sig);
+    let sig = fcx.tcx.fn_sig(method.def_id);
+    let sig = fcx.normalize_associated_types_in(span, &sig);
+    let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &sig);
 
-        debug!("check_method_receiver: sig={:?}", sig);
+    debug!("check_method_receiver: sig={:?}", sig);
 
-        let self_ty = fcx.normalize_associated_types_in(span, &self_ty);
-        let self_ty = fcx.tcx.liberate_late_bound_regions(
-            method.def_id,
-            &ty::Binder(self_ty)
-        );
+    let self_ty = fcx.normalize_associated_types_in(span, &self_ty);
+    let self_ty = fcx.tcx.liberate_late_bound_regions(
+        method.def_id,
+        &ty::Binder(self_ty)
+    );
 
-        let self_arg_ty = sig.inputs()[0];
+    let self_arg_ty = sig.inputs()[0];
 
-        let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver);
-        let self_arg_ty = fcx.normalize_associated_types_in(span, &self_arg_ty);
-        let self_arg_ty = fcx.tcx.liberate_late_bound_regions(
-            method.def_id,
-            &ty::Binder(self_arg_ty)
-        );
+    let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver);
+    let self_arg_ty = fcx.normalize_associated_types_in(span, &self_arg_ty);
+    let self_arg_ty = fcx.tcx.liberate_late_bound_regions(
+        method.def_id,
+        &ty::Binder(self_arg_ty)
+    );
 
-        let mut autoderef = fcx.autoderef(span, self_arg_ty).include_raw_pointers();
+    let mut autoderef = fcx.autoderef(span, self_arg_ty).include_raw_pointers();
 
-        loop {
-            if let Some((potential_self_ty, _)) = autoderef.next() {
-                debug!("check_method_receiver: potential self type `{:?}` to match `{:?}`",
-                    potential_self_ty, self_ty);
+    loop {
+        if let Some((potential_self_ty, _)) = autoderef.next() {
+            debug!("check_method_receiver: potential self type `{:?}` to match `{:?}`",
+                potential_self_ty, self_ty);
 
-                if fcx.infcx.can_eq(fcx.param_env, self_ty, potential_self_ty).is_ok() {
-                    autoderef.finalize();
-                    if let Some(mut err) = fcx.demand_eqtype_with_origin(
-                        &cause, self_ty, potential_self_ty) {
-                        err.emit();
-                    }
-                    break
+            if fcx.infcx.can_eq(fcx.param_env, self_ty, potential_self_ty).is_ok() {
+                autoderef.finalize();
+                if let Some(mut err) = fcx.demand_eqtype_with_origin(
+                    &cause, self_ty, potential_self_ty) {
+                    err.emit();
                 }
-            } else {
-                fcx.tcx.sess.diagnostic().mut_span_err(
-                    span, &format!("invalid `self` type: {:?}", self_arg_ty))
-                .note(&format!("type must be `{:?}` or a type that dereferences to it", self_ty))
-                .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
-                .code(DiagnosticId::Error("E0307".into()))
-                .emit();
-                return
+                break
             }
+        } else {
+            fcx.tcx.sess.diagnostic().mut_span_err(
+                span, &format!("invalid `self` type: {:?}", self_arg_ty))
+            .note(&format!("type must be `{:?}` or a type that dereferences to it", self_ty))
+            .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
+            .code(DiagnosticId::Error("E0307".into()))
+            .emit();
+            return
         }
+    }
 
-        let is_self_ty = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok();
-        let self_kind = ExplicitSelf::determine(self_arg_ty, is_self_ty);
-
-        if !fcx.tcx.features().arbitrary_self_types {
-            match self_kind {
-                ExplicitSelf::ByValue |
-                ExplicitSelf::ByReference(_, _) |
-                ExplicitSelf::ByBox => (),
-
-                ExplicitSelf::ByRawPointer(_) => {
-                    feature_gate::feature_err(
-                        &fcx.tcx.sess.parse_sess,
-                        "arbitrary_self_types",
-                        span,
-                        GateIssue::Language,
-                        "raw pointer `self` is unstable")
-                    .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
-                    .emit();
-                }
+    let is_self_ty = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok();
+    let self_kind = ExplicitSelf::determine(self_arg_ty, is_self_ty);
+
+    if !fcx.tcx.features().arbitrary_self_types {
+        match self_kind {
+            ExplicitSelf::ByValue |
+            ExplicitSelf::ByReference(_, _) |
+            ExplicitSelf::ByBox => (),
+
+            ExplicitSelf::ByRawPointer(_) => {
+                feature_gate::feature_err(
+                    &fcx.tcx.sess.parse_sess,
+                    "arbitrary_self_types",
+                    span,
+                    GateIssue::Language,
+                    "raw pointer `self` is unstable")
+                .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
+                .emit();
+            }
 
-                ExplicitSelf::Other => {
-                    feature_gate::feature_err(
-                        &fcx.tcx.sess.parse_sess,
-                        "arbitrary_self_types",
-                        span,
-                        GateIssue::Language,"arbitrary `self` types are unstable")
-                    .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
-                    .emit();
-                }
+            ExplicitSelf::Other => {
+                feature_gate::feature_err(
+                    &fcx.tcx.sess.parse_sess,
+                    "arbitrary_self_types",
+                    span,
+                    GateIssue::Language,"arbitrary `self` types are unstable")
+                .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
+                .emit();
             }
         }
     }
+}
 
-    fn check_variances_for_type_defn(&self,
-                                     item: &hir::Item,
-                                     ast_generics: &hir::Generics)
-    {
-        let item_def_id = self.tcx.hir.local_def_id(item.id);
-        let ty = self.tcx.type_of(item_def_id);
-        if self.tcx.has_error_field(ty) {
-            return;
-        }
-
-        let ty_predicates = self.tcx.predicates_of(item_def_id);
-        assert_eq!(ty_predicates.parent, None);
-        let variances = self.tcx.variances_of(item_def_id);
+fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                    item: &hir::Item,
+                                    ast_generics: &hir::Generics)
+{
+    let item_def_id = tcx.hir.local_def_id(item.id);
+    let ty = tcx.type_of(item_def_id);
+    if tcx.has_error_field(ty) {
+        return;
+    }
 
-        let mut constrained_parameters: FxHashSet<_> =
-            variances.iter().enumerate()
-                     .filter(|&(_, &variance)| variance != ty::Bivariant)
-                     .map(|(index, _)| Parameter(index as u32))
-                     .collect();
+    let ty_predicates = tcx.predicates_of(item_def_id);
+    assert_eq!(ty_predicates.parent, None);
+    let variances = tcx.variances_of(item_def_id);
 
-        identify_constrained_type_params(self.tcx,
-                                         ty_predicates.predicates.as_slice(),
-                                         None,
-                                         &mut constrained_parameters);
+    let mut constrained_parameters: FxHashSet<_> =
+        variances.iter().enumerate()
+                    .filter(|&(_, &variance)| variance != ty::Bivariant)
+                    .map(|(index, _)| Parameter(index as u32))
+                    .collect();
 
-        for (index, _) in variances.iter().enumerate() {
-            if constrained_parameters.contains(&Parameter(index as u32)) {
-                continue;
-            }
+    identify_constrained_type_params(tcx,
+                                        ty_predicates.predicates.as_slice(),
+                                        None,
+                                        &mut constrained_parameters);
 
-            let (span, name) = match ast_generics.params[index] {
-                hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()),
-                hir::GenericParam::Type(ref tp) => (tp.span, tp.name),
-            };
-            self.report_bivariance(span, name);
+    for (index, _) in variances.iter().enumerate() {
+        if constrained_parameters.contains(&Parameter(index as u32)) {
+            continue;
         }
+
+        let (span, name) = match ast_generics.params[index] {
+            hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()),
+            hir::GenericParam::Type(ref tp) => (tp.span, tp.name),
+        };
+        report_bivariance(tcx, span, name);
     }
+}
 
-    fn report_bivariance(&self,
-                         span: Span,
-                         param_name: ast::Name)
-    {
-        let mut err = error_392(self.tcx, span, param_name);
-
-        let suggested_marker_id = self.tcx.lang_items().phantom_data();
-        match suggested_marker_id {
-            Some(def_id) => {
-                err.help(
-                    &format!("consider removing `{}` or using a marker such as `{}`",
-                             param_name,
-                             self.tcx.item_path_str(def_id)));
-            }
-            None => {
-                // no lang items, no help!
-            }
+fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                        span: Span,
+                        param_name: ast::Name)
+{
+    let mut err = error_392(tcx, span, param_name);
+
+    let suggested_marker_id = tcx.lang_items().phantom_data();
+    match suggested_marker_id {
+        Some(def_id) => {
+            err.help(
+                &format!("consider removing `{}` or using a marker such as `{}`",
+                            param_name,
+                            tcx.item_path_str(def_id)));
+        }
+        None => {
+            // no lang items, no help!
         }
-        err.emit();
     }
+    err.emit();
 }
 
 fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) {
@@ -648,6 +654,19 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) {
     }
 }
 
+pub struct CheckTypeWellFormedVisitor<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+}
+
+impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
+    pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>)
+               -> CheckTypeWellFormedVisitor<'a, 'gcx> {
+        CheckTypeWellFormedVisitor {
+            tcx,
+        }
+    }
+}
+
 impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
         NestedVisitorMap::None
@@ -655,27 +674,22 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> {
 
     fn visit_item(&mut self, i: &hir::Item) {
         debug!("visit_item: {:?}", i);
-        self.check_item_well_formed(i);
+        let def_id = self.tcx.hir.local_def_id(i.id);
+        ty::maps::queries::check_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_item(self, i);
     }
 
     fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
         debug!("visit_trait_item: {:?}", trait_item);
-        let method_sig = match trait_item.node {
-            hir::TraitItemKind::Method(ref sig, _) => Some(sig),
-            _ => None
-        };
-        self.check_associated_item(trait_item.id, trait_item.span, method_sig);
+        let def_id = self.tcx.hir.local_def_id(trait_item.id);
+        ty::maps::queries::check_trait_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_trait_item(self, trait_item)
     }
 
     fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) {
         debug!("visit_impl_item: {:?}", impl_item);
-        let method_sig = match impl_item.node {
-            hir::ImplItemKind::Method(ref sig, _) => Some(sig),
-            _ => None
-        };
-        self.check_associated_item(impl_item.id, impl_item.span, method_sig);
+        let def_id = self.tcx.hir.local_def_id(impl_item.id);
+        ty::maps::queries::check_impl_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_impl_item(self, impl_item)
     }
 }
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 862b15743c701..bbd04e0b19ae1 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -46,6 +46,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         wbcx.visit_anon_types();
         wbcx.visit_cast_types();
         wbcx.visit_free_region_map();
+        wbcx.visit_user_provided_tys();
 
         let used_trait_imports = mem::replace(
             &mut self.tables.borrow_mut().used_trait_imports,
@@ -341,6 +342,33 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
         self.tables.free_region_map = free_region_map;
     }
 
+    fn visit_user_provided_tys(&mut self) {
+        let fcx_tables = self.fcx.tables.borrow();
+        debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
+        let common_local_id_root = fcx_tables.local_id_root.unwrap();
+
+        for (&local_id, c_ty) in fcx_tables.user_provided_tys().iter() {
+            let hir_id = hir::HirId {
+                owner: common_local_id_root.index,
+                local_id,
+            };
+
+            let c_ty = if let Some(c_ty) = self.tcx().lift_to_global(c_ty) {
+                c_ty
+            } else {
+                span_bug!(
+                    hir_id.to_span(&self.fcx.tcx),
+                    "writeback: `{:?}` missing from the global type context",
+                    c_ty
+                );
+            };
+
+            self.tables
+                .user_provided_tys_mut()
+                .insert(hir_id, c_ty.clone());
+        }
+    }
+
     fn visit_anon_types(&mut self) {
         let gcx = self.tcx().global_tcx();
         for (&def_id, anon_defn) in self.fcx.anon_types.borrow().iter() {
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index 9493c36fe95a5..aa4322783c606 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -15,7 +15,7 @@ use rustc::infer::outlives::env::OutlivesEnvironment;
 use rustc::middle::region;
 use rustc::middle::lang_items::UnsizeTraitLangItem;
 
-use rustc::traits::{self, ObligationCause};
+use rustc::traits::{self, TraitEngine, ObligationCause};
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::TypeFoldable;
 use rustc::ty::adjustment::CoerceUnsizedInfo;
@@ -172,34 +172,34 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 }
 
-pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
                                      impl_did: DefId)
                                      -> CoerceUnsizedInfo {
     debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did);
-    let coerce_unsized_trait = tcx.lang_items().coerce_unsized_trait().unwrap();
+    let coerce_unsized_trait = gcx.lang_items().coerce_unsized_trait().unwrap();
 
-    let unsize_trait = match tcx.lang_items().require(UnsizeTraitLangItem) {
+    let unsize_trait = match gcx.lang_items().require(UnsizeTraitLangItem) {
         Ok(id) => id,
         Err(err) => {
-            tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err));
+            gcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err));
         }
     };
 
     // this provider should only get invoked for local def-ids
-    let impl_node_id = tcx.hir.as_local_node_id(impl_did).unwrap_or_else(|| {
+    let impl_node_id = gcx.hir.as_local_node_id(impl_did).unwrap_or_else(|| {
         bug!("coerce_unsized_info: invoked for non-local def-id {:?}", impl_did)
     });
 
-    let source = tcx.type_of(impl_did);
-    let trait_ref = tcx.impl_trait_ref(impl_did).unwrap();
+    let source = gcx.type_of(impl_did);
+    let trait_ref = gcx.impl_trait_ref(impl_did).unwrap();
     assert_eq!(trait_ref.def_id, coerce_unsized_trait);
     let target = trait_ref.substs.type_at(1);
     debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)",
            source,
            target);
 
-    let span = tcx.hir.span(impl_node_id);
-    let param_env = tcx.param_env(impl_did);
+    let span = gcx.hir.span(impl_node_id);
+    let param_env = gcx.param_env(impl_did);
     assert!(!source.has_escaping_regions());
 
     let err_info = CoerceUnsizedInfo { custom_kind: None };
@@ -208,11 +208,11 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
            source,
            target);
 
-    tcx.infer_ctxt().enter(|infcx| {
+    gcx.infer_ctxt().enter(|infcx| {
         let cause = ObligationCause::misc(span, impl_node_id);
-        let check_mutbl = |mt_a: ty::TypeAndMut<'tcx>,
-                           mt_b: ty::TypeAndMut<'tcx>,
-                           mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| {
+        let check_mutbl = |mt_a: ty::TypeAndMut<'gcx>,
+                           mt_b: ty::TypeAndMut<'gcx>,
+                           mk_ptr: &Fn(Ty<'gcx>) -> Ty<'gcx>| {
             if (mt_a.mutbl, mt_b.mutbl) == (hir::MutImmutable, hir::MutMutable) {
                 infcx.report_mismatched_types(&cause,
                                              mk_ptr(mt_b.ty),
@@ -225,20 +225,20 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         let (source, target, trait_def_id, kind) = match (&source.sty, &target.sty) {
             (&ty::TyRef(r_a, mt_a), &ty::TyRef(r_b, mt_b)) => {
                 infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a);
-                check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ref(r_b, ty))
+                check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ref(r_b, ty))
             }
 
             (&ty::TyRef(_, mt_a), &ty::TyRawPtr(mt_b)) |
             (&ty::TyRawPtr(mt_a), &ty::TyRawPtr(mt_b)) => {
-                check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty))
+                check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ptr(ty))
             }
 
             (&ty::TyAdt(def_a, substs_a), &ty::TyAdt(def_b, substs_b)) if def_a.is_struct() &&
                                                                           def_b.is_struct() => {
                 if def_a != def_b {
-                    let source_path = tcx.item_path_str(def_a.did);
-                    let target_path = tcx.item_path_str(def_b.did);
-                    span_err!(tcx.sess,
+                    let source_path = gcx.item_path_str(def_a.did);
+                    let target_path = gcx.item_path_str(def_b.did);
+                    span_err!(gcx.sess,
                               span,
                               E0377,
                               "the trait `CoerceUnsized` may only be implemented \
@@ -292,9 +292,9 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 let diff_fields = fields.iter()
                     .enumerate()
                     .filter_map(|(i, f)| {
-                        let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b));
+                        let (a, b) = (f.ty(gcx, substs_a), f.ty(gcx, substs_b));
 
-                        if tcx.type_of(f.did).is_phantom_data() {
+                        if gcx.type_of(f.did).is_phantom_data() {
                             // Ignore PhantomData fields
                             return None;
                         }
@@ -321,7 +321,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     .collect::<Vec<_>>();
 
                 if diff_fields.is_empty() {
-                    span_err!(tcx.sess,
+                    span_err!(gcx.sess,
                               span,
                               E0374,
                               "the trait `CoerceUnsized` may only be implemented \
@@ -329,14 +329,14 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                being coerced, none found");
                     return err_info;
                 } else if diff_fields.len() > 1 {
-                    let item = tcx.hir.expect_item(impl_node_id);
+                    let item = gcx.hir.expect_item(impl_node_id);
                     let span = if let ItemImpl(.., Some(ref t), _, _) = item.node {
                         t.path.span
                     } else {
-                        tcx.hir.span(impl_node_id)
+                        gcx.hir.span(impl_node_id)
                     };
 
-                    let mut err = struct_span_err!(tcx.sess,
+                    let mut err = struct_span_err!(gcx.sess,
                                                    span,
                                                    E0375,
                                                    "implementing the trait \
@@ -363,7 +363,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }
 
             _ => {
-                span_err!(tcx.sess,
+                span_err!(gcx.sess,
                           span,
                           E0376,
                           "the trait `CoerceUnsized` may only be implemented \
@@ -372,11 +372,11 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }
         };
 
-        let mut fulfill_cx = traits::FulfillmentContext::new();
+        let mut fulfill_cx = TraitEngine::new(infcx.tcx);
 
         // Register an obligation for `A: Trait<B>`.
         let cause = traits::ObligationCause::misc(span, impl_node_id);
-        let predicate = tcx.predicate_for_trait_def(param_env,
+        let predicate = gcx.predicate_for_trait_def(param_env,
                                                     cause,
                                                     trait_def_id,
                                                     0,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index a17b35dec42d7..6f24d06844bb4 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -35,8 +35,9 @@ use rustc::ty::{ToPredicate, ReprOptions};
 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
 use rustc::ty::maps::Providers;
 use rustc::ty::util::IntTypeExt;
-use rustc::util::nodemap::{FxHashSet, FxHashMap};
 use rustc::ty::util::Discr;
+use rustc::util::captures::Captures;
+use rustc::util::nodemap::{FxHashSet, FxHashMap};
 
 use syntax::{abi, ast};
 use syntax::ast::MetaItemKind;
@@ -1281,7 +1282,7 @@ fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
 fn early_bound_lifetimes_from_generics<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     ast_generics: &'a hir::Generics)
-    -> impl Iterator<Item=&'a hir::LifetimeDef>
+    -> impl Iterator<Item=&'a hir::LifetimeDef> + Captures<'tcx>
 {
     ast_generics
         .lifetimes()
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 24044fd2d7218..1f882676f61aa 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -3559,8 +3559,6 @@ elements in the array being matched.
 Example of erroneous code:
 
 ```compile_fail,E0527
-#![feature(slice_patterns)]
-
 let r = &[1, 2, 3, 4];
 match r {
     &[a, b] => { // error: pattern requires 2 elements but array
@@ -3625,8 +3623,6 @@ An array or slice pattern was matched against some other type.
 Example of erroneous code:
 
 ```compile_fail,E0529
-#![feature(slice_patterns)]
-
 let r: f32 = 1.0;
 match r {
     [a, b] => { // error: expected an array or slice, found `f32`
@@ -3639,8 +3635,6 @@ Ensure that the pattern and the expression being matched on are of consistent
 types:
 
 ```
-#![feature(slice_patterns)]
-
 let r = [1.0, 2.0];
 match r {
     [a, b] => { // ok!
@@ -4606,7 +4600,6 @@ This error indicates that there is a mismatch between generic parameters and
 impl Trait parameters in a trait declaration versus its impl.
 
 ```compile_fail,E0643
-#![feature(universal_impl_trait)]
 trait Foo {
     fn foo(&self, _: &impl Iterator);
 }
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 964c0021133aa..44ecb32a0bf9b 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -72,22 +72,23 @@ This API is completely unstable and subject to change.
 
 #![allow(non_camel_case_types)]
 
-#![feature(advanced_slice_patterns)]
+#![cfg_attr(stage0, feature(advanced_slice_patterns))]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
-#![feature(conservative_impl_trait)]
-#![feature(copy_closures, clone_closures)]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
+#![cfg_attr(stage0, feature(copy_closures, clone_closures))]
 #![feature(crate_visibility_modifier)]
 #![feature(from_ref)]
-#![feature(match_default_bindings)]
+#![cfg_attr(stage0, feature(match_default_bindings))]
 #![feature(exhaustive_patterns)]
 #![feature(option_filter)]
 #![feature(quote)]
 #![feature(refcell_replace_swap)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(slice_patterns)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![cfg_attr(stage0, feature(never_type))]
+#![feature(dyn_trait)]
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
@@ -111,7 +112,7 @@ use rustc::infer::InferOk;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::maps::Providers;
-use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode};
+use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine};
 use session::{CompileIncomplete, config};
 use util::common::time;
 
@@ -160,7 +161,7 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 -> bool {
     tcx.infer_ctxt().enter(|ref infcx| {
         let param_env = ty::ParamEnv::empty();
-        let mut fulfill_cx = FulfillmentContext::new();
+        let mut fulfill_cx = TraitEngine::new(infcx.tcx);
         match infcx.at(&cause, param_env).eq(expected, actual) {
             Ok(InferOk { obligations, .. }) => {
                 fulfill_cx.register_predicate_obligations(infcx, obligations);
@@ -208,8 +209,7 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }
 
             let actual = tcx.fn_sig(main_def_id);
-            let expected_return_type = if tcx.lang_items().termination().is_some()
-                && tcx.features().termination_trait {
+            let expected_return_type = if tcx.lang_items().termination().is_some() {
                 // we take the return type of the given main function, the real check is done
                 // in `check_fn`
                 actual.output().skip_binder()
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 370fc9bbca243..9ff3d25a45ae4 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use rustc::ty::TypeFoldable;
+use std::fmt::Debug;
 
 use super::*;
 
@@ -1081,18 +1082,25 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                     return None;
                 }
 
+                let mut bounds_vec = bounds.into_iter().collect();
+                self.sort_where_bounds(&mut bounds_vec);
+
                 Some(WherePredicate::BoundPredicate {
                     ty,
-                    bounds: bounds.into_iter().collect(),
+                    bounds: bounds_vec,
                 })
             })
             .chain(
                 lifetime_to_bounds
                     .into_iter()
                     .filter(|&(_, ref bounds)| !bounds.is_empty())
-                    .map(|(lifetime, bounds)| WherePredicate::RegionPredicate {
-                        lifetime,
-                        bounds: bounds.into_iter().collect(),
+                    .map(|(lifetime, bounds)| {
+                        let mut bounds_vec = bounds.into_iter().collect();
+                        self.sort_where_lifetimes(&mut bounds_vec);
+                        WherePredicate::RegionPredicate {
+                            lifetime,
+                            bounds: bounds_vec,
+                        }
                     }),
             )
             .collect()
@@ -1372,40 +1380,64 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
     // a given set of predicates always appears in the same order -
     // both for visual consistency between 'rustdoc' runs, and to
     // make writing tests much easier
-    fn sort_where_predicates(&self, predicates: &mut Vec<WherePredicate>) {
+    #[inline]
+    fn sort_where_predicates(&self, mut predicates: &mut Vec<WherePredicate>) {
         // We should never have identical bounds - and if we do,
         // they're visually identical as well. Therefore, using
         // an unstable sort is fine.
-        predicates.sort_unstable_by(|first, second| {
-            // This might look horrendously hacky, but it's actually not that bad.
-            //
-            // For performance reasons, we use several different FxHashMaps
-            // in the process of computing the final set of where predicates.
-            // However, the iteration order of a HashMap is completely unspecified.
-            // In fact, the iteration of an FxHashMap can even vary between platforms,
-            // since FxHasher has different behavior for 32-bit and 64-bit platforms.
-            //
-            // Obviously, it's extremely undesireable for documentation rendering
-            // to be depndent on the platform it's run on. Apart from being confusing
-            // to end users, it makes writing tests much more difficult, as predicates
-            // can appear in any order in the final result.
-            //
-            // To solve this problem, we sort WherePredicates by their Debug
-            // string. The thing to keep in mind is that we don't really
-            // care what the final order is - we're synthesizing an impl
-            // ourselves, so any order can be considered equally valid.
-            // By sorting the predicates, however, we ensure that for
-            // a given codebase, all auto-trait impls always render
-            // in exactly the same way.
-            //
-            // Using the Debug impementation for sorting prevents
-            // us from needing to write quite a bit of almost
-            // entirely useless code (e.g. how should two
-            // Types be sorted relative to each other).
-            // This approach is probably somewhat slower, but
-            // the small number of items involved (impls
-            // rarely have more than a few bounds) means
-            // that it shouldn't matter in practice.
+        self.unstable_debug_sort(&mut predicates);
+    }
+
+    // Ensure that the bounds are in a consistent order. The precise
+    // ordering doesn't actually matter, but it's important that
+    // a given set of bounds always appears in the same order -
+    // both for visual consistency between 'rustdoc' runs, and to
+    // make writing tests much easier
+    #[inline]
+    fn sort_where_bounds(&self, mut bounds: &mut Vec<TyParamBound>) {
+        // We should never have identical bounds - and if we do,
+        // they're visually identical as well. Therefore, using
+        // an unstable sort is fine.
+        self.unstable_debug_sort(&mut bounds);
+    }
+
+    #[inline]
+    fn sort_where_lifetimes(&self, mut bounds: &mut Vec<Lifetime>) {
+        // We should never have identical bounds - and if we do,
+        // they're visually identical as well. Therefore, using
+        // an unstable sort is fine.
+        self.unstable_debug_sort(&mut bounds);
+    }
+
+    // This might look horrendously hacky, but it's actually not that bad.
+    //
+    // For performance reasons, we use several different FxHashMaps
+    // in the process of computing the final set of where predicates.
+    // However, the iteration order of a HashMap is completely unspecified.
+    // In fact, the iteration of an FxHashMap can even vary between platforms,
+    // since FxHasher has different behavior for 32-bit and 64-bit platforms.
+    //
+    // Obviously, it's extremely undesireable for documentation rendering
+    // to be depndent on the platform it's run on. Apart from being confusing
+    // to end users, it makes writing tests much more difficult, as predicates
+    // can appear in any order in the final result.
+    //
+    // To solve this problem, we sort WherePredicates and TyParamBounds
+    // by their Debug string. The thing to keep in mind is that we don't really
+    // care what the final order is - we're synthesizing an impl or bound
+    // ourselves, so any order can be considered equally valid. By sorting the
+    // predicates and bounds, however, we ensure that for a given codebase, all
+    // auto-trait impls always render in exactly the same way.
+    //
+    // Using the Debug impementation for sorting prevents us from needing to
+    // write quite a bit of almost entirely useless code (e.g. how should two
+    // Types be sorted relative to each other). It also allows us to solve the
+    // problem for both WherePredicates and TyParamBounds at the same time. This
+    // approach is probably somewhat slower, but the small number of items
+    // involved (impls rarely have more than a few bounds) means that it
+    // shouldn't matter in practice.
+    fn unstable_debug_sort<T: Debug>(&self, vec: &mut Vec<T>) {
+        vec.sort_unstable_by(|first, second| {
             format!("{:?}", first).cmp(&format!("{:?}", second))
         });
     }
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 5cac2d1bbe7ee..c228f54217d34 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -138,7 +138,7 @@ impl Cfg {
 
     /// Renders the configuration for human display, as a short HTML description.
     pub(crate) fn render_short_html(&self) -> String {
-        let mut msg = Html(self).to_string();
+        let mut msg = ShortHtml(self).to_string();
         if self.should_capitalize_first_letter() {
             if let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric()) {
                 msg[i .. i+1].make_ascii_uppercase();
@@ -149,7 +149,13 @@ impl Cfg {
 
     /// Renders the configuration for long display, as a long HTML description.
     pub(crate) fn render_long_html(&self) -> String {
-        let mut msg = format!("This is supported on <strong>{}</strong>", Html(self));
+        let on = if self.should_use_with_in_description() {
+            "with"
+        } else {
+            "on"
+        };
+
+        let mut msg = format!("This is supported {} <strong>{}</strong>", on, Html(self));
         if self.should_append_only_to_description() {
             msg.push_str(" only");
         }
@@ -180,6 +186,13 @@ impl Cfg {
             }
         }
     }
+
+    fn should_use_with_in_description(&self) -> bool {
+        match *self {
+            Cfg::Cfg(ref name, _) if name == &"target_feature" => true,
+            _ => false,
+        }
+    }
 }
 
 impl ops::Not for Cfg {
@@ -376,6 +389,8 @@ impl<'a> fmt::Display for Html<'a> {
                     },
                     ("target_endian", Some(endian)) => return write!(fmt, "{}-endian", endian),
                     ("target_pointer_width", Some(bits)) => return write!(fmt, "{}-bit", bits),
+                    ("target_feature", Some(feat)) =>
+                        return write!(fmt, "target feature <code>{}</code>", feat),
                     _ => "",
                 };
                 if !human_readable.is_empty() {
@@ -390,6 +405,19 @@ impl<'a> fmt::Display for Html<'a> {
     }
 }
 
+struct ShortHtml<'a>(&'a Cfg);
+
+impl<'a> fmt::Display for ShortHtml<'a> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        match *self.0 {
+            Cfg::Cfg(ref name, Some(ref vendor)) if name == &"target_feature" => {
+                write!(fmt, "<code>{}</code>", vendor)
+            },
+            ref cfg => write!(fmt, "{}", Html(cfg)),
+        }
+    }
+}
+
 #[cfg(test)]
 mod test {
     use super::Cfg;
@@ -824,6 +852,10 @@ mod test {
                 ).render_short_html(),
                 "(Debug-assertions enabled or Windows) and Unix"
             );
+            assert_eq!(
+                name_value_cfg("target_feature", "sse2").render_short_html(),
+                "<code>sse2</code>"
+            );
         })
     }
 
@@ -898,6 +930,10 @@ mod test {
                 "This is supported on <strong>(debug-assertions enabled or Windows) and Unix\
                 </strong> only."
             );
+            assert_eq!(
+                name_value_cfg("target_feature", "sse2").render_long_html(),
+                "This is supported with <strong>target feature <code>sse2</code></strong> only."
+            );
         })
     }
 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 904c24815cb7f..42c9d9e52f35c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -828,6 +828,19 @@ impl Attributes {
             })
         }).collect();
 
+        // treat #[target_feature(enable = "feat")] attributes as if they were
+        // #[doc(cfg(target_feature = "feat"))] attributes as well
+        for attr in attrs.lists("target_feature") {
+            if attr.check_name("enable") {
+                if let Some(feat) = attr.value_str() {
+                    let meta = attr::mk_name_value_item_str("target_feature".into(), feat);
+                    if let Ok(feat_cfg) = Cfg::parse(&meta) {
+                        cfg &= feat_cfg;
+                    }
+                }
+            }
+        }
+
         Attributes {
             doc_strings,
             other_attrs,
@@ -929,7 +942,7 @@ fn ambiguity_error(cx: &DocContext, attrs: &Attributes,
                       select the {}",
                       disambig1, kind1, disambig2,
                       kind2))
-             .emit();
+      .emit();
 }
 
 /// Given an enum variant's def, return the def of its enum and the associated fragment
@@ -1009,11 +1022,12 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option
                                  .flat_map(|imp| cx.tcx.associated_items(*imp))
                                  .find(|item| item.name == item_name);
                 if let Some(item) = item {
-                    if item.kind == ty::AssociatedKind::Method && is_val {
-                        Ok((ty.def, Some(format!("method.{}", item_name))))
-                    } else {
-                        Err(())
-                    }
+                    let out = match item.kind {
+                        ty::AssociatedKind::Method if is_val => "method",
+                        ty::AssociatedKind::Const if is_val => "associatedconstant",
+                        _ => return Err(())
+                    };
+                    Ok((ty.def, Some(format!("{}.{}", out, item_name))))
                 } else {
                     Err(())
                 }
@@ -1074,6 +1088,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option<Def> {
     }
 }
 
+#[derive(Debug)]
 enum PathKind {
     /// can be either value or type, not a macro
     Unknown,
@@ -1082,7 +1097,7 @@ enum PathKind {
     /// values, functions, consts, statics, everything in the value namespace
     Value,
     /// types, traits, everything in the type namespace
-    Type
+    Type,
 }
 
 impl Clean<Attributes> for [ast::Attribute] {
@@ -1091,12 +1106,13 @@ impl Clean<Attributes> for [ast::Attribute] {
 
         if UnstableFeatures::from_environment().is_nightly_build() {
             let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new);
-            for link in markdown_links(&dox) {
+            for ori_link in markdown_links(&dox) {
                 // bail early for real links
-                if link.contains('/') {
+                if ori_link.contains('/') {
                     continue;
                 }
-                let (def, fragment)  = {
+                let link = ori_link.replace("`", "");
+                let (def, fragment) = {
                     let mut kind = PathKind::Unknown;
                     let path_str = if let Some(prefix) =
                         ["struct@", "enum@", "type@",
@@ -1124,15 +1140,11 @@ impl Clean<Attributes> for [ast::Attribute] {
                         &link[..]
                     }.trim();
 
-                    // avoid resolving things (i.e. regular links) which aren't like paths
-                    // FIXME(Manishearth) given that most links have slashes in them might be worth
-                    // doing a check for slashes first
                     if path_str.contains(|ch: char| !(ch.is_alphanumeric() ||
                                                       ch == ':' || ch == '_')) {
                         continue;
                     }
 
-
                     match kind {
                         PathKind::Value => {
                             if let Ok(def) = resolve(cx, path_str, true) {
@@ -1206,9 +1218,8 @@ impl Clean<Attributes> for [ast::Attribute] {
                     }
                 };
 
-
                 let id = register_def(cx, def);
-                attrs.links.push((link, id, fragment));
+                attrs.links.push((ori_link, id, fragment));
             }
 
             cx.sess().abort_if_errors();
@@ -1224,6 +1235,7 @@ pub struct TyParam {
     pub did: DefId,
     pub bounds: Vec<TyParamBound>,
     pub default: Option<Type>,
+    pub synthetic: Option<hir::SyntheticTyParamKind>,
 }
 
 impl Clean<TyParam> for hir::TyParam {
@@ -1233,6 +1245,7 @@ impl Clean<TyParam> for hir::TyParam {
             did: cx.tcx.hir.local_def_id(self.id),
             bounds: self.bounds.clean(cx),
             default: self.default.clean(cx),
+            synthetic: self.synthetic,
         }
     }
 }
@@ -1248,7 +1261,8 @@ impl<'tcx> Clean<TyParam> for ty::TypeParameterDef {
                 Some(cx.tcx.type_of(self.def_id).clean(cx))
             } else {
                 None
-            }
+            },
+            synthetic: None,
         }
     }
 }
@@ -1616,6 +1630,16 @@ pub enum GenericParam {
     Type(TyParam),
 }
 
+impl GenericParam {
+    pub fn is_synthetic_type_param(&self) -> bool {
+        if let GenericParam::Type(ref t) = *self {
+            t.synthetic.is_some()
+        } else {
+            false
+        }
+    }
+}
+
 impl Clean<GenericParam> for hir::GenericParam {
     fn clean(&self, cx: &DocContext) -> GenericParam {
         match *self {
@@ -1748,11 +1772,12 @@ pub struct Method {
 
 impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) {
     fn clean(&self, cx: &DocContext) -> Method {
+        let generics = self.1.clean(cx);
         Method {
-            generics: self.1.clean(cx),
+            decl: enter_impl_trait(cx, &generics.params, || (&*self.0.decl, self.2).clean(cx)),
+            generics,
             unsafety: self.0.unsafety,
             constness: self.0.constness,
-            decl: (&*self.0.decl, self.2).clean(cx),
             abi: self.0.abi
         }
     }
@@ -1777,6 +1802,8 @@ pub struct Function {
 
 impl Clean<Item> for doctree::Function {
     fn clean(&self, cx: &DocContext) -> Item {
+        let generics = self.generics.clean(cx);
+        let decl = enter_impl_trait(cx, &generics.params, || (&self.decl, self.body).clean(cx));
         Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
@@ -1786,8 +1813,8 @@ impl Clean<Item> for doctree::Function {
             deprecation: self.depr.clean(cx),
             def_id: cx.tcx.hir.local_def_id(self.id),
             inner: FunctionItem(Function {
-                decl: (&self.decl, self.body).clean(cx),
-                generics: self.generics.clean(cx),
+                decl,
+                generics,
                 unsafety: self.unsafety,
                 constness: self.constness,
                 abi: self.abi,
@@ -1872,7 +1899,8 @@ impl<'a, 'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
             vec![].into_iter()
         } else {
             cx.tcx.fn_arg_names(did).into_iter()
-        }.peekable();
+        };
+
         FnDecl {
             output: Return(sig.skip_binder().output().clean(cx)),
             attrs: Attributes::default(),
@@ -2014,10 +2042,13 @@ impl Clean<Item> for hir::TraitItem {
                 MethodItem((sig, &self.generics, body).clean(cx))
             }
             hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => {
+                let generics = self.generics.clean(cx);
                 TyMethodItem(TyMethod {
                     unsafety: sig.unsafety.clone(),
-                    decl: (&*sig.decl, &names[..]).clean(cx),
-                    generics: self.generics.clean(cx),
+                    decl: enter_impl_trait(cx, &generics.params, || {
+                        (&*sig.decl, &names[..]).clean(cx)
+                    }),
+                    generics,
                     abi: sig.abi
                 })
             }
@@ -2521,6 +2552,12 @@ impl Clean<Type> for hir::Ty {
                     return new_ty;
                 }
 
+                if let Def::TyParam(did) = path.def {
+                    if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did) {
+                        return ImplTrait(bounds);
+                    }
+                }
+
                 let mut alias = None;
                 if let Def::TyAlias(def_id) = path.def {
                     // Substitute private type aliases
@@ -3233,10 +3270,13 @@ pub struct BareFunctionDecl {
 
 impl Clean<BareFunctionDecl> for hir::BareFnTy {
     fn clean(&self, cx: &DocContext) -> BareFunctionDecl {
+        let generic_params = self.generic_params.clean(cx);
         BareFunctionDecl {
             unsafety: self.unsafety,
-            generic_params: self.generic_params.clean(cx),
-            decl: (&*self.decl, &self.arg_names[..]).clean(cx),
+            decl: enter_impl_trait(cx, &generic_params, || {
+                (&*self.decl, &self.arg_names[..]).clean(cx)
+            }),
+            generic_params,
             abi: self.abi,
         }
     }
@@ -3537,9 +3577,12 @@ impl Clean<Item> for hir::ForeignItem {
     fn clean(&self, cx: &DocContext) -> Item {
         let inner = match self.node {
             hir::ForeignItemFn(ref decl, ref names, ref generics) => {
+                let generics = generics.clean(cx);
                 ForeignFunctionItem(Function {
-                    decl: (&**decl, &names[..]).clean(cx),
-                    generics: generics.clean(cx),
+                    decl: enter_impl_trait(cx, &generics.params, || {
+                        (&**decl, &names[..]).clean(cx)
+                    }),
+                    generics,
                     unsafety: hir::Unsafety::Unsafe,
                     abi: Abi::Rust,
                     constness: hir::Constness::NotConst,
@@ -3841,6 +3884,29 @@ pub fn def_id_to_path(cx: &DocContext, did: DefId, name: Option<String>) -> Vec<
     once(crate_name).chain(relative).collect()
 }
 
+pub fn enter_impl_trait<F, R>(cx: &DocContext, gps: &[GenericParam], f: F) -> R
+where
+    F: FnOnce() -> R,
+{
+    let bounds = gps.iter()
+        .filter_map(|p| {
+            if let GenericParam::Type(ref tp) = *p {
+                if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
+                    return Some((tp.did, tp.bounds.clone()));
+                }
+            }
+
+            None
+        })
+        .collect::<FxHashMap<DefId, Vec<TyParamBound>>>();
+
+    let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), bounds);
+    let r = f();
+    assert!(cx.impl_trait_bounds.borrow().is_empty());
+    *cx.impl_trait_bounds.borrow_mut() = old_bounds;
+    r
+}
+
 // Start of code copied from rust-clippy
 
 pub fn get_trait_def_id(tcx: &TyCtxt, path: &[&str], use_local: bool) -> Option<DefId> {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 1e0fafc8d9dfd..462866e05da49 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -22,6 +22,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_resolve as resolve;
 use rustc_metadata::creader::CrateLoader;
 use rustc_metadata::cstore::CStore;
+use rustc_back::target::TargetTriple;
 
 use syntax::ast::NodeId;
 use syntax::codemap;
@@ -72,6 +73,8 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> {
     pub ty_substs: RefCell<FxHashMap<Def, clean::Type>>,
     /// Table node id of lifetime parameter definition -> substituted lifetime
     pub lt_substs: RefCell<FxHashMap<DefId, clean::Lifetime>>,
+    /// Table DefId of `impl Trait` in argument position -> bounds
+    pub impl_trait_bounds: RefCell<FxHashMap<DefId, Vec<clean::TyParamBound>>>,
     pub send_trait: Option<DefId>,
     pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>,
     pub all_fake_def_ids: RefCell<FxHashSet<DefId>>,
@@ -116,7 +119,7 @@ pub fn run_core(search_paths: SearchPaths,
                 cfgs: Vec<String>,
                 externs: config::Externs,
                 input: Input,
-                triple: Option<String>,
+                triple: Option<TargetTriple>,
                 maybe_sysroot: Option<PathBuf>,
                 allow_warnings: bool,
                 crate_name: Option<String>,
@@ -131,6 +134,7 @@ pub fn run_core(search_paths: SearchPaths,
 
     let warning_lint = lint::builtin::WARNINGS.name_lower();
 
+    let host_triple = TargetTriple::from_triple(config::host_triple());
     let sessopts = config::Options {
         maybe_sysroot,
         search_paths,
@@ -138,7 +142,7 @@ pub fn run_core(search_paths: SearchPaths,
         lint_opts: if !allow_warnings { vec![(warning_lint, lint::Allow)] } else { vec![] },
         lint_cap: Some(lint::Allow),
         externs,
-        target_triple: triple.unwrap_or(config::host_triple().to_string()),
+        target_triple: triple.unwrap_or(host_triple),
         // Ensure that rustdoc works even if rustc is feature-staged
         unstable_features: UnstableFeatures::Allow,
         actually_rustdoc: true,
@@ -261,6 +265,7 @@ pub fn run_core(search_paths: SearchPaths,
             renderinfo: Default::default(),
             ty_substs: Default::default(),
             lt_substs: Default::default(),
+            impl_trait_bounds: Default::default(),
             mod_ids: Default::default(),
             send_trait: send_trait,
             fake_def_ids: RefCell::new(FxHashMap()),
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 2913ea6a78ec3..0a7e19fc643f6 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -148,11 +148,17 @@ impl fmt::Display for clean::GenericParam {
 
 impl fmt::Display for clean::Generics {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        if self.params.is_empty() { return Ok(()) }
+        let real_params = self.params
+            .iter()
+            .filter(|p| !p.is_synthetic_type_param())
+            .collect::<Vec<_>>();
+        if real_params.is_empty() {
+            return Ok(());
+        }
         if f.alternate() {
-            write!(f, "<{:#}>", CommaSep(&self.params))
+            write!(f, "<{:#}>", CommaSep(&real_params))
         } else {
-            write!(f, "&lt;{}&gt;", CommaSep(&self.params))
+            write!(f, "&lt;{}&gt;", CommaSep(&real_params))
         }
     }
 }
@@ -575,7 +581,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
                 }
                 many => {
                     primitive_link(f, PrimitiveType::Tuple, "(")?;
-                    fmt::Display::fmt(&CommaSep(&many), f)?;
+                    fmt::Display::fmt(&CommaSep(many), f)?;
                     primitive_link(f, PrimitiveType::Tuple, ")")
                 }
             }
@@ -661,18 +667,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
             }
         }
         clean::ImplTrait(ref bounds) => {
-            write!(f, "impl ")?;
-            for (i, bound) in bounds.iter().enumerate() {
-                if i != 0 {
-                    write!(f, " + ")?;
-                }
-                if f.alternate() {
-                    write!(f, "{:#}", *bound)?;
-                } else {
-                    write!(f, "{}", *bound)?;
-                }
-            }
-            Ok(())
+            write!(f, "impl {}", TyParamBounds(bounds))
         }
         clean::QPath { ref name, ref self_type, ref trait_ } => {
             let should_show_cast = match *trait_ {
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index ef01c3e6bdb0c..cfa3f5a4e0b4f 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -323,12 +323,12 @@ impl<'a> Classifier<'a> {
             }
 
             // Keywords are also included in the identifier set.
-            token::Ident(ident) => {
+            token::Ident(ident, is_raw) => {
                 match &*ident.name.as_str() {
-                    "ref" | "mut" => Class::RefKeyWord,
+                    "ref" | "mut" if !is_raw => Class::RefKeyWord,
 
-                    "self" |"Self" => Class::Self_,
-                    "false" | "true" => Class::Bool,
+                    "self" | "Self" => Class::Self_,
+                    "false" | "true" if !is_raw => Class::Bool,
 
                     "Option" | "Result" => Class::PreludeTy,
                     "Some" | "None" | "Ok" | "Err" => Class::PreludeVal,
@@ -352,7 +352,7 @@ impl<'a> Classifier<'a> {
 
             token::Lifetime(..) => Class::Lifetime,
 
-            token::Underscore | token::Eof | token::Interpolated(..) |
+            token::Eof | token::Interpolated(..) |
             token::Tilde | token::At | token::DotEq => Class::None,
         };
 
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 5e55353a26e6b..c09bd4cc84ae5 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -27,6 +27,7 @@
 
 #![allow(non_camel_case_types)]
 
+use rustc::session;
 use std::cell::RefCell;
 use std::collections::{HashMap, VecDeque};
 use std::default::Default;
@@ -232,14 +233,14 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
 /// Make headings links with anchor ids and build up TOC.
 struct LinkReplacer<'a, 'b, I: Iterator<Item = Event<'a>>> {
     inner: I,
-    links: &'b [(String, String)]
+    links: &'b [(String, String)],
 }
 
 impl<'a, 'b, I: Iterator<Item = Event<'a>>> LinkReplacer<'a, 'b, I> {
     fn new(iter: I, links: &'b [(String, String)]) -> Self {
         LinkReplacer {
             inner: iter,
-            links
+            links,
         }
     }
 }
@@ -434,7 +435,8 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
     }
 }
 
-pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) {
+pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span,
+                          sess: Option<&session::Session>) {
     tests.set_position(position);
 
     let mut parser = Parser::new(doc);
@@ -484,6 +486,9 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp
                                    line, filename, block_info.allow_fail);
                     prev_offset = offset;
                 } else {
+                    if let Some(ref sess) = sess {
+                        sess.span_warn(position, "invalid start of a new code block");
+                    }
                     break;
                 }
             }
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 28d39cb174a10..6c6c067f95189 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -49,6 +49,13 @@
 
     var themesWidth = null;
 
+    if (!String.prototype.startsWith) {
+        String.prototype.startsWith = function(searchString, position) {
+            position = position || 0;
+            return this.indexOf(searchString, position) === position;
+        };
+    }
+
     function hasClass(elem, className) {
         if (elem && className && elem.className) {
             var elemClass = elem.className;
@@ -239,52 +246,59 @@
         }
     }
 
-    function handleShortcut(ev) {
-        if (document.activeElement.tagName === "INPUT" &&
-                hasClass(document.getElementById('main'), "hidden")) {
-            return;
+    function handleEscape(ev, help) {
+        hideModal();
+        var search = document.getElementById("search");
+        if (!hasClass(help, "hidden")) {
+            displayHelp(false, ev);
+        } else if (!hasClass(search, "hidden")) {
+            ev.preventDefault();
+            addClass(search, "hidden");
+            removeClass(document.getElementById("main"), "hidden");
         }
+        defocusSearchBar();
+    }
 
+    function handleShortcut(ev) {
         // Don't interfere with browser shortcuts
         if (ev.ctrlKey || ev.altKey || ev.metaKey) {
             return;
         }
 
         var help = document.getElementById("help");
-        switch (getVirtualKey(ev)) {
-        case "Escape":
-            hideModal();
-            var search = document.getElementById("search");
-            if (!hasClass(help, "hidden")) {
-                displayHelp(false, ev);
-            } else if (!hasClass(search, "hidden")) {
-                ev.preventDefault();
-                addClass(search, "hidden");
-                removeClass(document.getElementById("main"), "hidden");
+        if (document.activeElement.tagName === "INPUT") {
+            switch (getVirtualKey(ev)) {
+            case "Escape":
+                handleEscape(ev, help);
+                break;
             }
-            defocusSearchBar();
-            break;
+        } else {
+            switch (getVirtualKey(ev)) {
+            case "Escape":
+                handleEscape(ev, help);
+                break;
 
-        case "s":
-        case "S":
-            displayHelp(false, ev);
-            hideModal();
-            ev.preventDefault();
-            focusSearchBar();
-            break;
+            case "s":
+            case "S":
+                displayHelp(false, ev);
+                hideModal();
+                ev.preventDefault();
+                focusSearchBar();
+                break;
 
-        case "+":
-        case "-":
-            ev.preventDefault();
-            toggleAllDocs();
-            break;
+            case "+":
+            case "-":
+                ev.preventDefault();
+                toggleAllDocs();
+                break;
 
-        case "?":
-            if (ev.shiftKey) {
-                hideModal();
-                displayHelp(true, ev);
+            case "?":
+                if (ev.shiftKey) {
+                    hideModal();
+                    displayHelp(true, ev);
+                }
+                break;
             }
-            break;
         }
     }
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index da52fd5aa3725..0339a58d58219 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -20,7 +20,7 @@
 #![feature(box_syntax)]
 #![feature(fs_read_write)]
 #![feature(set_stdio)]
-#![feature(slice_patterns)]
+#![cfg_attr(stage0, feature(slice_patterns))]
 #![feature(test)]
 #![feature(unicode)]
 #![feature(vec_remove_item)]
@@ -64,6 +64,7 @@ use std::sync::mpsc::channel;
 use externalfiles::ExternalHtml;
 use rustc::session::search_paths::SearchPaths;
 use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options, Externs};
+use rustc_back::target::TargetTriple;
 
 #[macro_use]
 pub mod externalfiles;
@@ -542,7 +543,13 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
         paths.add_path(s, ErrorOutputType::default());
     }
     let cfgs = matches.opt_strs("cfg");
-    let triple = matches.opt_str("target");
+    let triple = matches.opt_str("target").map(|target| {
+        if target.ends_with(".json") {
+            TargetTriple::TargetPath(PathBuf::from(target))
+        } else {
+            TargetTriple::TargetTriple(target)
+        }
+    });
     let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
     let crate_name = matches.opt_str("crate-name");
     let crate_version = matches.opt_str("crate-version");
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 0f107457d2bf8..3a55b279b5cc7 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -152,7 +152,7 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
                                        true, opts, maybe_sysroot, None,
                                        Some(PathBuf::from(input)),
                                        linker);
-    find_testable_code(&input_str, &mut collector, DUMMY_SP);
+    find_testable_code(&input_str, &mut collector, DUMMY_SP, None);
     test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&test_args, collector.tests,
                        testing::Options::new().display_output(display_warnings));
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 117b21d47587f..8ab9ca451871b 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -406,8 +406,6 @@ pub fn make_test(s: &str,
 
 // FIXME(aburka): use a real parser to deal with multiline attributes
 fn partition_source(s: &str) -> (String, String) {
-    use std_unicode::str::UnicodeStr;
-
     let mut after_header = false;
     let mut before = String::new();
     let mut after = String::new();
@@ -416,6 +414,7 @@ fn partition_source(s: &str) -> (String, String) {
         let trimline = line.trim();
         let header = trimline.is_whitespace() ||
             trimline.starts_with("#![") ||
+            trimline.starts_with("#[macro_use] extern crate") ||
             trimline.starts_with("extern crate");
         if !header || after_header {
             after_header = true;
@@ -645,8 +644,10 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
         // the collapse-docs pass won't combine sugared/raw doc attributes, or included files with
         // anything else, this will combine them for us
         if let Some(doc) = attrs.collapsed_doc_value() {
-            markdown::find_testable_code(&doc, self.collector,
-                                         attrs.span.unwrap_or(DUMMY_SP));
+            markdown::find_testable_code(&doc,
+                                         self.collector,
+                                         attrs.span.unwrap_or(DUMMY_SP),
+                                         Some(self.sess));
         }
 
         nested(self);
@@ -825,6 +826,24 @@ assert_eq!(2+2, 4);
         assert_eq!(output, (expected, 2));
     }
 
+    #[test]
+    fn make_test_manual_extern_crate_with_macro_use() {
+        let opts = TestOptions::default();
+        let input =
+"#[macro_use] extern crate asdf;
+use asdf::qwop;
+assert_eq!(2+2, 4);";
+        let expected =
+"#![allow(unused)]
+#[macro_use] extern crate asdf;
+fn main() {
+use asdf::qwop;
+assert_eq!(2+2, 4);
+}".to_string();
+        let output = make_test(input, Some("asdf"), false, &opts);
+        assert_eq!(output, (expected, 2));
+    }
+
     #[test]
     fn make_test_opts_attrs() {
         //if you supplied some doctest attributes with #![doc(test(attr(...)))], it will use those
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index f692e05d6a259..f45a5b030db2b 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -406,13 +406,13 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> {
             // If we're inlining, skip private items.
             _ if self.inlining && item.vis != hir::Public => {}
             hir::ItemGlobalAsm(..) => {}
-            hir::ItemExternCrate(ref p) => {
+            hir::ItemExternCrate(orig_name) => {
                 let def_id = self.cx.tcx.hir.local_def_id(item.id);
                 om.extern_crates.push(ExternCrate {
                     cnum: self.cx.tcx.extern_mod_stmt_cnum(def_id)
                                 .unwrap_or(LOCAL_CRATE),
                     name,
-                    path: p.map(|x|x.to_string()),
+                    path: orig_name.map(|x|x.to_string()),
                     vis: item.vis.clone(),
                     attrs: item.attrs.clone(),
                     whence: item.span,
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 2e354252c1573..ee95252346223 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -23,7 +23,7 @@ Core encoding and decoding interfaces.
 
 #![feature(box_syntax)]
 #![feature(core_intrinsics)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(specialization)]
 #![cfg_attr(test, feature(test))]
 
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 0837ff91c142d..6472edb0aa7d3 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -52,6 +52,7 @@ pub use core::ascii::{EscapeDefault, escape_default};
 ///
 /// [combining character]: https://en.wikipedia.org/wiki/Combining_character
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
 pub trait AsciiExt {
     /// Container type for copied ASCII characters.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -84,6 +85,7 @@ pub trait AsciiExt {
     /// [`make_ascii_uppercase`]: #tymethod.make_ascii_uppercase
     /// [`str::to_uppercase`]: ../primitive.str.html#method.to_uppercase
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[allow(deprecated)]
     fn to_ascii_uppercase(&self) -> Self::Owned;
 
     /// Makes a copy of the value in its ASCII lower case equivalent.
@@ -104,6 +106,7 @@ pub trait AsciiExt {
     /// [`make_ascii_lowercase`]: #tymethod.make_ascii_lowercase
     /// [`str::to_lowercase`]: ../primitive.str.html#method.to_lowercase
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[allow(deprecated)]
     fn to_ascii_lowercase(&self) -> Self::Owned;
 
     /// Checks that two values are an ASCII case-insensitive match.
@@ -162,6 +165,7 @@ pub trait AsciiExt {
     /// This method will be deprecated in favor of the identically-named
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     #[unstable(feature = "ascii_ctype", issue = "39658")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
     fn is_ascii_alphabetic(&self) -> bool { unimplemented!(); }
 
     /// Checks if the value is an ASCII uppercase character:
@@ -174,6 +178,7 @@ pub trait AsciiExt {
     /// This method will be deprecated in favor of the identically-named
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     #[unstable(feature = "ascii_ctype", issue = "39658")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
     fn is_ascii_uppercase(&self) -> bool { unimplemented!(); }
 
     /// Checks if the value is an ASCII lowercase character:
@@ -186,6 +191,7 @@ pub trait AsciiExt {
     /// This method will be deprecated in favor of the identically-named
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     #[unstable(feature = "ascii_ctype", issue = "39658")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
     fn is_ascii_lowercase(&self) -> bool { unimplemented!(); }
 
     /// Checks if the value is an ASCII alphanumeric character:
@@ -199,6 +205,7 @@ pub trait AsciiExt {
     /// This method will be deprecated in favor of the identically-named
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     #[unstable(feature = "ascii_ctype", issue = "39658")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
     fn is_ascii_alphanumeric(&self) -> bool { unimplemented!(); }
 
     /// Checks if the value is an ASCII decimal digit:
@@ -211,6 +218,7 @@ pub trait AsciiExt {
     /// This method will be deprecated in favor of the identically-named
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     #[unstable(feature = "ascii_ctype", issue = "39658")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
     fn is_ascii_digit(&self) -> bool { unimplemented!(); }
 
     /// Checks if the value is an ASCII hexadecimal digit:
@@ -224,6 +232,7 @@ pub trait AsciiExt {
     /// This method will be deprecated in favor of the identically-named
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     #[unstable(feature = "ascii_ctype", issue = "39658")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
     fn is_ascii_hexdigit(&self) -> bool { unimplemented!(); }
 
     /// Checks if the value is an ASCII punctuation character:
@@ -241,6 +250,7 @@ pub trait AsciiExt {
     /// This method will be deprecated in favor of the identically-named
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     #[unstable(feature = "ascii_ctype", issue = "39658")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
     fn is_ascii_punctuation(&self) -> bool { unimplemented!(); }
 
     /// Checks if the value is an ASCII graphic character:
@@ -253,6 +263,7 @@ pub trait AsciiExt {
     /// This method will be deprecated in favor of the identically-named
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     #[unstable(feature = "ascii_ctype", issue = "39658")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
     fn is_ascii_graphic(&self) -> bool { unimplemented!(); }
 
     /// Checks if the value is an ASCII whitespace character:
@@ -282,6 +293,7 @@ pub trait AsciiExt {
     /// This method will be deprecated in favor of the identically-named
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     #[unstable(feature = "ascii_ctype", issue = "39658")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
     fn is_ascii_whitespace(&self) -> bool { unimplemented!(); }
 
     /// Checks if the value is an ASCII control character:
@@ -294,6 +306,7 @@ pub trait AsciiExt {
     /// This method will be deprecated in favor of the identically-named
     /// inherent methods on `u8`, `char`, `[u8]` and `str`.
     #[unstable(feature = "ascii_ctype", issue = "39658")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
     fn is_ascii_control(&self) -> bool { unimplemented!(); }
 }
 
@@ -354,6 +367,7 @@ macro_rules! delegating_ascii_ctype_methods {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 impl AsciiExt for u8 {
     type Owned = u8;
 
@@ -362,6 +376,7 @@ impl AsciiExt for u8 {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 impl AsciiExt for char {
     type Owned = char;
 
@@ -370,6 +385,7 @@ impl AsciiExt for char {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 impl AsciiExt for [u8] {
     type Owned = Vec<u8>;
 
@@ -427,6 +443,7 @@ impl AsciiExt for [u8] {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 impl AsciiExt for str {
     type Owned = String;
 
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index b18b38ec30246..f0bb781411fb4 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -1184,6 +1184,34 @@ impl<K, V, S> HashMap<K, V, S>
         self.search(k).map(|bucket| bucket.into_refs().1)
     }
 
+    /// Returns the key-value pair corresponding to the supplied key.
+    ///
+    /// The supplied key may be any borrowed form of the map's key type, but
+    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
+    /// the key type.
+    ///
+    /// [`Eq`]: ../../std/cmp/trait.Eq.html
+    /// [`Hash`]: ../../std/hash/trait.Hash.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(map_get_key_value)]
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
+    /// assert_eq!(map.get_key_value(&2), None);
+    /// ```
+    #[unstable(feature = "map_get_key_value", issue = "49347")]
+    pub fn get_key_value<Q: ?Sized>(&self, k: &Q) -> Option<(&K, &V)>
+        where K: Borrow<Q>,
+              Q: Hash + Eq
+    {
+        self.search(k).map(|bucket| bucket.into_refs())
+    }
+
     /// Returns true if the map contains a value for the specified key.
     ///
     /// The key may be any borrowed form of the map's key type, but
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index f8dbe193fed27..3d0c96585b552 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -56,7 +56,6 @@ use any::TypeId;
 use borrow::Cow;
 use cell;
 use char;
-use convert;
 use core::array;
 use fmt::{self, Debug, Display};
 use mem::transmute;
@@ -276,14 +275,14 @@ impl Error for num::ParseIntError {
     }
 }
 
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl Error for num::TryFromIntError {
     fn description(&self) -> &str {
         self.__description()
     }
 }
 
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl Error for array::TryFromSliceError {
     fn description(&self) -> &str {
         self.__description()
@@ -357,7 +356,7 @@ impl Error for cell::BorrowMutError {
     }
 }
 
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl Error for char::CharTryFromError {
     fn description(&self) -> &str {
         "converted integer out of range for `char`"
@@ -371,14 +370,6 @@ impl Error for char::ParseCharError {
     }
 }
 
-#[unstable(feature = "try_from", issue = "33417")]
-impl Error for convert::Infallible {
-    fn description(&self) -> &str {
-        match *self {
-        }
-    }
-}
-
 // copied from any.rs
 impl Error + 'static {
     /// Returns true if the boxed type is the same as `T`
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index a760922115aef..ceb019bc95b4c 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -780,7 +780,7 @@ impl f32 {
         unsafe { cmath::atanf(self) }
     }
 
-    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
+    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
     ///
     /// * `x = 0`, `y = 0`: `0`
     /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
@@ -791,12 +791,13 @@ impl f32 {
     /// use std::f32;
     ///
     /// let pi = f32::consts::PI;
-    /// // All angles from horizontal right (+x)
-    /// // 45 deg counter-clockwise
+    /// // Positive angles measured counter-clockwise
+    /// // from positive x axis
+    /// // -pi/4 radians (45 deg clockwise)
     /// let x1 = 3.0f32;
     /// let y1 = -3.0f32;
     ///
-    /// // 135 deg clockwise
+    /// // 3pi/4 radians (135 deg counter-clockwise)
     /// let x2 = -3.0f32;
     /// let y2 = 3.0f32;
     ///
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index 6f34f176a9711..97adf108b73b0 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -716,7 +716,7 @@ impl f64 {
         unsafe { cmath::atan(self) }
     }
 
-    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
+    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
     ///
     /// * `x = 0`, `y = 0`: `0`
     /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
@@ -727,12 +727,13 @@ impl f64 {
     /// use std::f64;
     ///
     /// let pi = f64::consts::PI;
-    /// // All angles from horizontal right (+x)
-    /// // 45 deg counter-clockwise
+    /// // Positive angles measured counter-clockwise
+    /// // from positive x axis
+    /// // -pi/4 radians (45 deg clockwise)
     /// let x1 = 3.0_f64;
     /// let y1 = -3.0_f64;
     ///
-    /// // 135 deg clockwise
+    /// // 3pi/4 radians (135 deg counter-clockwise)
     /// let x2 = -3.0_f64;
     /// let y2 = 3.0_f64;
     ///
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index db52ed67d3a85..5caa703ee97e3 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -906,7 +906,13 @@ impl Metadata {
         FileType(self.0.file_type())
     }
 
-    /// Returns whether this metadata is for a directory.
+    /// Returns whether this metadata is for a directory. The
+    /// result is mutually exclusive to the result of
+    /// [`is_file`], and will be false for symlink metadata
+    /// obtained from [`symlink_metadata`].
+    ///
+    /// [`is_file`]: struct.Metadata.html#method.is_file
+    /// [`symlink_metadata`]: fn.symlink_metadata.html
     ///
     /// # Examples
     ///
@@ -923,7 +929,13 @@ impl Metadata {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_dir(&self) -> bool { self.file_type().is_dir() }
 
-    /// Returns whether this metadata is for a regular file.
+    /// Returns whether this metadata is for a regular file. The
+    /// result is mutually exclusive to the result of
+    /// [`is_dir`], and will be false for symlink metadata
+    /// obtained from [`symlink_metadata`].
+    ///
+    /// [`is_dir`]: struct.Metadata.html#method.is_dir
+    /// [`symlink_metadata`]: fn.symlink_metadata.html
     ///
     /// # Examples
     ///
@@ -1148,7 +1160,13 @@ impl Permissions {
 }
 
 impl FileType {
-    /// Test whether this file type represents a directory.
+    /// Test whether this file type represents a directory. The
+    /// result is mutually exclusive to the results of
+    /// [`is_file`] and [`is_symlink`]; only zero or one of these
+    /// tests may pass.
+    ///
+    /// [`is_file`]: struct.FileType.html#method.is_file
+    /// [`is_symlink`]: struct.FileType.html#method.is_symlink
     ///
     /// # Examples
     ///
@@ -1167,6 +1185,12 @@ impl FileType {
     pub fn is_dir(&self) -> bool { self.0.is_dir() }
 
     /// Test whether this file type represents a regular file.
+    /// The result is  mutually exclusive to the results of
+    /// [`is_dir`] and [`is_symlink`]; only zero or one of these
+    /// tests may pass.
+    ///
+    /// [`is_dir`]: struct.FileType.html#method.is_dir
+    /// [`is_symlink`]: struct.FileType.html#method.is_symlink
     ///
     /// # Examples
     ///
@@ -1185,6 +1209,9 @@ impl FileType {
     pub fn is_file(&self) -> bool { self.0.is_file() }
 
     /// Test whether this file type represents a symbolic link.
+    /// The result is mutually exclusive to the results of
+    /// [`is_dir`] and [`is_file`]; only zero or one of these
+    /// tests may pass.
     ///
     /// The underlying [`Metadata`] struct needs to be retrieved
     /// with the [`fs::symlink_metadata`] function and not the
@@ -1195,6 +1222,8 @@ impl FileType {
     /// [`Metadata`]: struct.Metadata.html
     /// [`fs::metadata`]: fn.metadata.html
     /// [`fs::symlink_metadata`]: fn.symlink_metadata.html
+    /// [`is_dir`]: struct.FileType.html#method.is_dir
+    /// [`is_file`]: struct.FileType.html#method.is_file
     /// [`is_symlink`]: struct.FileType.html#method.is_symlink
     ///
     /// # Examples
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 9250c1c437b2a..ccaa19acc8379 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -168,8 +168,36 @@ impl<R: Read> BufReader<R> {
     /// # }
     /// ```
     #[unstable(feature = "bufreader_is_empty", issue = "45323", reason = "recently added")]
+    #[rustc_deprecated(since = "1.26.0", reason = "use .buffer().is_empty() instead")]
     pub fn is_empty(&self) -> bool {
-        self.pos == self.cap
+        self.buffer().is_empty()
+    }
+
+    /// Returns a reference to the internally buffered data.
+    ///
+    /// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(bufreader_buffer)]
+    /// use std::io::{BufReader, BufRead};
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let f = File::open("log.txt")?;
+    /// let mut reader = BufReader::new(f);
+    /// assert!(reader.buffer().is_empty());
+    ///
+    /// if reader.fill_buf()?.len() > 0 {
+    ///     assert!(!reader.buffer().is_empty());
+    /// }
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[unstable(feature = "bufreader_buffer", issue = "45323")]
+    pub fn buffer(&self) -> &[u8] {
+        &self.buf[self.pos..self.cap]
     }
 
     /// Unwraps this `BufReader`, returning the underlying reader.
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 76bcb5fedc94a..2673f3ccfa3ab 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -10,7 +10,6 @@
 
 use io::prelude::*;
 
-use core::convert::TryInto;
 use cmp;
 use io::{self, Initializer, SeekFrom, Error, ErrorKind};
 
@@ -260,9 +259,26 @@ fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<us
     Ok(amt)
 }
 
+/// Compensate removal of some impls per
+/// https://github.com/rust-lang/rust/pull/49305#issuecomment-376293243
+#[cfg(any(target_pointer_width = "16",
+          target_pointer_width = "32"))]
+fn try_into(n: u64) -> Result<usize, ()> {
+    if n <= (<usize>::max_value() as u64) {
+        Ok(n as usize)
+    } else {
+        Err(())
+    }
+}
+
+#[cfg(any(target_pointer_width = "64"))]
+fn try_into(n: u64) -> Result<usize, ()> {
+    Ok(n as usize)
+}
+
 // Resizing write implementation
 fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
-    let pos: usize = (*pos_mut).try_into().map_err(|_| {
+    let pos: usize = try_into(*pos_mut).map_err(|_| {
         Error::new(ErrorKind::InvalidInput,
                     "cursor position exceeds maximum possible vector length")
     })?;
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 5c0a83fde102f..15a22443b6af7 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -267,10 +267,9 @@
 #![feature(fn_traits)]
 #![feature(fnbox)]
 #![feature(generic_param_attrs)]
-#![feature(hashmap_hasher)]
+#![feature(hashmap_internals)]
 #![feature(heap_api)]
-#![feature(i128)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type, i128))]
 #![feature(int_error_internals)]
 #![feature(integer_atomics)]
 #![feature(into_cow)]
@@ -299,7 +298,6 @@
 #![feature(raw)]
 #![feature(rustc_attrs)]
 #![feature(stdsimd)]
-#![feature(sip_hash_13)]
 #![feature(slice_bytes)]
 #![feature(slice_concat_ext)]
 #![feature(slice_internals)]
@@ -309,11 +307,9 @@
 #![feature(str_char)]
 #![feature(str_internals)]
 #![feature(str_utf16)]
-#![feature(termination_trait)]
 #![feature(test, rustc_private)]
 #![feature(thread_local)]
 #![feature(toowned_clone_into)]
-#![feature(try_from)]
 #![feature(try_reserve)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
@@ -326,6 +322,7 @@
 #![cfg_attr(test, feature(update_panic_count))]
 #![cfg_attr(windows, feature(used))]
 #![cfg_attr(stage0, feature(never_type))]
+#![cfg_attr(stage0, feature(termination_trait))]
 
 #![default_lib_allocator]
 
@@ -436,7 +433,7 @@ pub use core::i16;
 pub use core::i32;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::i64;
-#[unstable(feature = "i128", issue = "35118")]
+#[stable(feature = "i128", since = "1.26.0")]
 pub use core::i128;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::usize;
@@ -466,7 +463,7 @@ pub use alloc::string;
 pub use alloc::vec;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use std_unicode::char;
-#[unstable(feature = "i128", issue = "35118")]
+#[stable(feature = "i128", since = "1.26.0")]
 pub use core::u128;
 
 pub mod f32;
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 000f971361530..47609f17221ef 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -335,6 +335,18 @@ pub mod builtin {
     /// proxied through this one.  `format_args!`, unlike its derived macros, avoids
     /// heap allocations.
     ///
+    /// You can use the [`fmt::Arguments`] value that `format_args!` returns
+    /// in `Debug` and `Display` contexts as seen below. The example also shows
+    /// that `Debug` and `Display` format to the same thing: the interpolated
+    /// format string in `format_args!`.
+    ///
+    /// ```rust
+    /// let display = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
+    /// let debug = format!("{}", format_args!("{} foo {:?}", 1, 2));
+    /// assert_eq!("1 foo 2", display);
+    /// assert_eq!(display, debug);
+    /// ```
+    ///
     /// For more information, see the documentation in [`std::fmt`].
     ///
     /// [`Display`]: ../std/fmt/trait.Display.html
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index fa430939f058c..bc2c9f522d3b0 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -28,6 +28,9 @@ use slice;
 /// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and
 /// [`SocketAddrV6`]'s respective documentation for more details.
 ///
+/// The size of a `SocketAddr` instance may vary depending on the target operating
+/// system.
+///
 /// [IP address]: ../../std/net/enum.IpAddr.html
 /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
 /// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
@@ -61,6 +64,9 @@ pub enum SocketAddr {
 ///
 /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
 ///
+/// The size of a `SocketAddrV4` struct may vary depending on the target operating
+/// system.
+///
 /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
 /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
 /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
@@ -88,6 +94,9 @@ pub struct SocketAddrV4 { inner: c::sockaddr_in }
 ///
 /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
 ///
+/// The size of a `SocketAddrV6` struct may vary depending on the target operating
+/// system.
+///
 /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
 /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
 /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 0d73a6f4fd7f4..25fa909553638 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -26,6 +26,9 @@ use sys_common::{AsInner, FromInner};
 /// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their
 /// respective documentation for more details.
 ///
+/// The size of an `IpAddr` instance may vary depending on the target operating
+/// system.
+///
 /// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
 /// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
 ///
@@ -61,6 +64,9 @@ pub enum IpAddr {
 ///
 /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
 ///
+/// The size of an `Ipv4Addr` struct may vary depending on the target operating
+/// system.
+///
 /// [IETF RFC 791]: https://tools.ietf.org/html/rfc791
 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html
 ///
@@ -93,6 +99,9 @@ pub struct Ipv4Addr {
 ///
 /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
 ///
+/// The size of an `Ipv6Addr` struct may vary depending on the target operating
+/// system.
+///
 /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html
 ///
@@ -1346,7 +1355,7 @@ impl FromInner<c::in6_addr> for Ipv6Addr {
     }
 }
 
-#[unstable(feature = "i128", issue = "35118")]
+#[stable(feature = "i128", since = "1.26.0")]
 impl From<Ipv6Addr> for u128 {
     fn from(ip: Ipv6Addr) -> u128 {
         let ip = ip.segments();
@@ -1355,7 +1364,7 @@ impl From<Ipv6Addr> for u128 {
             ((ip[6] as u128) << 16) + (ip[7] as u128)
     }
 }
-#[unstable(feature = "i128", issue = "35118")]
+#[stable(feature = "i128", since = "1.26.0")]
 impl From<u128> for Ipv6Addr {
     fn from(ip: u128) -> Ipv6Addr {
         Ipv6Addr::new(
diff --git a/src/libstd/num.rs b/src/libstd/num.rs
index 0c618370ac212..aa806b947b097 100644
--- a/src/libstd/num.rs
+++ b/src/libstd/num.rs
@@ -22,15 +22,8 @@ pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError}
 pub use core::num::Wrapping;
 
 #[unstable(feature = "nonzero", issue = "49137")]
-pub use core::num::{
-    NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32,
-    NonZeroU64, NonZeroI64, NonZeroUsize, NonZeroIsize,
-};
-
-// Change this to `#[unstable(feature = "i128", issue = "35118")]`
-// if other NonZero* integer types are stabilizied before 128-bit integers
-#[unstable(feature = "nonzero", issue = "49137")]
-pub use core::num::{NonZeroU128, NonZeroI128};
+#[allow(deprecated)]
+pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
 
 #[cfg(test)] use fmt;
 #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
@@ -180,7 +173,6 @@ mod tests {
 
     macro_rules! test_checked_next_power_of_two {
         ($test_name:ident, $T:ident) => (
-            #[cfg_attr(target_os = "emscripten", ignore)] // FIXME(#39119)
             fn $test_name() {
                 #![test]
                 assert_eq!((0 as $T).checked_next_power_of_two(), Some(1));
diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs
index feedd4e1abe5f..d5b7c68a3fa86 100644
--- a/src/libstd/prelude/v1.rs
+++ b/src/libstd/prelude/v1.rs
@@ -35,6 +35,8 @@
 #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From};
+#[stable(feature = "try_from", since = "1.26.0")]
+#[doc(no_inline)] pub use convert::{TryFrom, TryInto};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use default::Default;
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index e6e6be2e45379..ce4bbfffc2e47 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -751,7 +751,7 @@ mod prim_i64 { }
 /// The 128-bit signed integer type.
 ///
 /// *[See also the `std::i128` module](i128/index.html).*
-#[unstable(feature = "i128", issue="35118")]
+#[stable(feature = "i128", since="1.26.0")]
 mod prim_i128 { }
 
 #[doc(primitive = "u8")]
@@ -791,7 +791,7 @@ mod prim_u64 { }
 /// The 128-bit unsigned integer type.
 ///
 /// *[See also the `std::u128` module](u128/index.html).*
-#[unstable(feature = "i128", issue="35118")]
+#[stable(feature = "i128", since="1.26.0")]
 mod prim_u128 { }
 
 #[doc(primitive = "isize")]
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index d5ac2d19e831f..92e9f48f7ebef 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -1442,8 +1442,9 @@ pub fn id() -> u32 {
 /// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
 #[cfg_attr(not(test), lang = "termination")]
 #[unstable(feature = "termination_trait_lib", issue = "43301")]
-#[rustc_on_unimplemented =
-  "`main` can only return types that implement {Termination}, not `{Self}`"]
+#[rustc_on_unimplemented(
+  message="`main` has invalid return type `{Self}`",
+  label="`main` can only return types that implement `{Termination}`")]
 pub trait Termination {
     /// Is called to get the representation of the value as status code.
     /// This status code is returned to the operating system.
diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs
index ad437658d144a..ba80cbe47c824 100644
--- a/src/libstd/sys/unix/ext/net.rs
+++ b/src/libstd/sys/unix/ext/net.rs
@@ -51,13 +51,11 @@ use libc::MSG_NOSIGNAL;
 const MSG_NOSIGNAL: libc::c_int = 0x0;
 
 fn sun_path_offset() -> usize {
-    unsafe {
-        // Work with an actual instance of the type since using a null pointer is UB
-        let addr: libc::sockaddr_un = mem::uninitialized();
-        let base = &addr as *const _ as usize;
-        let path = &addr.sun_path as *const _ as usize;
-        path - base
-    }
+    // Work with an actual instance of the type since using a null pointer is UB
+    let addr: libc::sockaddr_un = unsafe { mem::uninitialized() };
+    let base = &addr as *const _ as usize;
+    let path = &addr.sun_path as *const _ as usize;
+    path - base
 }
 
 unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs
index 3f65975e60880..04d9f0b06d344 100644
--- a/src/libstd/sys/unix/net.rs
+++ b/src/libstd/sys/unix/net.rs
@@ -383,12 +383,12 @@ impl IntoInner<c_int> for Socket {
 // believe it's thread-safe).
 #[cfg(target_env = "gnu")]
 fn on_resolver_failure() {
+    use sys;
+
     // If the version fails to parse, we treat it the same as "not glibc".
-    if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) {
-        if let Some(version) = parse_glibc_version(version_str) {
-            if version < (2, 26) {
-                unsafe { libc::res_init() };
-            }
+    if let Some(version) = sys::os::glibc_version() {
+        if version < (2, 26) {
+            unsafe { libc::res_init() };
         }
     }
 }
@@ -396,29 +396,6 @@ fn on_resolver_failure() {
 #[cfg(not(target_env = "gnu"))]
 fn on_resolver_failure() {}
 
-#[cfg(target_env = "gnu")]
-fn glibc_version_cstr() -> Option<&'static CStr> {
-    weak! {
-        fn gnu_get_libc_version() -> *const libc::c_char
-    }
-    if let Some(f) = gnu_get_libc_version.get() {
-        unsafe { Some(CStr::from_ptr(f())) }
-    } else {
-        None
-    }
-}
-
-// Returns Some((major, minor)) if the string is a valid "x.y" version,
-// ignoring any extra dot-separated parts. Otherwise return None.
-#[cfg(target_env = "gnu")]
-fn parse_glibc_version(version: &str) -> Option<(usize, usize)> {
-    let mut parsed_ints = version.split(".").map(str::parse::<usize>).fuse();
-    match (parsed_ints.next(), parsed_ints.next()) {
-        (Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)),
-        _ => None
-    }
-}
-
 #[cfg(all(test, taget_env = "gnu"))]
 mod test {
     use super::*;
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index a46e855b4a6f4..4c86fddee4b45 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -546,3 +546,35 @@ pub fn getpid() -> u32 {
 pub fn getppid() -> u32 {
     unsafe { libc::getppid() as u32 }
 }
+
+#[cfg(target_env = "gnu")]
+pub fn glibc_version() -> Option<(usize, usize)> {
+    if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) {
+        parse_glibc_version(version_str)
+    } else {
+        None
+    }
+}
+
+#[cfg(target_env = "gnu")]
+fn glibc_version_cstr() -> Option<&'static CStr> {
+    weak! {
+        fn gnu_get_libc_version() -> *const libc::c_char
+    }
+    if let Some(f) = gnu_get_libc_version.get() {
+        unsafe { Some(CStr::from_ptr(f())) }
+    } else {
+        None
+    }
+}
+
+// Returns Some((major, minor)) if the string is a valid "x.y" version,
+// ignoring any extra dot-separated parts. Otherwise return None.
+#[cfg(target_env = "gnu")]
+fn parse_glibc_version(version: &str) -> Option<(usize, usize)> {
+    let mut parsed_ints = version.split(".").map(str::parse::<usize>).fuse();
+    match (parsed_ints.next(), parsed_ints.next()) {
+        (Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)),
+        _ => None
+    }
+}
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index d0486f06a143a..b7f30600b8a4c 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -184,6 +184,10 @@ impl Command {
         let maybe_env = self.env.capture_if_changed();
         maybe_env.map(|env| construct_envp(env, &mut self.saw_nul))
     }
+    #[allow(dead_code)]
+    pub fn env_saw_path(&self) -> bool {
+        self.env.have_changed_path()
+    }
 
     pub fn setup_io(&self, default: Stdio, needs_stdin: bool)
                 -> io::Result<(StdioPipes, ChildPipes)> {
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index 189280a4ba9a8..9d6d607e3f340 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -34,6 +34,11 @@ impl Command {
         }
 
         let (ours, theirs) = self.setup_io(default, needs_stdin)?;
+
+        if let Some(ret) = self.posix_spawn(&theirs, envp.as_ref())? {
+            return Ok((ret, ours))
+        }
+
         let (input, output) = sys::pipe::anon_pipe()?;
 
         let pid = unsafe {
@@ -229,6 +234,119 @@ impl Command {
         libc::execvp(self.get_argv()[0], self.get_argv().as_ptr());
         io::Error::last_os_error()
     }
+
+    #[cfg(not(any(target_os = "macos", target_os = "freebsd",
+                  all(target_os = "linux", target_env = "gnu"))))]
+    fn posix_spawn(&mut self, _: &ChildPipes, _: Option<&CStringArray>)
+        -> io::Result<Option<Process>>
+    {
+        Ok(None)
+    }
+
+    // Only support platforms for which posix_spawn() can return ENOENT
+    // directly.
+    #[cfg(any(target_os = "macos", target_os = "freebsd",
+              all(target_os = "linux", target_env = "gnu")))]
+    fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>)
+        -> io::Result<Option<Process>>
+    {
+        use mem;
+        use sys;
+
+        if self.get_cwd().is_some() ||
+            self.get_gid().is_some() ||
+            self.get_uid().is_some() ||
+            self.env_saw_path() ||
+            self.get_closures().len() != 0 {
+            return Ok(None)
+        }
+
+        // Only glibc 2.24+ posix_spawn() supports returning ENOENT directly.
+        #[cfg(all(target_os = "linux", target_env = "gnu"))]
+        {
+            if let Some(version) = sys::os::glibc_version() {
+                if version < (2, 24) {
+                    return Ok(None)
+                }
+            } else {
+                return Ok(None)
+            }
+        }
+
+        let mut p = Process { pid: 0, status: None };
+
+        struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t);
+
+        impl Drop for PosixSpawnFileActions {
+            fn drop(&mut self) {
+                unsafe {
+                    libc::posix_spawn_file_actions_destroy(&mut self.0);
+                }
+            }
+        }
+
+        struct PosixSpawnattr(libc::posix_spawnattr_t);
+
+        impl Drop for PosixSpawnattr {
+            fn drop(&mut self) {
+                unsafe {
+                    libc::posix_spawnattr_destroy(&mut self.0);
+                }
+            }
+        }
+
+        unsafe {
+            let mut file_actions = PosixSpawnFileActions(mem::uninitialized());
+            let mut attrs = PosixSpawnattr(mem::uninitialized());
+
+            libc::posix_spawnattr_init(&mut attrs.0);
+            libc::posix_spawn_file_actions_init(&mut file_actions.0);
+
+            if let Some(fd) = stdio.stdin.fd() {
+                cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
+                                                           fd,
+                                                           libc::STDIN_FILENO))?;
+            }
+            if let Some(fd) = stdio.stdout.fd() {
+                cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
+                                                           fd,
+                                                           libc::STDOUT_FILENO))?;
+            }
+            if let Some(fd) = stdio.stderr.fd() {
+                cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
+                                                           fd,
+                                                           libc::STDERR_FILENO))?;
+            }
+
+            let mut set: libc::sigset_t = mem::uninitialized();
+            cvt(libc::sigemptyset(&mut set))?;
+            cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0,
+                                                 &set))?;
+            cvt(libc::sigaddset(&mut set, libc::SIGPIPE))?;
+            cvt(libc::posix_spawnattr_setsigdefault(&mut attrs.0,
+                                                    &set))?;
+
+            let flags = libc::POSIX_SPAWN_SETSIGDEF |
+                libc::POSIX_SPAWN_SETSIGMASK;
+            cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?;
+
+            let envp = envp.map(|c| c.as_ptr())
+                .unwrap_or(*sys::os::environ() as *const _);
+            let ret = libc::posix_spawnp(
+                &mut p.pid,
+                self.get_argv()[0],
+                &file_actions.0,
+                &attrs.0,
+                self.get_argv().as_ptr() as *const _,
+                envp as *const _,
+            );
+            if ret == 0 {
+                Ok(Some(p))
+            } else {
+                Err(io::Error::from_raw_os_error(ret))
+            }
+        }
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index f1ab9c4760965..afa8e3e136935 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -10,7 +10,6 @@
 
 #![unstable(feature = "process_internals", issue = "0")]
 
-use ascii::AsciiExt;
 use collections::BTreeMap;
 use env::split_paths;
 use env;
diff --git a/src/libstd/sys_common/process.rs b/src/libstd/sys_common/process.rs
index fd1a5fdb4109b..d0c5951bd6c0a 100644
--- a/src/libstd/sys_common/process.rs
+++ b/src/libstd/sys_common/process.rs
@@ -47,6 +47,7 @@ impl EnvKey for DefaultEnvKey {}
 #[derive(Clone, Debug)]
 pub struct CommandEnv<K> {
     clear: bool,
+    saw_path: bool,
     vars: BTreeMap<K, Option<OsString>>
 }
 
@@ -54,6 +55,7 @@ impl<K: EnvKey> Default for CommandEnv<K> {
     fn default() -> Self {
         CommandEnv {
             clear: false,
+            saw_path: false,
             vars: Default::default()
         }
     }
@@ -108,9 +110,11 @@ impl<K: EnvKey> CommandEnv<K> {
 
     // The following functions build up changes
     pub fn set(&mut self, key: &OsStr, value: &OsStr) {
+        self.maybe_saw_path(&key);
         self.vars.insert(key.to_owned().into(), Some(value.to_owned()));
     }
     pub fn remove(&mut self, key: &OsStr) {
+        self.maybe_saw_path(&key);
         if self.clear {
             self.vars.remove(key);
         } else {
@@ -121,4 +125,12 @@ impl<K: EnvKey> CommandEnv<K> {
         self.clear = true;
         self.vars.clear();
     }
+    pub fn have_changed_path(&self) -> bool {
+        self.saw_path || self.clear
+    }
+    fn maybe_saw_path(&mut self, key: &OsStr) {
+        if !self.saw_path && key == "PATH" {
+            self.saw_path = true;
+        }
+    }
 }
diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs
index 9fff8b91f96f3..78b2bb5fe6e2f 100644
--- a/src/libstd/sys_common/wtf8.rs
+++ b/src/libstd/sys_common/wtf8.rs
@@ -27,7 +27,6 @@
 
 use core::str::next_code_point;
 
-use ascii::*;
 use borrow::Cow;
 use char;
 use fmt;
@@ -871,24 +870,22 @@ impl Hash for Wtf8 {
     }
 }
 
-impl AsciiExt for Wtf8 {
-    type Owned = Wtf8Buf;
-
-    fn is_ascii(&self) -> bool {
+impl Wtf8 {
+    pub fn is_ascii(&self) -> bool {
         self.bytes.is_ascii()
     }
-    fn to_ascii_uppercase(&self) -> Wtf8Buf {
+    pub fn to_ascii_uppercase(&self) -> Wtf8Buf {
         Wtf8Buf { bytes: self.bytes.to_ascii_uppercase() }
     }
-    fn to_ascii_lowercase(&self) -> Wtf8Buf {
+    pub fn to_ascii_lowercase(&self) -> Wtf8Buf {
         Wtf8Buf { bytes: self.bytes.to_ascii_lowercase() }
     }
-    fn eq_ignore_ascii_case(&self, other: &Wtf8) -> bool {
+    pub fn eq_ignore_ascii_case(&self, other: &Wtf8) -> bool {
         self.bytes.eq_ignore_ascii_case(&other.bytes)
     }
 
-    fn make_ascii_uppercase(&mut self) { self.bytes.make_ascii_uppercase() }
-    fn make_ascii_lowercase(&mut self) { self.bytes.make_ascii_lowercase() }
+    pub fn make_ascii_uppercase(&mut self) { self.bytes.make_ascii_uppercase() }
+    pub fn make_ascii_lowercase(&mut self) { self.bytes.make_ascii_lowercase() }
 }
 
 #[cfg(test)]
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 12f2a9bb85f83..7256ac43e27e4 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -49,6 +49,9 @@ pub use core::time::Duration;
 /// allows measuring the duration between two instants (or comparing two
 /// instants).
 ///
+/// The size of an `Instant` struct may vary depending on the target operating
+/// system.
+///
 /// Example:
 ///
 /// ```no_run
@@ -88,6 +91,9 @@ pub struct Instant(time::Instant);
 /// fixed point in time, a `SystemTime` can be converted to a human-readable time,
 /// or perhaps some other string representation.
 ///
+/// The size of a `SystemTime` struct may vary depending on the target operating
+/// system.
+///
 /// [`Instant`]: ../../std/time/struct.Instant.html
 /// [`Result`]: ../../std/result/enum.Result.html
 /// [`Duration`]: ../../std/time/struct.Duration.html
diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs
index de8b46d5f1b02..33e47ade8cb9c 100644
--- a/src/libstd_unicode/char.rs
+++ b/src/libstd_unicode/char.rs
@@ -42,7 +42,7 @@ pub use core::char::{EscapeDebug, EscapeDefault, EscapeUnicode};
 pub use core::char::ParseCharError;
 
 // unstable re-exports
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 pub use core::char::CharTryFromError;
 #[unstable(feature = "decode_utf8", issue = "33906")]
 pub use core::char::{DecodeUtf8, decode_utf8};
diff --git a/src/libstd_unicode/lib.rs b/src/libstd_unicode/lib.rs
index f155b62e3cc72..c22ea1671fa59 100644
--- a/src/libstd_unicode/lib.rs
+++ b/src/libstd_unicode/lib.rs
@@ -39,7 +39,6 @@
 #![feature(lang_items)]
 #![feature(non_exhaustive)]
 #![feature(staged_api)]
-#![feature(try_from)]
 #![feature(unboxed_closures)]
 
 mod bool_trie;
diff --git a/src/libsyntax/README.md b/src/libsyntax/README.md
index 3bf735ee86803..7214203830e74 100644
--- a/src/libsyntax/README.md
+++ b/src/libsyntax/README.md
@@ -1,7 +1,9 @@
-NB: This crate is part of the Rust compiler. For an overview of the
-compiler as a whole, see
-[the README.md file found in `librustc`](../librustc/README.md).
-
 The `syntax` crate contains those things concerned purely with syntax
 – that is, the AST ("abstract syntax tree"), parser, pretty-printer,
 lexer, macro expander, and utilities for traversing ASTs.
+
+For more information about how these things work in rustc, see the
+rustc guide:
+
+- [Parsing](https://rust-lang-nursery.github.io/rustc-guide/the-parser.html)
+- [Macro Expansion](https://rust-lang-nursery.github.io/rustc-guide/macro-expansion.html)
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 8b3a7164cccb6..a3af6b247ee2f 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -108,17 +108,16 @@ impl Path {
         }
     }
 
-    // Add starting "crate root" segment to all paths except those that
-    // already have it or start with `self`, `super`, `Self` or `$crate`.
-    pub fn default_to_global(mut self) -> Path {
-        if !self.is_global() {
-            let ident = self.segments[0].identifier;
-            if !::parse::token::Ident(ident).is_path_segment_keyword() ||
-               ident.name == keywords::Crate.name() {
-                self.segments.insert(0, PathSegment::crate_root(self.span));
+    // Make a "crate root" segment for this path unless it already has it
+    // or starts with something like `self`/`super`/`$crate`/etc.
+    pub fn make_root(&self) -> Option<PathSegment> {
+        if let Some(ident) = self.segments.get(0).map(|seg| seg.identifier) {
+            if ::parse::token::is_path_segment_keyword(ident) &&
+               ident.name != keywords::Crate.name() {
+                return None;
             }
         }
-        self
+        Some(PathSegment::crate_root(self.span.shrink_to_lo()))
     }
 
     pub fn is_global(&self) -> bool {
@@ -1878,20 +1877,37 @@ pub struct Variant_ {
 
 pub type Variant = Spanned<Variant_>;
 
+/// Part of `use` item to the right of its prefix.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum UseTreeKind {
-    Simple(Ident),
-    Glob,
+    /// `use prefix` or `use prefix as rename`
+    Simple(Option<Ident>),
+    /// `use prefix::{...}`
     Nested(Vec<(UseTree, NodeId)>),
+    /// `use prefix::*`
+    Glob,
 }
 
+/// A tree of paths sharing common prefixes.
+/// Used in `use` items both at top-level and inside of braces in import groups.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct UseTree {
-    pub kind: UseTreeKind,
     pub prefix: Path,
+    pub kind: UseTreeKind,
     pub span: Span,
 }
 
+impl UseTree {
+    pub fn ident(&self) -> Ident {
+        match self.kind {
+            UseTreeKind::Simple(Some(rename)) => rename,
+            UseTreeKind::Simple(None) =>
+                self.prefix.segments.last().expect("empty prefix in a simple import").identifier,
+            _ => panic!("`UseTree::ident` can only be used on a simple import"),
+        }
+    }
+}
+
 /// Distinguishes between Attributes that decorate items and Attributes that
 /// are contained as statements within items. These two cases need to be
 /// distinguished for pretty-printing.
@@ -2055,7 +2071,7 @@ pub struct Item {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum ItemKind {
-    /// An `extern crate` item, with optional original crate name.
+    /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
     ///
     /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
     ExternCrate(Option<Name>),
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index f2cdcda98da51..5954b9eb27475 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -1106,7 +1106,8 @@ impl IntType {
 
 impl MetaItem {
     fn tokens(&self) -> TokenStream {
-        let ident = TokenTree::Token(self.span, Token::Ident(Ident::with_empty_ctxt(self.name)));
+        let ident = TokenTree::Token(self.span,
+                                     Token::from_ast_ident(Ident::with_empty_ctxt(self.name)));
         TokenStream::concat(vec![ident.into(), self.node.tokens(self.span)])
     }
 
@@ -1114,9 +1115,9 @@ impl MetaItem {
         where I: Iterator<Item = TokenTree>,
     {
         let (span, name) = match tokens.next() {
-            Some(TokenTree::Token(span, Token::Ident(ident))) => (span, ident.name),
+            Some(TokenTree::Token(span, Token::Ident(ident, _))) => (span, ident.name),
             Some(TokenTree::Token(_, Token::Interpolated(ref nt))) => match nt.0 {
-                token::Nonterminal::NtIdent(ident) => (ident.span, ident.node.name),
+                token::Nonterminal::NtIdent(ident, _) => (ident.span, ident.node.name),
                 token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()),
                 _ => return None,
             },
@@ -1269,14 +1270,14 @@ impl LitKind {
                 "true"
             } else {
                 "false"
-            }))),
+            })), false),
         }
     }
 
     fn from_token(token: Token) -> Option<LitKind> {
         match token {
-            Token::Ident(ident) if ident.name == "true" => Some(LitKind::Bool(true)),
-            Token::Ident(ident) if ident.name == "false" => Some(LitKind::Bool(false)),
+            Token::Ident(ident, false) if ident.name == "true" => Some(LitKind::Bool(true)),
+            Token::Ident(ident, false) if ident.name == "false" => Some(LitKind::Bool(false)),
             Token::Interpolated(ref nt) => match nt.0 {
                 token::NtExpr(ref v) => match v.node {
                     ExprKind::Lit(ref lit) => Some(lit.node.clone()),
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index a1aec05208859..73924c4270e66 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -597,21 +597,6 @@ impl CodeMap {
         self.span_to_source(sp, |src, start_index, _| src[..start_index].to_string())
     }
 
-    /// Given a `Span`, try to get a shorter span ending before the first occurrence of `c` `char`
-    pub fn span_until_char(&self, sp: Span, c: char) -> Span {
-        match self.span_to_snippet(sp) {
-            Ok(snippet) => {
-                let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right();
-                if !snippet.is_empty() && !snippet.contains('\n') {
-                    sp.with_hi(BytePos(sp.lo().0 + snippet.len() as u32))
-                } else {
-                    sp
-                }
-            }
-            _ => sp,
-        }
-    }
-
     /// Extend the given `Span` to just after the previous occurrence of `c`. Return the same span
     /// if no character could be found or if an error occurred while retrieving the code snippet.
     pub fn span_extend_to_prev_char(&self, sp: Span, c: char) -> Span {
@@ -646,26 +631,50 @@ impl CodeMap {
         sp
     }
 
+    /// Given a `Span`, try to get a shorter span ending before the first occurrence of `c` `char`
+    pub fn span_until_char(&self, sp: Span, c: char) -> Span {
+        match self.span_to_snippet(sp) {
+            Ok(snippet) => {
+                let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right();
+                if !snippet.is_empty() && !snippet.contains('\n') {
+                    sp.with_hi(BytePos(sp.lo().0 + snippet.len() as u32))
+                } else {
+                    sp
+                }
+            }
+            _ => sp,
+        }
+    }
+
+    /// Given a `Span`, try to get a shorter span ending just after the first occurrence of `char`
+    /// `c`.
+    pub fn span_through_char(&self, sp: Span, c: char) -> Span {
+        if let Ok(snippet) = self.span_to_snippet(sp) {
+            if let Some(offset) = snippet.find(c) {
+                return sp.with_hi(BytePos(sp.lo().0 + (offset + c.len_utf8()) as u32));
+            }
+        }
+        sp
+    }
+
     /// Given a `Span`, get a new `Span` covering the first token and all its trailing whitespace or
     /// the original `Span`.
     ///
     /// If `sp` points to `"let mut x"`, then a span pointing at `"let "` will be returned.
     pub fn span_until_non_whitespace(&self, sp: Span) -> Span {
-        if let Ok(snippet) = self.span_to_snippet(sp) {
-            let mut offset = 0;
-            // get the bytes width of all the non-whitespace characters
-            for c in snippet.chars().take_while(|c| !c.is_whitespace()) {
-                offset += c.len_utf8();
-            }
-            // get the bytes width of all the whitespace characters after that
-            for c in snippet[offset..].chars().take_while(|c| c.is_whitespace()) {
-                offset += c.len_utf8();
+        let mut whitespace_found = false;
+
+        self.span_take_while(sp, |c| {
+            if !whitespace_found && c.is_whitespace() {
+                whitespace_found = true;
             }
-            if offset > 1 {
-                return sp.with_hi(BytePos(sp.lo().0 + offset as u32));
+
+            if whitespace_found && !c.is_whitespace() {
+                false
+            } else {
+                true
             }
-        }
-        sp
+        })
     }
 
     /// Given a `Span`, get a new `Span` covering the first token without its trailing whitespace or
@@ -673,28 +682,23 @@ impl CodeMap {
     ///
     /// If `sp` points to `"let mut x"`, then a span pointing at `"let"` will be returned.
     pub fn span_until_whitespace(&self, sp: Span) -> Span {
-        if let Ok(snippet) = self.span_to_snippet(sp) {
-            let mut offset = 0;
-            // Get the bytes width of all the non-whitespace characters
-            for c in snippet.chars().take_while(|c| !c.is_whitespace()) {
-                offset += c.len_utf8();
-            }
-            if offset > 1 {
-                return sp.with_hi(BytePos(sp.lo().0 + offset as u32));
-            }
-        }
-        sp
+        self.span_take_while(sp, |c| !c.is_whitespace())
     }
 
-    /// Given a `Span`, try to get a shorter span ending just after the first occurrence of `char`
-    /// `c`.
-    pub fn span_through_char(&self, sp: Span, c: char) -> Span {
+    /// Given a `Span`, get a shorter one until `predicate` yields false.
+    pub fn span_take_while<P>(&self, sp: Span, predicate: P) -> Span
+        where P: for <'r> FnMut(&'r char) -> bool
+    {
         if let Ok(snippet) = self.span_to_snippet(sp) {
-            if let Some(offset) = snippet.find(c) {
-                return sp.with_hi(BytePos(sp.lo().0 + (offset + c.len_utf8()) as u32));
-            }
+            let offset = snippet.chars()
+                .take_while(predicate)
+                .map(|c| c.len_utf8())
+                .sum::<usize>();
+
+            sp.with_hi(BytePos(sp.lo().0 + (offset as u32)))
+        } else {
+            sp
         }
-        sp
     }
 
     pub fn def_span(&self, sp: Span) -> Span {
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 6013c20daf235..56b1306e5b33f 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -13,7 +13,7 @@ use feature_gate::{feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features
 use {fold, attr};
 use ast;
 use codemap::Spanned;
-use epoch::Epoch;
+use edition::Edition;
 use parse::{token, ParseSess};
 
 use ptr::P;
@@ -27,7 +27,7 @@ pub struct StripUnconfigured<'a> {
 }
 
 // `cfg_attr`-process the crate's attributes and compute the crate's features.
-pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, epoch: Epoch)
+pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, edition: Edition)
                 -> (ast::Crate, Features) {
     let features;
     {
@@ -47,7 +47,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, epoc
             return (krate, Features::new());
         }
 
-        features = get_features(&sess.span_diagnostic, &krate.attrs, epoch);
+        features = get_features(&sess.span_diagnostic, &krate.attrs, edition);
 
         // Avoid reconfiguring malformed `cfg_attr`s
         if err_count == sess.span_diagnostic.err_count() {
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index 1f87c1b94c50d..bb7988e64bce9 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -250,7 +250,10 @@ An unstable feature was used.
 Erroneous code example:
 
 ```compile_fail,E658
-let x = ::std::u128::MAX; // error: use of unstable library feature 'i128'
+#[repr(u128)] // error: use of unstable library feature 'repr128'
+enum Foo {
+    Bar(u64),
+}
 ```
 
 If you're using a stable or a beta version of rustc, you won't be able to use
@@ -261,10 +264,11 @@ If you're using a nightly version of rustc, just add the corresponding feature
 to be able to use it:
 
 ```
-#![feature(i128)]
+#![feature(repr128)]
 
-fn main() {
-    let x = ::std::u128::MAX; // ok!
+#[repr(u128)] // ok!
+enum Foo {
+    Bar(u64),
 }
 ```
 "##,
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index e8c2d325bd653..aecf32ab6afb7 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -19,7 +19,7 @@ use ext::base::{ExtCtxt, MacEager, MacResult};
 use ext::build::AstBuilder;
 use parse::token;
 use ptr::P;
-use symbol::Symbol;
+use symbol::{keywords, Symbol};
 use tokenstream::{TokenTree};
 use util::small_vector::SmallVector;
 
@@ -44,7 +44,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
                                    token_tree: &[TokenTree])
                                    -> Box<MacResult+'cx> {
     let code = match (token_tree.len(), token_tree.get(0)) {
-        (1, Some(&TokenTree::Token(_, token::Ident(code)))) => code,
+        (1, Some(&TokenTree::Token(_, token::Ident(code, _)))) => code,
         _ => unreachable!()
     };
 
@@ -82,10 +82,10 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
         token_tree.get(1),
         token_tree.get(2)
     ) {
-        (1, Some(&TokenTree::Token(_, token::Ident(ref code))), None, None) => {
+        (1, Some(&TokenTree::Token(_, token::Ident(ref code, _))), None, None) => {
             (code, None)
         },
-        (3, Some(&TokenTree::Token(_, token::Ident(ref code))),
+        (3, Some(&TokenTree::Token(_, token::Ident(ref code, _))),
             Some(&TokenTree::Token(_, token::Comma)),
             Some(&TokenTree::Token(_, token::Literal(token::StrRaw(description, _), None)))) => {
             (code, Some(description))
@@ -150,9 +150,9 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
     let (crate_name, name) = match (&token_tree[0], &token_tree[2]) {
         (
             // Crate name.
-            &TokenTree::Token(_, token::Ident(ref crate_name)),
+            &TokenTree::Token(_, token::Ident(ref crate_name, _)),
             // DIAGNOSTICS ident.
-            &TokenTree::Token(_, token::Ident(ref name))
+            &TokenTree::Token(_, token::Ident(ref name, _))
         ) => (*&crate_name, name),
         _ => unreachable!()
     };
@@ -192,7 +192,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
             (descriptions.len(), ecx.expr_vec(span, descriptions))
         });
 
-    let static_ = ecx.lifetime(span, Ident::from_str("'static"));
+    let static_ = ecx.lifetime(span, keywords::StaticLifetime.ident());
     let ty_str = ecx.ty_rptr(
         span,
         ecx.ty_ident(span, ecx.ident_of("str")),
@@ -220,7 +220,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
                 ty,
                 expr,
             ),
-            vis: codemap::respan(span.empty(), ast::VisibilityKind::Public),
+            vis: codemap::respan(span.shrink_to_lo(), ast::VisibilityKind::Public),
             span,
             tokens: None,
         })
diff --git a/src/libsyntax/epoch.rs b/src/libsyntax/edition.rs
similarity index 56%
rename from src/libsyntax/epoch.rs
rename to src/libsyntax/edition.rs
index 32cbc79c550e3..61246d4493ca3 100644
--- a/src/libsyntax/epoch.rs
+++ b/src/libsyntax/edition.rs
@@ -11,58 +11,58 @@
 use std::fmt;
 use std::str::FromStr;
 
-/// The epoch of the compiler (RFC 2052)
+/// The edition of the compiler (RFC 2052)
 #[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)]
 #[non_exhaustive]
-pub enum Epoch {
-    // epochs must be kept in order, newest to oldest
+pub enum Edition {
+    // editions must be kept in order, newest to oldest
 
-    /// The 2015 epoch
-    Epoch2015,
-    /// The 2018 epoch
-    Epoch2018,
+    /// The 2015 edition
+    Edition2015,
+    /// The 2018 edition
+    Edition2018,
 
-    // when adding new epochs, be sure to update:
+    // when adding new editions, be sure to update:
     //
-    // - the list in the `parse_epoch` static in librustc::session::config
+    // - the list in the `parse_edition` static in librustc::session::config
     // - add a `rust_####()` function to the session
     // - update the enum in Cargo's sources as well
     //
-    // When -Zepoch becomes --epoch, there will
-    // also be a check for the epoch being nightly-only
+    // When -Zedition becomes --edition, there will
+    // also be a check for the edition being nightly-only
     // somewhere. That will need to be updated
-    // whenever we're stabilizing/introducing a new epoch
+    // whenever we're stabilizing/introducing a new edition
     // as well as changing the default Cargo template.
 }
 
 // must be in order from oldest to newest
-pub const ALL_EPOCHS: &[Epoch] = &[Epoch::Epoch2015, Epoch::Epoch2018];
+pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018];
 
-impl fmt::Display for Epoch {
+impl fmt::Display for Edition {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let s = match *self {
-            Epoch::Epoch2015 => "2015",
-            Epoch::Epoch2018 => "2018",
+            Edition::Edition2015 => "2015",
+            Edition::Edition2018 => "2018",
         };
         write!(f, "{}", s)
     }
 }
 
-impl Epoch {
+impl Edition {
     pub fn lint_name(&self) -> &'static str {
         match *self {
-            Epoch::Epoch2015 => "epoch_2015",
-            Epoch::Epoch2018 => "epoch_2018",
+            Edition::Edition2015 => "edition_2015",
+            Edition::Edition2018 => "edition_2018",
         }
     }
 }
 
-impl FromStr for Epoch {
+impl FromStr for Edition {
     type Err = ();
     fn from_str(s: &str) -> Result<Self, ()> {
         match s {
-            "2015" => Ok(Epoch::Epoch2015),
-            "2018" => Ok(Epoch::Epoch2018),
+            "2015" => Ok(Edition::Edition2015),
+            "2018" => Ok(Edition::Edition2018),
             _ => Err(())
         }
     }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 23c42972912a1..c3ae0fd2ca863 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -229,8 +229,9 @@ impl<F> TTMacroExpander for F
         impl Folder for AvoidInterpolatedIdents {
             fn fold_tt(&mut self, tt: tokenstream::TokenTree) -> tokenstream::TokenTree {
                 if let tokenstream::TokenTree::Token(_, token::Interpolated(ref nt)) = tt {
-                    if let token::NtIdent(ident) = nt.0 {
-                        return tokenstream::TokenTree::Token(ident.span, token::Ident(ident.node));
+                    if let token::NtIdent(ident, is_raw) = nt.0 {
+                        return tokenstream::TokenTree::Token(ident.span,
+                                                             token::Ident(ident.node, is_raw));
                     }
                 }
                 fold::noop_fold_tt(tt, self)
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index b88e064e7e56d..269517e998f5b 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -214,7 +214,7 @@ pub trait AstBuilder {
 
     fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::Arg;
     // FIXME unused self
-    fn fn_decl(&self, inputs: Vec<ast::Arg> , output: P<ast::Ty>) -> P<ast::FnDecl>;
+    fn fn_decl(&self, inputs: Vec<ast::Arg> , output: ast::FunctionRetTy) -> P<ast::FnDecl>;
 
     fn item_fn_poly(&self,
                     span: Span,
@@ -294,7 +294,7 @@ pub trait AstBuilder {
                 vis: ast::Visibility, vp: P<ast::UseTree>) -> P<ast::Item>;
     fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item>;
     fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
-                        ident: ast::Ident, path: ast::Path) -> P<ast::Item>;
+                        ident: Option<ast::Ident>, path: ast::Path) -> P<ast::Item>;
     fn item_use_list(&self, sp: Span, vis: ast::Visibility,
                      path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item>;
     fn item_use_glob(&self, sp: Span,
@@ -329,9 +329,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             None
         };
         segments.push(ast::PathSegment { identifier: last_identifier, span, parameters });
-        let path = ast::Path { span, segments };
-
-        if global { path.default_to_global() } else { path }
+        let mut path = ast::Path { span, segments };
+        if global {
+            if let Some(seg) = path.make_root() {
+                path.segments.insert(0, seg);
+            }
+        }
+        path
     }
 
     /// Constructs a qualified path.
@@ -920,7 +924,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
               -> P<ast::Expr> {
         let fn_decl = self.fn_decl(
             ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(),
-            self.ty_infer(span));
+            ast::FunctionRetTy::Default(span));
 
         // FIXME -- We are using `span` as the span of the `|...|`
         // part of the lambda, but it probably (maybe?) corresponds to
@@ -966,10 +970,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     // FIXME unused self
-    fn fn_decl(&self, inputs: Vec<ast::Arg>, output: P<ast::Ty>) -> P<ast::FnDecl> {
+    fn fn_decl(&self, inputs: Vec<ast::Arg>, output: ast::FunctionRetTy) -> P<ast::FnDecl> {
         P(ast::FnDecl {
             inputs,
-            output: ast::FunctionRetTy::Ty(output),
+            output,
             variadic: false
         })
     }
@@ -983,7 +987,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             attrs,
             id: ast::DUMMY_NODE_ID,
             node,
-            vis: respan(span.empty(), ast::VisibilityKind::Inherited),
+            vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
             span,
             tokens: None,
         })
@@ -999,7 +1003,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.item(span,
                   name,
                   Vec::new(),
-                  ast::ItemKind::Fn(self.fn_decl(inputs, output),
+                  ast::ItemKind::Fn(self.fn_decl(inputs, ast::FunctionRetTy::Ty(output)),
                               ast::Unsafety::Normal,
                               dummy_spanned(ast::Constness::NotConst),
                               Abi::Rust,
@@ -1029,7 +1033,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
                 span: ty.span,
                 ty,
                 ident: None,
-                vis: respan(span.empty(), ast::VisibilityKind::Inherited),
+                vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
                 attrs: Vec::new(),
                 id: ast::DUMMY_NODE_ID,
             }
@@ -1159,16 +1163,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item> {
-        let last = path.segments.last().unwrap().identifier;
-        self.item_use_simple_(sp, vis, last, path)
+        self.item_use_simple_(sp, vis, None, path)
     }
 
     fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
-                        ident: ast::Ident, path: ast::Path) -> P<ast::Item> {
+                        rename: Option<ast::Ident>, path: ast::Path) -> P<ast::Item> {
         self.item_use(sp, vis, P(ast::UseTree {
             span: sp,
             prefix: path,
-            kind: ast::UseTreeKind::Simple(ident),
+            kind: ast::UseTreeKind::Simple(rename),
         }))
     }
 
@@ -1178,7 +1181,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             (ast::UseTree {
                 span: sp,
                 prefix: self.path(sp, vec![*id]),
-                kind: ast::UseTreeKind::Simple(*id),
+                kind: ast::UseTreeKind::Simple(None),
             }, ast::DUMMY_NODE_ID)
         }).collect();
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 7ccace014d032..34dd7696168a6 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -239,7 +239,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             node: ast::ItemKind::Mod(krate.module),
             ident: keywords::Invalid.ident(),
             id: ast::DUMMY_NODE_ID,
-            vis: respan(krate.span.empty(), ast::VisibilityKind::Public),
+            vis: respan(krate.span.shrink_to_lo(), ast::VisibilityKind::Public),
             tokens: None,
         })));
 
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 7a024dbad8830..540a03ff032ff 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -75,7 +75,7 @@ pub mod rt {
 
     impl ToTokens for ast::Ident {
         fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
-            vec![TokenTree::Token(DUMMY_SP, token::Ident(*self))]
+            vec![TokenTree::Token(DUMMY_SP, Token::from_ast_ident(*self))]
         }
     }
 
@@ -238,7 +238,9 @@ pub mod rt {
                 if i > 0 {
                     inner.push(TokenTree::Token(self.span, token::Colon).into());
                 }
-                inner.push(TokenTree::Token(self.span, token::Ident(segment.identifier)).into());
+                inner.push(TokenTree::Token(
+                    self.span, token::Token::from_ast_ident(segment.identifier)
+                ).into());
             }
             inner.push(self.tokens.clone());
 
@@ -658,10 +660,10 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
         token::Literal(token::ByteStr(i), suf) => return mk_lit!("ByteStr", suf, i),
         token::Literal(token::ByteStrRaw(i, n), suf) => return mk_lit!("ByteStrRaw", suf, i, n),
 
-        token::Ident(ident) => {
+        token::Ident(ident, is_raw) => {
             return cx.expr_call(sp,
                                 mk_token_path(cx, sp, "Ident"),
-                                vec![mk_ident(cx, sp, ident)]);
+                                vec![mk_ident(cx, sp, ident), cx.expr_bool(sp, is_raw)]);
         }
 
         token::Lifetime(ident) => {
@@ -709,7 +711,6 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
         token::Pound        => "Pound",
         token::Dollar       => "Dollar",
         token::Question     => "Question",
-        token::Underscore   => "Underscore",
         token::Eof          => "Eof",
 
         token::Whitespace | token::Comment | token::Shebang(_) => {
@@ -721,7 +722,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
 
 fn statements_mk_tt(cx: &ExtCtxt, tt: &TokenTree, quoted: bool) -> Vec<ast::Stmt> {
     match *tt {
-        TokenTree::Token(sp, token::Ident(ident)) if quoted => {
+        TokenTree::Token(sp, token::Ident(ident, _)) if quoted => {
             // tt.extend($ident.to_tokens(ext_cx))
 
             let e_to_toks =
@@ -858,7 +859,7 @@ fn expand_wrapper(cx: &ExtCtxt,
         let path = path.iter().map(|s| s.to_string()).collect();
         let use_item = cx.item_use_glob(
             sp,
-            respan(sp.empty(), ast::VisibilityKind::Inherited),
+            respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
             ids_ext(path),
         );
         cx.stmt_item(sp, use_item)
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 0621f728e2a9d..8cb331c65da28 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -86,7 +86,7 @@ use self::TokenTreeOrTokenTreeVec::*;
 
 use ast::Ident;
 use syntax_pos::{self, BytePos, Span};
-use codemap::Spanned;
+use codemap::respan;
 use errors::FatalError;
 use ext::tt::quoted::{self, TokenTree};
 use parse::{Directory, ParseSess};
@@ -364,8 +364,8 @@ pub fn parse_failure_msg(tok: Token) -> String {
 
 /// Perform a token equality check, ignoring syntax context (that is, an unhygienic comparison)
 fn token_name_eq(t1: &Token, t2: &Token) -> bool {
-    if let (Some(id1), Some(id2)) = (t1.ident(), t2.ident()) {
-        id1.name == id2.name
+    if let (Some((id1, is_raw1)), Some((id2, is_raw2))) = (t1.ident(), t2.ident()) {
+        id1.name == id2.name && is_raw1 == is_raw2
     } else if let (&token::Lifetime(id1), &token::Lifetime(id2)) = (t1, t2) {
         id1.name == id2.name
     } else {
@@ -709,6 +709,16 @@ pub fn parse(
     }
 }
 
+/// The token is an identifier, but not `_`.
+/// We prohibit passing `_` to macros expecting `ident` for now.
+fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> {
+    match *token {
+        token::Ident(ident, is_raw) if ident.name != keywords::Underscore.name() =>
+            Some((ident, is_raw)),
+        _ => None,
+    }
+}
+
 /// Checks whether a non-terminal may begin with a particular token.
 ///
 /// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that
@@ -725,10 +735,10 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
     match name {
         "expr" => token.can_begin_expr(),
         "ty" => token.can_begin_type(),
-        "ident" => token.is_ident(),
+        "ident" => get_macro_ident(token).is_some(),
         "vis" => match *token {
             // The follow-set of :vis + "priv" keyword + interpolated
-            Token::Comma | Token::Ident(_) | Token::Interpolated(_) => true,
+            Token::Comma | Token::Ident(..) | Token::Interpolated(_) => true,
             _ => token.can_begin_type(),
         },
         "block" => match *token {
@@ -737,7 +747,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
                 token::NtItem(_)
                 | token::NtPat(_)
                 | token::NtTy(_)
-                | token::NtIdent(_)
+                | token::NtIdent(..)
                 | token::NtMeta(_)
                 | token::NtPath(_)
                 | token::NtVis(_) => false, // none of these may start with '{'.
@@ -746,7 +756,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
             _ => false,
         },
         "path" | "meta" => match *token {
-            Token::ModSep | Token::Ident(_) => true,
+            Token::ModSep | Token::Ident(..) => true,
             Token::Interpolated(ref nt) => match nt.0 {
                 token::NtPath(_) | token::NtMeta(_) => true,
                 _ => may_be_ident(&nt.0),
@@ -754,7 +764,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
             _ => false,
         },
         "pat" => match *token {
-            Token::Ident(_) |               // box, ref, mut, and other identifiers (can stricten)
+            Token::Ident(..) |               // box, ref, mut, and other identifiers (can stricten)
             Token::OpenDelim(token::Paren) |    // tuple pattern
             Token::OpenDelim(token::Bracket) |  // slice pattern
             Token::BinOp(token::And) |          // reference
@@ -765,8 +775,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
             Token::DotDotDot |                  // range pattern (future compat)
             Token::ModSep |                     // path
             Token::Lt |                         // path (UFCS constant)
-            Token::BinOp(token::Shl) |          // path (double UFCS)
-            Token::Underscore => true,          // placeholder
+            Token::BinOp(token::Shl) => true,   // path (double UFCS)
             Token::Interpolated(ref nt) => may_be_ident(&nt.0),
             _ => false,
         },
@@ -815,21 +824,14 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
         "expr" => token::NtExpr(panictry!(p.parse_expr())),
         "ty" => token::NtTy(panictry!(p.parse_ty())),
         // this could be handled like a token, since it is one
-        "ident" => match p.token {
-            token::Ident(sn) => {
-                p.bump();
-                token::NtIdent(Spanned::<Ident> {
-                    node: sn,
-                    span: p.prev_span,
-                })
-            }
-            _ => {
-                let token_str = pprust::token_to_string(&p.token);
-                p.fatal(&format!("expected ident, found {}", &token_str[..]))
-                    .emit();
-                FatalError.raise()
-            }
-        },
+        "ident" => if let Some((ident, is_raw)) = get_macro_ident(&p.token) {
+            p.bump();
+            token::NtIdent(respan(p.prev_span, ident), is_raw)
+        } else {
+            let token_str = pprust::token_to_string(&p.token);
+            p.fatal(&format!("expected ident, found {}", &token_str)).emit();
+            FatalError.raise()
+        }
         "path" => token::NtPath(panictry!(p.parse_path_common(PathStyle::Type, false))),
         "meta" => token::NtMeta(panictry!(p.parse_meta_item())),
         "vis" => token::NtVis(panictry!(p.parse_visibility(true))),
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index a4b2c3990f5e1..10e5926eb9e36 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -831,7 +831,7 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> Result<bool, (String, &'
             "pat" => match *tok {
                 TokenTree::Token(_, ref tok) => match *tok {
                     FatArrow | Comma | Eq | BinOp(token::Or) => Ok(true),
-                    Ident(i) if i.name == "if" || i.name == "in" => Ok(true),
+                    Ident(i, false) if i.name == "if" || i.name == "in" => Ok(true),
                     _ => Ok(false)
                 },
                 _ => Ok(false),
@@ -840,7 +840,7 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> Result<bool, (String, &'
                 TokenTree::Token(_, ref tok) => match *tok {
                     OpenDelim(token::DelimToken::Brace) | OpenDelim(token::DelimToken::Bracket) |
                     Comma | FatArrow | Colon | Eq | Gt | Semi | BinOp(token::Or) => Ok(true),
-                    Ident(i) if i.name == "as" || i.name == "where" => Ok(true),
+                    Ident(i, false) if i.name == "as" || i.name == "where" => Ok(true),
                     _ => Ok(false)
                 },
                 TokenTree::MetaVarDecl(_, _, frag) if frag.name == "block" => Ok(true),
@@ -860,7 +860,7 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> Result<bool, (String, &'
                 match *tok {
                     TokenTree::Token(_, ref tok) => match *tok {
                         Comma => Ok(true),
-                        Ident(i) if i.name != "priv" => Ok(true),
+                        Ident(i, is_raw) if is_raw || i.name != "priv" => Ok(true),
                         ref tok => Ok(tok.can_begin_type())
                     },
                     TokenTree::MetaVarDecl(_, _, frag) if frag.name == "ident"
diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs
index 122bb9ba024a4..f324edeb1178a 100644
--- a/src/libsyntax/ext/tt/quoted.rs
+++ b/src/libsyntax/ext/tt/quoted.rs
@@ -200,7 +200,7 @@ pub fn parse(
                 let span = match trees.next() {
                     Some(tokenstream::TokenTree::Token(span, token::Colon)) => match trees.next() {
                         Some(tokenstream::TokenTree::Token(end_sp, ref tok)) => match tok.ident() {
-                            Some(kind) => {
+                            Some((kind, _)) => {
                                 let span = end_sp.with_lo(start_sp.lo());
                                 result.push(TokenTree::MetaVarDecl(span, ident, kind));
                                 continue;
@@ -289,14 +289,14 @@ where
             // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate` special
             // metavariable that names the crate of the invokation.
             Some(tokenstream::TokenTree::Token(ident_span, ref token)) if token.is_ident() => {
-                let ident = token.ident().unwrap();
+                let (ident, _) = token.ident().unwrap();
                 let span = ident_span.with_lo(span.lo());
                 if ident.name == keywords::Crate.name() {
                     let ident = ast::Ident {
                         name: keywords::DollarCrate.name(),
                         ..ident
                     };
-                    TokenTree::Token(span, token::Ident(ident))
+                    TokenTree::Token(span, token::Ident(ident, false))
                 } else {
                     TokenTree::MetaVar(span, ident)
                 }
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 7883c4bbc1648..3f01d5ec6dd87 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -169,7 +169,7 @@ pub fn transcribe(cx: &ExtCtxt,
                         Ident { ctxt: ident.ctxt.apply_mark(cx.current_expansion.mark), ..ident };
                     sp = sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark));
                     result.push(TokenTree::Token(sp, token::Dollar).into());
-                    result.push(TokenTree::Token(sp, token::Ident(ident)).into());
+                    result.push(TokenTree::Token(sp, token::Token::from_ast_ident(ident)).into());
                 }
             }
             quoted::TokenTree::Delimited(mut span, delimited) => {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index f42cb8a258314..ce8c613dc8bb6 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -28,7 +28,7 @@ use self::AttributeGate::*;
 use abi::Abi;
 use ast::{self, NodeId, PatKind, RangeEnd};
 use attr;
-use epoch::Epoch;
+use edition::Edition;
 use codemap::Spanned;
 use syntax_pos::{Span, DUMMY_SP};
 use errors::{DiagnosticBuilder, Handler, FatalError};
@@ -55,13 +55,13 @@ macro_rules! set {
 }
 
 macro_rules! declare_features {
-    ($((active, $feature: ident, $ver: expr, $issue: expr, $epoch: expr),)+) => {
+    ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => {
         /// Represents active features that are currently being implemented or
         /// currently being considered for addition/removal.
         const ACTIVE_FEATURES:
                 &'static [(&'static str, &'static str, Option<u32>,
-                           Option<Epoch>, fn(&mut Features, Span))] =
-            &[$((stringify!($feature), $ver, $issue, $epoch, set!($feature))),+];
+                           Option<Edition>, fn(&mut Features, Span))] =
+            &[$((stringify!($feature), $ver, $issue, $edition, set!($feature))),+];
 
         /// A set of features to be used by later passes.
         #[derive(Clone)]
@@ -145,7 +145,6 @@ declare_features! (
     // rustc internal
     (active, rustc_diagnostic_macros, "1.0.0", None, None),
     (active, rustc_const_unstable, "1.0.0", None, None),
-    (active, advanced_slice_patterns, "1.0.0", Some(23121), None),
     (active, box_syntax, "1.0.0", Some(27779), None),
     (active, placement_in_syntax, "1.0.0", Some(27779), None),
     (active, unboxed_closures, "1.0.0", Some(29625), None),
@@ -277,12 +276,6 @@ declare_features! (
     // Allows cfg(target_has_atomic = "...").
     (active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
 
-    // Allows `impl Trait` in function return types.
-    (active, conservative_impl_trait, "1.12.0", Some(34511), None),
-
-    // Allows `impl Trait` in function arguments.
-    (active, universal_impl_trait, "1.23.0", Some(34511), None),
-
     // Allows exhaustive pattern matching on types that contain uninhabited types.
     (active, exhaustive_patterns, "1.13.0", None, None),
 
@@ -310,9 +303,6 @@ declare_features! (
     // `extern "ptx-*" fn()`
     (active, abi_ptx, "1.15.0", None, None),
 
-    // The `i128` type
-    (active, i128_type, "1.16.0", Some(35118), None),
-
     // The `repr(i128)` annotation for enums
     (active, repr128, "1.16.0", Some(35118), None),
 
@@ -392,18 +382,11 @@ declare_features! (
     // Future-proofing enums/structs with #[non_exhaustive] attribute (RFC 2008)
     (active, non_exhaustive, "1.22.0", Some(44109), None),
 
-    // Copy/Clone closures (RFC 2132)
-    (active, clone_closures, "1.22.0", Some(44490), None),
-    (active, copy_closures, "1.22.0", Some(44490), None),
-
     // allow `'_` placeholder lifetimes
     (active, underscore_lifetimes, "1.22.0", Some(44524), None),
 
-    // Default match binding modes (RFC 2005)
-    (active, match_default_bindings, "1.22.0", Some(42640), None),
-
     // Trait object syntax with `dyn` prefix
-    (active, dyn_trait, "1.22.0", Some(44662), Some(Epoch::Epoch2018)),
+    (active, dyn_trait, "1.22.0", Some(44662), Some(Edition::Edition2018)),
 
     // `crate` as visibility modifier, synonymous to `pub(crate)`
     (active, crate_visibility_modifier, "1.23.0", Some(45388), None),
@@ -429,8 +412,8 @@ declare_features! (
     // `foo.rs` as an alternative to `foo/mod.rs`
     (active, non_modrs_mods, "1.24.0", Some(44660), None),
 
-    // Termination trait in main (RFC 1937)
-    (active, termination_trait, "1.24.0", Some(43301), None),
+    // Termination trait in tests (RFC 1937)
+    (active, termination_trait_test, "1.24.0", Some(48854), None),
 
     // Allows use of the :lifetime macro fragment specifier
     (active, macro_lifetime_matcher, "1.24.0", Some(46895), None),
@@ -452,6 +435,15 @@ declare_features! (
 
     // `use path as _;` and `extern crate c as _;`
     (active, underscore_imports, "1.26.0", Some(48216), None),
+
+    // The #[wasm_custom_section] attribute
+    (active, wasm_custom_section, "1.26.0", None, None),
+
+    // The #![wasm_import_module] attribute
+    (active, wasm_import_module, "1.26.0", None, None),
+
+    // Allows keywords to be escaped for use as identifiers
+    (active, raw_identifiers, "1.26.0", Some(48589), None),
 );
 
 declare_features! (
@@ -474,6 +466,8 @@ declare_features! (
     (removed, allocator, "1.0.0", None, None),
     // Allows the `#[simd]` attribute -- removed in favor of `#[repr(simd)]`
     (removed, simd, "1.0.0", Some(27731), None),
+    // Merged into `slice_patterns`
+    (removed, advanced_slice_patterns, "1.0.0", Some(23121), None),
 );
 
 declare_features! (
@@ -555,6 +549,19 @@ declare_features! (
     (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
     // allow `..=` in patterns (RFC 1192)
     (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None),
+    // Termination trait in main (RFC 1937)
+    (accepted, termination_trait, "1.26.0", Some(43301), None),
+    // Copy/Clone closures (RFC 2132)
+    (accepted, clone_closures, "1.26.0", Some(44490), None),
+    (accepted, copy_closures, "1.26.0", Some(44490), None),
+    // Allows `impl Trait` in function arguments.
+    (accepted, universal_impl_trait, "1.26.0", Some(34511), None),
+    // Allows `impl Trait` in function return types.
+    (accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
+    // The `i128` type
+    (accepted, i128_type, "1.26.0", Some(35118), None),
+    // Default match binding modes (RFC 2005)
+    (accepted, match_default_bindings, "1.26.0", Some(42640), None),
 );
 
 // If you change this, please modify src/doc/unstable-book as well. You must
@@ -832,6 +839,13 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
                                                           across crates and will never be stable",
                                                           cfg_fn!(rustc_attrs))),
 
+    ("rustc_dump_program_clauses", Whitelisted, Gated(Stability::Unstable,
+                                                     "rustc_attrs",
+                                                     "the `#[rustc_dump_program_clauses]` \
+                                                      attribute is just used for rustc unit \
+                                                      tests and will never be stable",
+                                                     cfg_fn!(rustc_attrs))),
+
     // RFC #2094
     ("nll", Whitelisted, Gated(Stability::Unstable,
                                "nll",
@@ -909,6 +923,10 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
         "the `#[no_debug]` attribute was an experimental feature that has been \
          deprecated due to lack of demand",
         cfg_fn!(no_debug))),
+    ("wasm_import_module", Normal, Gated(Stability::Unstable,
+                                 "wasm_import_module",
+                                 "experimental attribute",
+                                 cfg_fn!(wasm_import_module))),
     ("omit_gdb_pretty_printer_section", Whitelisted, Gated(Stability::Unstable,
                                                        "omit_gdb_pretty_printer_section",
                                                        "the `#[omit_gdb_pretty_printer_section]` \
@@ -996,6 +1014,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
                                  "never will be stable",
                                  cfg_fn!(rustc_attrs))),
 
+    ("wasm_custom_section", Whitelisted, Gated(Stability::Unstable,
+                                 "wasm_custom_section",
+                                 "attribute is currently unstable",
+                                 cfg_fn!(wasm_custom_section))),
+
     // Crate level attributes
     ("crate_name", CrateLevel, Ungated),
     ("crate_type", CrateLevel, Ungated),
@@ -1438,7 +1461,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     }
 
     fn visit_use_tree(&mut self, use_tree: &'a ast::UseTree, id: NodeId, _nested: bool) {
-        if let ast::UseTreeKind::Simple(ident) = use_tree.kind {
+        if let ast::UseTreeKind::Simple(Some(ident)) = use_tree.kind {
             if ident.name == "_" {
                 gate_feature_post!(&self, underscore_imports, use_tree.span,
                                    "renaming imports with `_` is unstable");
@@ -1616,18 +1639,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                                   e.span,
                                   "yield syntax is experimental");
             }
-            ast::ExprKind::Lit(ref lit) => {
-                if let ast::LitKind::Int(_, ref ty) = lit.node {
-                    match *ty {
-                        ast::LitIntType::Signed(ast::IntTy::I128) |
-                        ast::LitIntType::Unsigned(ast::UintTy::U128) => {
-                            gate_feature_post!(&self, i128_type, e.span,
-                                               "128-bit integers are not stable");
-                        }
-                        _ => {}
-                    }
-                }
-            }
             ast::ExprKind::Catch(_) => {
                 gate_feature_post!(&self, catch_expr, e.span, "`catch` expression is experimental");
             }
@@ -1648,17 +1659,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 
     fn visit_pat(&mut self, pattern: &'a ast::Pat) {
         match pattern.node {
-            PatKind::Slice(_, Some(_), ref last) if !last.is_empty() => {
-                gate_feature_post!(&self, advanced_slice_patterns,
-                                  pattern.span,
-                                  "multiple-element slice matches anywhere \
-                                   but at the end of a slice (e.g. \
-                                   `[0, ..xs, 0]`) are experimental")
-            }
-            PatKind::Slice(..) => {
+            PatKind::Slice(_, Some(ref subslice), _) => {
                 gate_feature_post!(&self, slice_patterns,
-                                  pattern.span,
-                                  "slice pattern syntax is experimental");
+                                   subslice.span,
+                                   "syntax for subslices in slice patterns is not yet stabilized");
             }
             PatKind::Box(..) => {
                 gate_feature_post!(&self, box_patterns,
@@ -1790,7 +1794,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     }
 
     fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) {
-        if lt.ident.name == "'_" {
+        if lt.ident.name == keywords::UnderscoreLifetime.name() {
             gate_feature_post!(&self, underscore_lifetimes, lt.span,
                                "underscore lifetimes are unstable");
         }
@@ -1799,16 +1803,16 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 }
 
 pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
-                    epoch: Epoch) -> Features {
+                    edition: Edition) -> Features {
     let mut features = Features::new();
 
     let mut feature_checker = FeatureChecker::default();
 
-    for &(.., f_epoch, set) in ACTIVE_FEATURES.iter() {
-        if let Some(f_epoch) = f_epoch {
-            if epoch >= f_epoch {
+    for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
+        if let Some(f_edition) = f_edition {
+            if edition >= f_edition {
                 // FIXME(Manishearth) there is currently no way to set
-                // lang features by epoch
+                // lang features by edition
                 set(&mut features, DUMMY_SP);
             }
         }
@@ -1866,8 +1870,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
 struct FeatureChecker {
     proc_macro: Option<Span>,
     custom_attribute: Option<Span>,
-    copy_closures: Option<Span>,
-    clone_closures: Option<Span>,
 }
 
 impl FeatureChecker {
@@ -1883,14 +1885,6 @@ impl FeatureChecker {
         if features.custom_attribute {
             self.custom_attribute = self.custom_attribute.or(Some(span));
         }
-
-        if features.copy_closures {
-            self.copy_closures = self.copy_closures.or(Some(span));
-        }
-
-        if features.clone_closures {
-            self.clone_closures = self.clone_closures.or(Some(span));
-        }
     }
 
     fn check(self, handler: &Handler) {
@@ -1902,15 +1896,6 @@ impl FeatureChecker {
 
             FatalError.raise();
         }
-
-        if let (Some(span), None) = (self.copy_closures, self.clone_closures) {
-            handler.struct_span_err(span, "`#![feature(copy_closures)]` can only be used with \
-                                           `#![feature(clone_closures)]`")
-                  .span_note(span, "`#![feature(copy_closures)]` declared here")
-                  .emit();
-
-            FatalError.raise();
-        }
     }
 }
 
@@ -1925,6 +1910,17 @@ pub fn check_crate(krate: &ast::Crate,
         parse_sess: sess,
         plugin_attributes,
     };
+
+    if !features.raw_identifiers {
+        for &span in sess.raw_identifier_spans.borrow().iter() {
+            if !span.allows_unstable() {
+                gate_feature!(&ctx, raw_identifiers, span,
+                    "raw identifiers are experimental and subject to change"
+                );
+            }
+        }
+    }
+
     let visitor = &mut PostExpansionVisitor { context: &ctx };
     visitor.whole_crate_feature_gates(krate);
     visit::walk_crate(visitor, krate);
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 2cf99e15d1f9b..05a3150c139c9 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -323,7 +323,8 @@ pub fn noop_fold_use_tree<T: Folder>(use_tree: UseTree, fld: &mut T) -> UseTree
         span: fld.new_span(use_tree.span),
         prefix: fld.fold_path(use_tree.prefix),
         kind: match use_tree.kind {
-            UseTreeKind::Simple(ident) => UseTreeKind::Simple(fld.fold_ident(ident)),
+            UseTreeKind::Simple(rename) =>
+                UseTreeKind::Simple(rename.map(|ident| fld.fold_ident(ident))),
             UseTreeKind::Glob => UseTreeKind::Glob,
             UseTreeKind::Nested(items) => UseTreeKind::Nested(items.move_map(|(tree, id)| {
                 (fld.fold_use_tree(tree), fld.new_id(id))
@@ -577,7 +578,7 @@ pub fn noop_fold_tts<T: Folder>(tts: TokenStream, fld: &mut T) -> TokenStream {
 // apply ident folder if it's an ident, apply other folds to interpolated nodes
 pub fn noop_fold_token<T: Folder>(t: token::Token, fld: &mut T) -> token::Token {
     match t {
-        token::Ident(id) => token::Ident(fld.fold_ident(id)),
+        token::Ident(id, is_raw) => token::Ident(fld.fold_ident(id), is_raw),
         token::Lifetime(id) => token::Lifetime(fld.fold_ident(id)),
         token::Interpolated(nt) => {
             let nt = match Lrc::try_unwrap(nt) {
@@ -629,7 +630,8 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
         token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)),
         token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)),
         token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)),
-        token::NtIdent(id) => token::NtIdent(Spanned::<Ident>{node: fld.fold_ident(id.node), ..id}),
+        token::NtIdent(id, is_raw) =>
+            token::NtIdent(Spanned::<Ident>{node: fld.fold_ident(id.node), ..id}, is_raw),
         token::NtMeta(meta) => token::NtMeta(fld.fold_meta_item(meta)),
         token::NtPath(path) => token::NtPath(fld.fold_path(path)),
         token::NtTT(tt) => token::NtTT(fld.fold_tt(tt)),
@@ -886,7 +888,7 @@ pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
 
 pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
     match i {
-        ItemKind::ExternCrate(string) => ItemKind::ExternCrate(string),
+        ItemKind::ExternCrate(orig_name) => ItemKind::ExternCrate(orig_name),
         ItemKind::Use(use_tree) => {
             ItemKind::Use(use_tree.map(|tree| folder.fold_use_tree(tree)))
         }
@@ -1018,7 +1020,7 @@ pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, span}: Crate,
         ident: keywords::Invalid.ident(),
         attrs,
         id: ast::DUMMY_NODE_ID,
-        vis: respan(span.empty(), ast::VisibilityKind::Public),
+        vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Public),
         span,
         node: ast::ItemKind::Mod(module),
         tokens: None,
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 5f58b3bc3a050..dc349c1a3e6a1 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -22,9 +22,9 @@
 
 #![feature(unicode)]
 #![feature(rustc_diagnostic_macros)]
-#![feature(match_default_bindings)]
+#![cfg_attr(stage0, feature(match_default_bindings))]
 #![feature(non_exhaustive)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(const_atomic_usize_new)]
 #![feature(rustc_attrs)]
 
@@ -145,7 +145,7 @@ pub mod codemap;
 #[macro_use]
 pub mod config;
 pub mod entry;
-pub mod epoch;
+pub mod edition;
 pub mod feature_gate;
 pub mod fold;
 pub mod parse;
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 053746b579dcb..4c3f42d9c6b7d 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -90,7 +90,7 @@ impl<'a> Parser<'a> {
         debug!("parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}",
                inner_parse_policy,
                self.token);
-        let (span, path, tokens, mut style) = match self.token {
+        let (span, path, tokens, style) = match self.token {
             token::Pound => {
                 let lo = self.span;
                 self.bump();
@@ -129,15 +129,6 @@ impl<'a> Parser<'a> {
             }
         };
 
-        if inner_parse_policy == InnerAttributeParsePolicy::Permitted &&
-           self.token == token::Semi {
-            self.bump();
-            self.span_warn(span,
-                           "this inner attribute syntax is deprecated. The new syntax is \
-                            `#![foo]`, with a bang and no semicolon");
-            style = ast::AttrStyle::Inner;
-        }
-
         Ok(ast::Attribute {
             id: attr::mk_attr_id(),
             style,
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 815ba49a60a72..068929c8948df 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -14,7 +14,7 @@ use codemap::{CodeMap, FilePathMapping};
 use errors::{FatalError, DiagnosticBuilder};
 use parse::{token, ParseSess};
 use str::char_at;
-use symbol::Symbol;
+use symbol::{Symbol, keywords};
 use std_unicode::property::Pattern_White_Space;
 
 use std::borrow::Cow;
@@ -34,7 +34,7 @@ pub struct TokenAndSpan {
 
 impl Default for TokenAndSpan {
     fn default() -> Self {
-        TokenAndSpan { tok: token::Underscore, sp: syntax_pos::DUMMY_SP }
+        TokenAndSpan { tok: token::Whitespace, sp: syntax_pos::DUMMY_SP }
     }
 }
 
@@ -126,7 +126,7 @@ impl<'a> StringReader<'a> {
     pub fn try_next_token(&mut self) -> Result<TokenAndSpan, ()> {
         assert!(self.fatal_errs.is_empty());
         let ret_val = TokenAndSpan {
-            tok: replace(&mut self.peek_tok, token::Underscore),
+            tok: replace(&mut self.peek_tok, token::Whitespace),
             sp: self.peek_span,
         };
         self.advance_token()?;
@@ -214,7 +214,7 @@ impl<'a> StringReader<'a> {
 
         // Make the range zero-length if the span is invalid.
         if span.lo() > span.hi() || begin.fm.start_pos != end.fm.start_pos {
-            span = span.with_hi(span.lo());
+            span = span.shrink_to_lo();
         }
 
         let mut sr = StringReader::new_raw_internal(sess, begin.fm);
@@ -1115,32 +1115,53 @@ impl<'a> StringReader<'a> {
     /// token, and updates the interner
     fn next_token_inner(&mut self) -> Result<token::Token, ()> {
         let c = self.ch;
-        if ident_start(c) &&
-           match (c.unwrap(), self.nextch(), self.nextnextch()) {
-            // Note: r as in r" or r#" is part of a raw string literal,
-            // b as in b' is part of a byte literal.
-            // They are not identifiers, and are handled further down.
-            ('r', Some('"'), _) |
-            ('r', Some('#'), _) |
-            ('b', Some('"'), _) |
-            ('b', Some('\''), _) |
-            ('b', Some('r'), Some('"')) |
-            ('b', Some('r'), Some('#')) => false,
-            _ => true,
-        } {
-            let start = self.pos;
-            while ident_continue(self.ch) {
-                self.bump();
-            }
 
-            return Ok(self.with_str_from(start, |string| {
-                if string == "_" {
-                    token::Underscore
-                } else {
-                    // FIXME: perform NFKC normalization here. (Issue #2253)
-                    token::Ident(self.mk_ident(string))
+        if ident_start(c) {
+            let (is_ident_start, is_raw_ident) =
+                match (c.unwrap(), self.nextch(), self.nextnextch()) {
+                    // r# followed by an identifier starter is a raw identifier.
+                    // This is an exception to the r# case below.
+                    ('r', Some('#'), x) if ident_start(x) => (true, true),
+                    // r as in r" or r#" is part of a raw string literal.
+                    // b as in b' is part of a byte literal.
+                    // They are not identifiers, and are handled further down.
+                    ('r', Some('"'), _) |
+                    ('r', Some('#'), _) |
+                    ('b', Some('"'), _) |
+                    ('b', Some('\''), _) |
+                    ('b', Some('r'), Some('"')) |
+                    ('b', Some('r'), Some('#')) => (false, false),
+                    _ => (true, false),
+                };
+            if is_ident_start {
+                let raw_start = self.pos;
+                if is_raw_ident {
+                    // Consume the 'r#' characters.
+                    self.bump();
+                    self.bump();
+                }
+
+                let start = self.pos;
+                while ident_continue(self.ch) {
+                    self.bump();
                 }
-            }));
+
+                return Ok(self.with_str_from(start, |string| {
+                    // FIXME: perform NFKC normalization here. (Issue #2253)
+                    let ident = self.mk_ident(string);
+                    if is_raw_ident && (token::is_path_segment_keyword(ident) ||
+                                        ident.name == keywords::Underscore.name()) {
+                        self.fatal_span_(raw_start, self.pos,
+                            &format!("`r#{}` is not currently supported.", ident.name)
+                        ).raise();
+                    }
+                    if is_raw_ident {
+                        let span = self.mk_sp(raw_start, self.pos);
+                        self.sess.raw_identifier_spans.borrow_mut().push(span);
+                    }
+                    token::Ident(ident, is_raw_ident)
+                }));
+            }
         }
 
         if is_dec_digit(c) {
@@ -1779,6 +1800,7 @@ mod tests {
             included_mod_stack: RefCell::new(Vec::new()),
             code_map: cm,
             missing_fragment_specifiers: RefCell::new(HashSet::new()),
+            raw_identifier_spans: RefCell::new(Vec::new()),
             registered_diagnostics: Lock::new(ErrorMap::new()),
             non_modrs_mods: RefCell::new(vec![]),
         }
@@ -1807,7 +1829,7 @@ mod tests {
             assert_eq!(string_reader.next_token().tok, token::Whitespace);
             let tok1 = string_reader.next_token();
             let tok2 = TokenAndSpan {
-                tok: token::Ident(id),
+                tok: token::Ident(id, false),
                 sp: Span::new(BytePos(21), BytePos(23), NO_EXPANSION),
             };
             assert_eq!(tok1, tok2);
@@ -1817,7 +1839,7 @@ mod tests {
             // read another token:
             let tok3 = string_reader.next_token();
             let tok4 = TokenAndSpan {
-                tok: token::Ident(Ident::from_str("main")),
+                tok: mk_ident("main"),
                 sp: Span::new(BytePos(24), BytePos(28), NO_EXPANSION),
             };
             assert_eq!(tok3, tok4);
@@ -1836,7 +1858,7 @@ mod tests {
 
     // make the identifier by looking up the string in the interner
     fn mk_ident(id: &str) -> token::Token {
-        token::Ident(Ident::from_str(id))
+        token::Token::from_ast_ident(Ident::from_str(id))
     }
 
     #[test]
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index ff097c362fe61..1483691a1eaee 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -40,7 +40,6 @@ pub mod attr;
 
 pub mod common;
 pub mod classify;
-pub mod obsolete;
 
 /// Info about a parsing session.
 pub struct ParseSess {
@@ -48,6 +47,9 @@ pub struct ParseSess {
     pub unstable_features: UnstableFeatures,
     pub config: CrateConfig,
     pub missing_fragment_specifiers: RefCell<HashSet<Span>>,
+    /// Places where raw identifiers were used. This is used for feature gating
+    /// raw identifiers
+    pub raw_identifier_spans: RefCell<Vec<Span>>,
     /// The registered diagnostics codes
     pub registered_diagnostics: Lock<ErrorMap>,
     // Spans where a `mod foo;` statement was included in a non-mod.rs file.
@@ -74,6 +76,7 @@ impl ParseSess {
             unstable_features: UnstableFeatures::from_environment(),
             config: HashSet::new(),
             missing_fragment_specifiers: RefCell::new(HashSet::new()),
+            raw_identifier_spans: RefCell::new(Vec::new()),
             registered_diagnostics: Lock::new(ErrorMap::new()),
             included_mod_stack: RefCell::new(vec![]),
             code_map,
@@ -298,7 +301,6 @@ pub fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String {
     debug!("parse_str_lit: given {}", escape_default(lit));
     let mut res = String::with_capacity(lit.len());
 
-    // FIXME #8372: This could be a for-loop if it didn't borrow the iterator
     let error = |i| format!("lexer should have rejected {} at {}", lit, i);
 
     /// Eat everything up to a non-whitespace
@@ -503,7 +505,6 @@ pub fn byte_lit(lit: &str) -> (u8, usize) {
 pub fn byte_str_lit(lit: &str) -> Lrc<Vec<u8>> {
     let mut res = Vec::with_capacity(lit.len());
 
-    // FIXME #8372: This could be a for-loop if it didn't borrow the iterator
     let error = |i| format!("lexer should have rejected {} at {}", lit, i);
 
     /// Eat everything up to a non-whitespace
@@ -713,7 +714,7 @@ mod tests {
                         id: ast::DUMMY_NODE_ID,
                         node: ast::ExprKind::Path(None, ast::Path {
                             span: sp(0, 6),
-                            segments: vec![ast::PathSegment::crate_root(sp(0, 2)),
+                            segments: vec![ast::PathSegment::crate_root(sp(0, 0)),
                                         str2seg("a", 2, 3),
                                         str2seg("b", 5, 6)]
                         }),
@@ -741,9 +742,9 @@ mod tests {
             match (tts.len(), tts.get(0), tts.get(1), tts.get(2), tts.get(3)) {
                 (
                     4,
-                    Some(&TokenTree::Token(_, token::Ident(name_macro_rules))),
+                    Some(&TokenTree::Token(_, token::Ident(name_macro_rules, false))),
                     Some(&TokenTree::Token(_, token::Not)),
-                    Some(&TokenTree::Token(_, token::Ident(name_zip))),
+                    Some(&TokenTree::Token(_, token::Ident(name_zip, false))),
                     Some(&TokenTree::Delimited(_, ref macro_delimed)),
                 )
                 if name_macro_rules.name == "macro_rules"
@@ -762,7 +763,7 @@ mod tests {
                                 (
                                     2,
                                     Some(&TokenTree::Token(_, token::Dollar)),
-                                    Some(&TokenTree::Token(_, token::Ident(ident))),
+                                    Some(&TokenTree::Token(_, token::Ident(ident, false))),
                                 )
                                 if first_delimed.delim == token::Paren && ident.name == "a" => {},
                                 _ => panic!("value 3: {:?}", *first_delimed),
@@ -772,7 +773,7 @@ mod tests {
                                 (
                                     2,
                                     Some(&TokenTree::Token(_, token::Dollar)),
-                                    Some(&TokenTree::Token(_, token::Ident(ident))),
+                                    Some(&TokenTree::Token(_, token::Ident(ident, false))),
                                 )
                                 if second_delimed.delim == token::Paren
                                 && ident.name == "a" => {},
@@ -793,17 +794,18 @@ mod tests {
             let tts = string_to_stream("fn a (b : i32) { b; }".to_string());
 
             let expected = TokenStream::concat(vec![
-                TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"))).into(),
-                TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"))).into(),
+                TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"), false)).into(),
+                TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"), false)).into(),
                 TokenTree::Delimited(
                     sp(5, 14),
                     tokenstream::Delimited {
                         delim: token::DelimToken::Paren,
                         tts: TokenStream::concat(vec![
-                            TokenTree::Token(sp(6, 7), token::Ident(Ident::from_str("b"))).into(),
+                            TokenTree::Token(sp(6, 7),
+                                             token::Ident(Ident::from_str("b"), false)).into(),
                             TokenTree::Token(sp(8, 9), token::Colon).into(),
                             TokenTree::Token(sp(10, 13),
-                                             token::Ident(Ident::from_str("i32"))).into(),
+                                             token::Ident(Ident::from_str("i32"), false)).into(),
                         ]).into(),
                     }).into(),
                 TokenTree::Delimited(
@@ -811,7 +813,8 @@ mod tests {
                     tokenstream::Delimited {
                         delim: token::DelimToken::Brace,
                         tts: TokenStream::concat(vec![
-                            TokenTree::Token(sp(17, 18), token::Ident(Ident::from_str("b"))).into(),
+                            TokenTree::Token(sp(17, 18),
+                                             token::Ident(Ident::from_str("b"), false)).into(),
                             TokenTree::Token(sp(18, 19), token::Semi).into(),
                         ]).into(),
                     }).into()
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
deleted file mode 100644
index 49a697edf4164..0000000000000
--- a/src/libsyntax/parse/obsolete.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2012-2014 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.
-
-//! Support for parsing unsupported, old syntaxes, for the purpose of reporting errors. Parsing of
-//! these syntaxes is tested by compile-test/obsolete-syntax.rs.
-//!
-//! Obsolete syntax that becomes too hard to parse can be removed.
-
-use syntax_pos::Span;
-use parse::parser;
-
-/// The specific types of unsupported syntax
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub enum ObsoleteSyntax {
-    // Nothing here at the moment
-}
-
-pub trait ParserObsoleteMethods {
-    /// Reports an obsolete syntax non-fatal error.
-    fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
-    fn report(&mut self,
-              sp: Span,
-              kind: ObsoleteSyntax,
-              kind_str: &str,
-              desc: &str,
-              error: bool);
-}
-
-impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
-    /// Reports an obsolete syntax non-fatal error.
-    #[allow(unused_variables)]
-    #[allow(unreachable_code)]
-    fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
-        let (kind_str, desc, error) = match kind {
-            // Nothing here at the moment
-        };
-
-        self.report(sp, kind, kind_str, desc, error);
-    }
-
-    fn report(&mut self,
-              sp: Span,
-              kind: ObsoleteSyntax,
-              kind_str: &str,
-              desc: &str,
-              error: bool) {
-        let mut err = if error {
-            self.diagnostic().struct_span_err(sp, &format!("obsolete syntax: {}", kind_str))
-        } else {
-            self.diagnostic().struct_span_warn(sp, &format!("obsolete syntax: {}", kind_str))
-        };
-
-        if !self.obsolete_set.contains(&kind) &&
-            (error || self.sess.span_diagnostic.flags.can_emit_warnings) {
-            err.note(desc);
-            self.obsolete_set.insert(kind);
-        }
-        err.emit();
-    }
-}
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index a3a6489fe8b14..b4b21285d3b2b 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -48,7 +48,6 @@ use parse::{self, classify, token};
 use parse::common::SeqSep;
 use parse::lexer::TokenAndSpan;
 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
-use parse::obsolete::ObsoleteSyntax;
 use parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership};
 use util::parser::{AssocOp, Fixity};
 use print::pprust;
@@ -59,7 +58,6 @@ use symbol::{Symbol, keywords};
 use util::ThinVec;
 
 use std::cmp;
-use std::collections::HashSet;
 use std::mem;
 use std::path::{self, Path, PathBuf};
 use std::slice;
@@ -229,9 +227,6 @@ pub struct Parser<'a> {
     /// the previous token kind
     prev_token_kind: PrevTokenKind,
     pub restrictions: Restrictions,
-    /// The set of seen errors about obsolete syntax. Used to suppress
-    /// extra detail when the same error is seen twice
-    pub obsolete_set: HashSet<ObsoleteSyntax>,
     /// Used to determine the path to externally loaded source files
     pub directory: Directory,
     /// Whether to parse sub-modules in other files.
@@ -358,7 +353,7 @@ impl TokenCursor {
 
         let body = TokenTree::Delimited(sp, Delimited {
             delim: token::Bracket,
-            tts: [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"))),
+            tts: [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"), false)),
                   TokenTree::Token(sp, token::Eq),
                   TokenTree::Token(sp, token::Literal(
                       token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))]
@@ -549,13 +544,12 @@ impl<'a> Parser<'a> {
                -> Self {
         let mut parser = Parser {
             sess,
-            token: token::Underscore,
+            token: token::Whitespace,
             span: syntax_pos::DUMMY_SP,
             prev_span: syntax_pos::DUMMY_SP,
             meta_var_span: None,
             prev_token_kind: PrevTokenKind::Other,
             restrictions: Restrictions::empty(),
-            obsolete_set: HashSet::new(),
             recurse_into_file_modules,
             directory: Directory {
                 path: PathBuf::new(),
@@ -784,7 +778,7 @@ impl<'a> Parser<'a> {
 
     fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> {
         match self.token {
-            token::Ident(i) => {
+            token::Ident(i, _) => {
                 if self.token.is_reserved_ident() {
                     let mut err = self.expected_ident_found();
                     if recover {
@@ -800,11 +794,7 @@ impl<'a> Parser<'a> {
                 Err(if self.prev_token_kind == PrevTokenKind::DocComment {
                         self.span_fatal_err(self.prev_span, Error::UselessDocComment)
                     } else {
-                        let mut err = self.expected_ident_found();
-                        if self.token == token::Underscore {
-                            err.note("`_` is a wildcard pattern, not an identifier");
-                        }
-                        err
+                        self.expected_ident_found()
                     })
             }
         }
@@ -1512,7 +1502,7 @@ impl<'a> Parser<'a> {
         if self.eat(&token::RArrow) {
             Ok(FunctionRetTy::Ty(self.parse_ty_common(allow_plus, true)?))
         } else {
-            Ok(FunctionRetTy::Default(self.span.with_hi(self.span.lo())))
+            Ok(FunctionRetTy::Default(self.span.shrink_to_lo()))
         }
     }
 
@@ -1602,7 +1592,7 @@ impl<'a> Parser<'a> {
             let e = self.parse_expr()?;
             self.expect(&token::CloseDelim(token::Paren))?;
             TyKind::Typeof(e)
-        } else if self.eat(&token::Underscore) {
+        } else if self.eat_keyword(keywords::Underscore) {
             // A type to be inferred `_`
             TyKind::Infer
         } else if self.token_is_bare_fn_keyword() {
@@ -1796,7 +1786,7 @@ impl<'a> Parser<'a> {
             _ => 0,
         };
 
-        self.look_ahead(offset, |t| t.is_ident() || t == &token::Underscore) &&
+        self.look_ahead(offset, |t| t.is_ident()) &&
         self.look_ahead(offset + 1, |t| t == &token::Colon)
     }
 
@@ -1929,7 +1919,7 @@ impl<'a> Parser<'a> {
 
     pub fn parse_path_segment_ident(&mut self) -> PResult<'a, ast::Ident> {
         match self.token {
-            token::Ident(sid) if self.token.is_path_segment_keyword() => {
+            token::Ident(sid, _) if self.token.is_path_segment_keyword() => {
                 self.bump();
                 Ok(sid)
             }
@@ -1990,7 +1980,7 @@ impl<'a> Parser<'a> {
         let lo = self.meta_var_span.unwrap_or(self.span);
         let mut segments = Vec::new();
         if self.eat(&token::ModSep) {
-            segments.push(PathSegment::crate_root(lo));
+            segments.push(PathSegment::crate_root(lo.shrink_to_lo()));
         }
         self.parse_path_segments(&mut segments, style, enable_warning)?;
 
@@ -2025,7 +2015,7 @@ impl<'a> Parser<'a> {
         loop {
             segments.push(self.parse_path_segment(style, enable_warning)?);
 
-            if self.is_import_coupler(false) || !self.eat(&token::ModSep) {
+            if self.is_import_coupler() || !self.eat(&token::ModSep) {
                 return Ok(());
             }
         }
@@ -2744,11 +2734,14 @@ impl<'a> Parser<'a> {
     }
 
     pub fn process_potential_macro_variable(&mut self) {
-        let ident = match self.token {
+        let (ident, is_raw) = match self.token {
             token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() &&
                              self.look_ahead(1, |t| t.is_ident()) => {
                 self.bump();
-                let name = match self.token { token::Ident(ident) => ident, _ => unreachable!() };
+                let name = match self.token {
+                    token::Ident(ident, _) => ident,
+                    _ => unreachable!()
+                };
                 let mut err = self.fatal(&format!("unknown macro variable `{}`", name));
                 err.span_label(self.span, "unknown macro variable");
                 err.emit();
@@ -2757,13 +2750,13 @@ impl<'a> Parser<'a> {
             token::Interpolated(ref nt) => {
                 self.meta_var_span = Some(self.span);
                 match nt.0 {
-                    token::NtIdent(ident) => ident,
+                    token::NtIdent(ident, is_raw) => (ident, is_raw),
                     _ => return,
                 }
             }
             _ => return,
         };
-        self.token = token::Ident(ident.node);
+        self.token = token::Ident(ident.node, is_raw);
         self.span = ident.span;
     }
 
@@ -2782,7 +2775,7 @@ impl<'a> Parser<'a> {
             },
             token::CloseDelim(_) | token::Eof => unreachable!(),
             _ => {
-                let (token, span) = (mem::replace(&mut self.token, token::Underscore), self.span);
+                let (token, span) = (mem::replace(&mut self.token, token::Whitespace), self.span);
                 self.bump();
                 TokenTree::Token(span, token)
             }
@@ -3622,7 +3615,7 @@ impl<'a> Parser<'a> {
                         slice = Some(P(Pat {
                             id: ast::DUMMY_NODE_ID,
                             node: PatKind::Wild,
-                            span: self.span,
+                            span: self.prev_span,
                         }));
                         before_slice = false;
                     }
@@ -3676,7 +3669,13 @@ impl<'a> Parser<'a> {
                 if self.token != token::CloseDelim(token::Brace) {
                     let token_str = self.this_token_to_string();
                     let mut err = self.fatal(&format!("expected `{}`, found `{}`", "}", token_str));
-                    err.span_label(self.span, "expected `}`");
+                    if self.token == token::Comma { // Issue #49257
+                        err.span_label(self.span,
+                                       "`..` must be in the last position, \
+                                        and cannot have a trailing comma");
+                    } else {
+                        err.span_label(self.span, "expected `}`");
+                    }
                     return Err(err);
                 }
                 etc = true;
@@ -3815,11 +3814,6 @@ impl<'a> Parser<'a> {
         let lo = self.span;
         let pat;
         match self.token {
-            token::Underscore => {
-                // Parse _
-                self.bump();
-                pat = PatKind::Wild;
-            }
             token::BinOp(token::And) | token::AndAnd => {
                 // Parse &pat / &mut pat
                 self.expect_and()?;
@@ -3849,8 +3843,11 @@ impl<'a> Parser<'a> {
                 self.expect(&token::CloseDelim(token::Bracket))?;
                 pat = PatKind::Slice(before, slice, after);
             }
-            // At this point, token != _, &, &&, (, [
-            _ => if self.eat_keyword(keywords::Mut) {
+            // At this point, token != &, &&, (, [
+            _ => if self.eat_keyword(keywords::Underscore) {
+                // Parse _
+                pat = PatKind::Wild;
+            } else if self.eat_keyword(keywords::Mut) {
                 // Parse mut ident @ pat / mut ref ident @ pat
                 let mutref_span = self.prev_span.to(self.span);
                 let binding_mode = if self.eat_keyword(keywords::Ref) {
@@ -4251,7 +4248,7 @@ impl<'a> Parser<'a> {
                      -> PResult<'a, Option<P<Item>>> {
         let token_lo = self.span;
         let (ident, def) = match self.token {
-            token::Ident(ident) if ident.name == keywords::Macro.name() => {
+            token::Ident(ident, false) if ident.name == keywords::Macro.name() => {
                 self.bump();
                 let ident = self.parse_ident()?;
                 let tokens = if self.check(&token::OpenDelim(token::Brace)) {
@@ -4279,7 +4276,7 @@ impl<'a> Parser<'a> {
 
                 (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
             }
-            token::Ident(ident) if ident.name == "macro_rules" &&
+            token::Ident(ident, _) if ident.name == "macro_rules" &&
                                    self.look_ahead(1, |t| *t == token::Not) => {
                 let prev_span = self.prev_span;
                 self.complain_if_pub_macro(&vis.node, prev_span);
@@ -5084,7 +5081,9 @@ impl<'a> Parser<'a> {
     fn parse_self_arg(&mut self) -> PResult<'a, Option<Arg>> {
         let expect_ident = |this: &mut Self| match this.token {
             // Preserve hygienic context.
-            token::Ident(ident) => { let sp = this.span; this.bump(); codemap::respan(sp, ident) }
+            token::Ident(ident, _) => {
+                let sp = this.span; this.bump(); codemap::respan(sp, ident)
+            }
             _ => unreachable!()
         };
         let isolated_self = |this: &mut Self, n| {
@@ -5381,7 +5380,7 @@ impl<'a> Parser<'a> {
             VisibilityKind::Inherited => Ok(()),
             _ => {
                 let is_macro_rules: bool = match self.token {
-                    token::Ident(sid) => sid.name == Symbol::intern("macro_rules"),
+                    token::Ident(sid, _) => sid.name == Symbol::intern("macro_rules"),
                     _ => false,
                 };
                 if is_macro_rules {
@@ -5869,7 +5868,7 @@ impl<'a> Parser<'a> {
                 // `pub(in path)`
                 self.bump(); // `(`
                 self.bump(); // `in`
-                let path = self.parse_path(PathStyle::Mod)?.default_to_global(); // `path`
+                let path = self.parse_path(PathStyle::Mod)?; // `path`
                 self.expect(&token::CloseDelim(token::Paren))?; // `)`
                 let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
                     path: P(path),
@@ -5882,7 +5881,7 @@ impl<'a> Parser<'a> {
             {
                 // `pub(self)` or `pub(super)`
                 self.bump(); // `(`
-                let path = self.parse_path(PathStyle::Mod)?.default_to_global(); // `super`/`self`
+                let path = self.parse_path(PathStyle::Mod)?; // `super`/`self`
                 self.expect(&token::CloseDelim(token::Paren))?; // `)`
                 let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
                     path: P(path),
@@ -6291,23 +6290,17 @@ impl<'a> Parser<'a> {
                                lo: Span,
                                visibility: Visibility,
                                attrs: Vec<Attribute>)
-                                -> PResult<'a, P<Item>> {
-
-        let crate_name = self.parse_ident()?;
-        let (maybe_path, ident) = if let Some(ident) = self.parse_rename()? {
-            (Some(crate_name.name), ident)
+                               -> PResult<'a, P<Item>> {
+        let orig_name = self.parse_ident()?;
+        let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
+            (rename, Some(orig_name.name))
         } else {
-            (None, crate_name)
+            (orig_name, None)
         };
         self.expect(&token::Semi)?;
 
-        let prev_span = self.prev_span;
-
-        Ok(self.mk_item(lo.to(prev_span),
-                        ident,
-                        ItemKind::ExternCrate(maybe_path),
-                        visibility,
-                        attrs))
+        let span = lo.to(self.prev_span);
+        Ok(self.mk_item(span, item_name, ItemKind::ExternCrate(orig_name), visibility, attrs))
     }
 
     /// Parse `extern` for foreign ABIs
@@ -6486,12 +6479,11 @@ impl<'a> Parser<'a> {
 
         if self.eat_keyword(keywords::Use) {
             // USE ITEM
-            let item_ = ItemKind::Use(P(self.parse_use_tree(false)?));
+            let item_ = ItemKind::Use(P(self.parse_use_tree()?));
             self.expect(&token::Semi)?;
 
-            let prev_span = self.prev_span;
-            let invalid = keywords::Invalid.ident();
-            let item = self.mk_item(lo.to(prev_span), invalid, item_, visibility, attrs);
+            let span = lo.to(self.prev_span);
+            let item = self.mk_item(span, keywords::Invalid.ident(), item_, visibility, attrs);
             return Ok(Some(item));
         }
 
@@ -6966,90 +6958,53 @@ impl<'a> Parser<'a> {
         }))
     }
 
-    /// `{` or `::{` or `*` or `::*`
-    /// `::{` or `::*` (also `{`  or `*` if unprefixed is true)
-    fn is_import_coupler(&mut self, unprefixed: bool) -> bool {
-        self.is_import_coupler_inner(&token::OpenDelim(token::Brace), unprefixed) ||
-            self.is_import_coupler_inner(&token::BinOp(token::Star), unprefixed)
-    }
-
-    fn is_import_coupler_inner(&mut self, token: &token::Token, unprefixed: bool) -> bool {
-        if self.check(&token::ModSep) {
-            self.look_ahead(1, |t| t == token)
-        } else if unprefixed {
-            self.check(token)
-        } else {
-            false
-        }
+    /// `::{` or `::*`
+    fn is_import_coupler(&mut self) -> bool {
+        self.check(&token::ModSep) &&
+            self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace) ||
+                                   *t == token::BinOp(token::Star))
     }
 
     /// Parse UseTree
     ///
-    /// USE_TREE = `*` |
-    ///            `{` USE_TREE_LIST `}` |
+    /// USE_TREE = [`::`] `*` |
+    ///            [`::`] `{` USE_TREE_LIST `}` |
     ///            PATH `::` `*` |
     ///            PATH `::` `{` USE_TREE_LIST `}` |
     ///            PATH [`as` IDENT]
-    fn parse_use_tree(&mut self, nested: bool) -> PResult<'a, UseTree> {
+    fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
         let lo = self.span;
 
-        let mut prefix = ast::Path {
-            segments: vec![],
-            span: lo.to(self.span),
-        };
-
-        let kind = if self.is_import_coupler(true) {
-            // `use *;` or `use ::*;` or `use {...};` `use ::{...};`
-
-            // Remove the first `::`
+        let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo() };
+        let kind = if self.check(&token::OpenDelim(token::Brace)) ||
+                      self.check(&token::BinOp(token::Star)) ||
+                      self.is_import_coupler() {
+            // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
             if self.eat(&token::ModSep) {
-                prefix.segments.push(PathSegment::crate_root(self.prev_span));
-            } else if !nested {
-                prefix.segments.push(PathSegment::crate_root(self.span));
+                prefix.segments.push(PathSegment::crate_root(lo.shrink_to_lo()));
             }
 
             if self.eat(&token::BinOp(token::Star)) {
-                // `use *;`
                 UseTreeKind::Glob
-            } else if self.check(&token::OpenDelim(token::Brace)) {
-                // `use {...};`
-                UseTreeKind::Nested(self.parse_use_tree_list()?)
             } else {
-                return self.unexpected();
+                UseTreeKind::Nested(self.parse_use_tree_list()?)
             }
         } else {
-            // `use path::...;`
-            let mut parsed = self.parse_path(PathStyle::Mod)?;
-            if !nested {
-                parsed = parsed.default_to_global();
-            }
-
-            prefix.segments.append(&mut parsed.segments);
-            prefix.span = prefix.span.to(parsed.span);
+            // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
+            prefix = self.parse_path(PathStyle::Mod)?;
 
             if self.eat(&token::ModSep) {
                 if self.eat(&token::BinOp(token::Star)) {
-                    // `use path::*;`
                     UseTreeKind::Glob
-                } else if self.check(&token::OpenDelim(token::Brace)) {
-                    // `use path::{...};`
-                    UseTreeKind::Nested(self.parse_use_tree_list()?)
                 } else {
-                    return self.unexpected();
+                    UseTreeKind::Nested(self.parse_use_tree_list()?)
                 }
             } else {
-                // `use path::foo;` or `use path::foo as bar;`
-                let rename = self.parse_rename()?.
-                                  unwrap_or(prefix.segments.last().unwrap().identifier);
-                UseTreeKind::Simple(rename)
+                UseTreeKind::Simple(self.parse_rename()?)
             }
         };
 
-        Ok(UseTree {
-            span: lo.to(self.prev_span),
-            kind,
-            prefix,
-        })
+        Ok(UseTree { prefix, kind, span: lo.to(self.prev_span) })
     }
 
     /// Parse UseTreeKind::Nested(list)
@@ -7059,16 +7014,18 @@ impl<'a> Parser<'a> {
         self.parse_unspanned_seq(&token::OpenDelim(token::Brace),
                                  &token::CloseDelim(token::Brace),
                                  SeqSep::trailing_allowed(token::Comma), |this| {
-            Ok((this.parse_use_tree(true)?, ast::DUMMY_NODE_ID))
+            Ok((this.parse_use_tree()?, ast::DUMMY_NODE_ID))
         })
     }
 
     fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
         if self.eat_keyword(keywords::As) {
-            if self.eat(&token::Underscore) {
-                Ok(Some(Ident::with_empty_ctxt(Symbol::gensym("_"))))
-            } else {
-                self.parse_ident().map(Some)
+            match self.token {
+                token::Ident(ident, false) if ident.name == keywords::Underscore.name() => {
+                    self.bump(); // `_`
+                    Ok(Some(Ident { name: ident.name.gensymed(), ..ident }))
+                }
+                _ => self.parse_ident().map(Some),
             }
         } else {
             Ok(None)
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 097a2eb89fdf4..e2dfca5d10a3c 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -91,8 +91,8 @@ impl Lit {
     }
 }
 
-fn ident_can_begin_expr(ident: ast::Ident) -> bool {
-    let ident_token: Token = Ident(ident);
+fn ident_can_begin_expr(ident: ast::Ident, is_raw: bool) -> bool {
+    let ident_token: Token = Ident(ident, is_raw);
 
     !ident_token.is_reserved_ident() ||
     ident_token.is_path_segment_keyword() ||
@@ -116,12 +116,13 @@ fn ident_can_begin_expr(ident: ast::Ident) -> bool {
     ].contains(&ident.name)
 }
 
-fn ident_can_begin_type(ident: ast::Ident) -> bool {
-    let ident_token: Token = Ident(ident);
+fn ident_can_begin_type(ident: ast::Ident, is_raw: bool) -> bool {
+    let ident_token: Token = Ident(ident, is_raw);
 
     !ident_token.is_reserved_ident() ||
     ident_token.is_path_segment_keyword() ||
     [
+        keywords::Underscore.name(),
         keywords::For.name(),
         keywords::Impl.name(),
         keywords::Fn.name(),
@@ -131,6 +132,44 @@ fn ident_can_begin_type(ident: ast::Ident) -> bool {
     ].contains(&ident.name)
 }
 
+pub fn is_path_segment_keyword(id: ast::Ident) -> bool {
+    id.name == keywords::Super.name() ||
+    id.name == keywords::SelfValue.name() ||
+    id.name == keywords::SelfType.name() ||
+    id.name == keywords::Extern.name() ||
+    id.name == keywords::Crate.name() ||
+    id.name == keywords::CrateRoot.name() ||
+    id.name == keywords::DollarCrate.name()
+}
+
+// We see this identifier in a normal identifier position, like variable name or a type.
+// How was it written originally? Did it use the raw form? Let's try to guess.
+pub fn is_raw_guess(ident: ast::Ident) -> bool {
+    ident.name != keywords::Invalid.name() &&
+    is_reserved_ident(ident) && !is_path_segment_keyword(ident)
+}
+
+// Returns true for reserved identifiers used internally for elided lifetimes,
+// unnamed method parameters, crate root module, error recovery etc.
+pub fn is_special_ident(id: ast::Ident) -> bool {
+    id.name <= keywords::Underscore.name()
+}
+
+/// Returns `true` if the token is a keyword used in the language.
+pub fn is_used_keyword(id: ast::Ident) -> bool {
+    id.name >= keywords::As.name() && id.name <= keywords::While.name()
+}
+
+/// Returns `true` if the token is a keyword reserved for possible future use.
+pub fn is_unused_keyword(id: ast::Ident) -> bool {
+    id.name >= keywords::Abstract.name() && id.name <= keywords::Yield.name()
+}
+
+/// Returns `true` if the token is either a special identifier or a keyword.
+pub fn is_reserved_ident(id: ast::Ident) -> bool {
+    is_special_ident(id) || is_used_keyword(id) || is_unused_keyword(id)
+}
+
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug)]
 pub enum Token {
     /* Expression-operator symbols. */
@@ -174,8 +213,7 @@ pub enum Token {
     Literal(Lit, Option<ast::Name>),
 
     /* Name components */
-    Ident(ast::Ident),
-    Underscore,
+    Ident(ast::Ident, /* is_raw */ bool),
     Lifetime(ast::Ident),
 
     // The `LazyTokenStream` is a pure function of the `Nonterminal`,
@@ -203,6 +241,11 @@ impl Token {
         Token::Interpolated(Lrc::new((nt, LazyTokenStream::new())))
     }
 
+    /// Recovers a `Token` from an `ast::Ident`. This creates a raw identifier if necessary.
+    pub fn from_ast_ident(ident: ast::Ident) -> Token {
+        Ident(ident, is_raw_guess(ident))
+    }
+
     /// Returns `true` if the token starts with '>'.
     pub fn is_like_gt(&self) -> bool {
         match *self {
@@ -214,7 +257,8 @@ impl Token {
     /// Returns `true` if the token can appear at the start of an expression.
     pub fn can_begin_expr(&self) -> bool {
         match *self {
-            Ident(ident)                => ident_can_begin_expr(ident), // value name or keyword
+            Ident(ident, is_raw)              =>
+                ident_can_begin_expr(ident, is_raw), // value name or keyword
             OpenDelim(..)                     | // tuple, array or block
             Literal(..)                       | // literal
             Not                               | // operator not
@@ -239,10 +283,10 @@ impl Token {
     /// Returns `true` if the token can appear at the start of a type.
     pub fn can_begin_type(&self) -> bool {
         match *self {
-            Ident(ident)                => ident_can_begin_type(ident), // type name or keyword
+            Ident(ident, is_raw)        =>
+                ident_can_begin_type(ident, is_raw), // type name or keyword
             OpenDelim(Paren)            | // tuple
             OpenDelim(Bracket)          | // array
-            Underscore                  | // placeholder
             Not                         | // never
             BinOp(Star)                 | // raw pointer
             BinOp(And)                  | // reference
@@ -273,11 +317,11 @@ impl Token {
         }
     }
 
-    pub fn ident(&self) -> Option<ast::Ident> {
+    pub fn ident(&self) -> Option<(ast::Ident, bool)> {
         match *self {
-            Ident(ident) => Some(ident),
+            Ident(ident, is_raw) => Some((ident, is_raw)),
             Interpolated(ref nt) => match nt.0 {
-                NtIdent(ident) => Some(ident.node),
+                NtIdent(ident, is_raw) => Some((ident.node, is_raw)),
                 _ => None,
             },
             _ => None,
@@ -352,18 +396,13 @@ impl Token {
 
     /// Returns `true` if the token is a given keyword, `kw`.
     pub fn is_keyword(&self, kw: keywords::Keyword) -> bool {
-        self.ident().map(|ident| ident.name == kw.name()).unwrap_or(false)
+        self.ident().map(|(ident, is_raw)| ident.name == kw.name() && !is_raw).unwrap_or(false)
     }
 
     pub fn is_path_segment_keyword(&self) -> bool {
         match self.ident() {
-            Some(id) => id.name == keywords::Super.name() ||
-                        id.name == keywords::SelfValue.name() ||
-                        id.name == keywords::SelfType.name() ||
-                        id.name == keywords::Extern.name() ||
-                        id.name == keywords::Crate.name() ||
-                        id.name == keywords::DollarCrate.name(),
-            None => false,
+            Some((id, false)) => is_path_segment_keyword(id),
+            _ => false,
         }
     }
 
@@ -371,7 +410,7 @@ impl Token {
     // unnamed method parameters, crate root module, error recovery etc.
     pub fn is_special_ident(&self) -> bool {
         match self.ident() {
-            Some(id) => id.name <= keywords::DollarCrate.name(),
+            Some((id, false)) => is_special_ident(id),
             _ => false,
         }
     }
@@ -379,7 +418,7 @@ impl Token {
     /// Returns `true` if the token is a keyword used in the language.
     pub fn is_used_keyword(&self) -> bool {
         match self.ident() {
-            Some(id) => id.name >= keywords::As.name() && id.name <= keywords::While.name(),
+            Some((id, false)) => is_used_keyword(id),
             _ => false,
         }
     }
@@ -387,7 +426,7 @@ impl Token {
     /// Returns `true` if the token is a keyword reserved for possible future use.
     pub fn is_unused_keyword(&self) -> bool {
         match self.ident() {
-            Some(id) => id.name >= keywords::Abstract.name() && id.name <= keywords::Yield.name(),
+            Some((id, false)) => is_unused_keyword(id),
             _ => false,
         }
     }
@@ -441,7 +480,7 @@ impl Token {
 
             Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotEq |
             DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar |
-            Question | OpenDelim(..) | CloseDelim(..) | Underscore => return None,
+            Question | OpenDelim(..) | CloseDelim(..) => return None,
 
             Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) |
             Whitespace | Comment | Shebang(..) | Eof => return None,
@@ -460,7 +499,10 @@ impl Token {
 
     /// Returns `true` if the token is either a special identifier or a keyword.
     pub fn is_reserved_ident(&self) -> bool {
-        self.is_special_ident() || self.is_used_keyword() || self.is_unused_keyword()
+        match self.ident() {
+            Some((id, false)) => is_reserved_ident(id),
+            _ => false,
+        }
     }
 
     pub fn interpolated_to_tokenstream(&self, sess: &ParseSess, span: Span)
@@ -496,8 +538,8 @@ impl Token {
             Nonterminal::NtImplItem(ref item) => {
                 tokens = prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span);
             }
-            Nonterminal::NtIdent(ident) => {
-                let token = Token::Ident(ident.node);
+            Nonterminal::NtIdent(ident, is_raw) => {
+                let token = Token::Ident(ident.node, is_raw);
                 tokens = Some(TokenTree::Token(ident.span, token).into());
             }
             Nonterminal::NtLifetime(lifetime) => {
@@ -529,7 +571,7 @@ pub enum Nonterminal {
     NtPat(P<ast::Pat>),
     NtExpr(P<ast::Expr>),
     NtTy(P<ast::Ty>),
-    NtIdent(ast::SpannedIdent),
+    NtIdent(ast::SpannedIdent, /* is_raw */ bool),
     /// Stuff inside brackets for attributes
     NtMeta(ast::MetaItem),
     NtPath(ast::Path),
@@ -573,7 +615,7 @@ impl fmt::Debug for Nonterminal {
 pub fn is_op(tok: &Token) -> bool {
     match *tok {
         OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) |
-        Ident(..) | Underscore | Lifetime(..) | Interpolated(..) |
+        Ident(..) | Lifetime(..) | Interpolated(..) |
         Whitespace | Comment | Shebang(..) | Eof => false,
         _ => true,
     }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 1cf2b7a44bc17..ae045fc095a50 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -250,9 +250,9 @@ pub fn token_to_string(tok: &Token) -> String {
         }
 
         /* Name components */
-        token::Ident(s)             => s.to_string(),
+        token::Ident(s, false)      => s.to_string(),
+        token::Ident(s, true)       => format!("r#{}", s),
         token::Lifetime(s)          => s.to_string(),
-        token::Underscore           => "_".to_string(),
 
         /* Other */
         token::DocComment(s)        => s.to_string(),
@@ -262,24 +262,25 @@ pub fn token_to_string(tok: &Token) -> String {
         token::Shebang(s)           => format!("/* shebang: {}*/", s),
 
         token::Interpolated(ref nt) => match nt.0 {
-            token::NtExpr(ref e)        => expr_to_string(e),
-            token::NtMeta(ref e)        => meta_item_to_string(e),
-            token::NtTy(ref e)          => ty_to_string(e),
-            token::NtPath(ref e)        => path_to_string(e),
-            token::NtItem(ref e)        => item_to_string(e),
-            token::NtBlock(ref e)       => block_to_string(e),
-            token::NtStmt(ref e)        => stmt_to_string(e),
-            token::NtPat(ref e)         => pat_to_string(e),
-            token::NtIdent(ref e)       => ident_to_string(e.node),
-            token::NtTT(ref tree)       => tt_to_string(tree.clone()),
-            token::NtArm(ref e)         => arm_to_string(e),
-            token::NtImplItem(ref e)    => impl_item_to_string(e),
-            token::NtTraitItem(ref e)   => trait_item_to_string(e),
-            token::NtGenerics(ref e)    => generic_params_to_string(&e.params),
-            token::NtWhereClause(ref e) => where_clause_to_string(e),
-            token::NtArg(ref e)         => arg_to_string(e),
-            token::NtVis(ref e)         => vis_to_string(e),
-            token::NtLifetime(ref e)    => lifetime_to_string(e),
+            token::NtExpr(ref e)         => expr_to_string(e),
+            token::NtMeta(ref e)         => meta_item_to_string(e),
+            token::NtTy(ref e)           => ty_to_string(e),
+            token::NtPath(ref e)         => path_to_string(e),
+            token::NtItem(ref e)         => item_to_string(e),
+            token::NtBlock(ref e)        => block_to_string(e),
+            token::NtStmt(ref e)         => stmt_to_string(e),
+            token::NtPat(ref e)          => pat_to_string(e),
+            token::NtIdent(ref e, false) => ident_to_string(e.node),
+            token::NtIdent(ref e, true)  => format!("r#{}", ident_to_string(e.node)),
+            token::NtTT(ref tree)        => tt_to_string(tree.clone()),
+            token::NtArm(ref e)          => arm_to_string(e),
+            token::NtImplItem(ref e)     => impl_item_to_string(e),
+            token::NtTraitItem(ref e)    => trait_item_to_string(e),
+            token::NtGenerics(ref e)     => generic_params_to_string(&e.params),
+            token::NtWhereClause(ref e)  => where_clause_to_string(e),
+            token::NtArg(ref e)          => arg_to_string(e),
+            token::NtVis(ref e)          => vis_to_string(e),
+            token::NtLifetime(ref e)     => lifetime_to_string(e),
         }
     }
 }
@@ -353,7 +354,7 @@ pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
 }
 
 pub fn path_to_string(p: &ast::Path) -> String {
-    to_string(|s| s.print_path(p, false, 0, false))
+    to_string(|s| s.print_path(p, false, 0))
 }
 
 pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
@@ -1051,7 +1052,7 @@ impl<'a> State<'a> {
                                  &f.generic_params)?;
             }
             ast::TyKind::Path(None, ref path) => {
-                self.print_path(path, false, 0, false)?;
+                self.print_path(path, false, 0)?;
             }
             ast::TyKind::Path(Some(ref qself), ref path) => {
                 self.print_qpath(path, qself, false)?
@@ -1174,15 +1175,10 @@ impl<'a> State<'a> {
         self.print_outer_attributes(&item.attrs)?;
         self.ann.pre(self, NodeItem(item))?;
         match item.node {
-            ast::ItemKind::ExternCrate(ref optional_path) => {
+            ast::ItemKind::ExternCrate(orig_name) => {
                 self.head(&visibility_qualified(&item.vis, "extern crate"))?;
-                if let Some(p) = *optional_path {
-                    let val = p.as_str();
-                    if val.contains('-') {
-                        self.print_string(&val, ast::StrStyle::Cooked)?;
-                    } else {
-                        self.print_name(p)?;
-                    }
+                if let Some(orig_name) = orig_name {
+                    self.print_name(orig_name)?;
                     self.s.space()?;
                     self.s.word("as")?;
                     self.s.space()?;
@@ -1383,7 +1379,7 @@ impl<'a> State<'a> {
                 self.s.word(";")?;
             }
             ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => {
-                self.print_path(&node.path, false, 0, false)?;
+                self.print_path(&node.path, false, 0)?;
                 self.s.word("! ")?;
                 self.print_ident(item.ident)?;
                 self.cbox(INDENT_UNIT)?;
@@ -1408,7 +1404,7 @@ impl<'a> State<'a> {
     }
 
     fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> {
-        self.print_path(&t.path, false, 0, false)
+        self.print_path(&t.path, false, 0)
     }
 
     fn print_formal_generic_params(
@@ -1465,7 +1461,7 @@ impl<'a> State<'a> {
                 ast::CrateSugar::JustCrate => self.word_nbsp("crate")
             }
             ast::VisibilityKind::Restricted { ref path, .. } => {
-                let path = to_string(|s| s.print_path(path, false, 0, true));
+                let path = to_string(|s| s.print_path(path, false, 0));
                 if path == "self" || path == "super" {
                     self.word_nbsp(&format!("pub({})", path))
                 } else {
@@ -1573,7 +1569,7 @@ impl<'a> State<'a> {
                     ti.ident,
                     ty,
                     default.as_ref().map(|expr| &**expr),
-                    &codemap::respan(ti.span.empty(), ast::VisibilityKind::Inherited),
+                    &codemap::respan(ti.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
                 )?;
             }
             ast::TraitItemKind::Method(ref sig, ref body) => {
@@ -1584,7 +1580,7 @@ impl<'a> State<'a> {
                     ti.ident,
                     &ti.generics,
                     sig,
-                    &codemap::respan(ti.span.empty(), ast::VisibilityKind::Inherited),
+                    &codemap::respan(ti.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
                 )?;
                 if let Some(ref body) = *body {
                     self.nbsp()?;
@@ -1599,7 +1595,7 @@ impl<'a> State<'a> {
             }
             ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => {
                 // code copied from ItemKind::Mac:
-                self.print_path(&node.path, false, 0, false)?;
+                self.print_path(&node.path, false, 0)?;
                 self.s.word("! ")?;
                 self.cbox(INDENT_UNIT)?;
                 self.popen()?;
@@ -1633,7 +1629,7 @@ impl<'a> State<'a> {
             }
             ast::ImplItemKind::Macro(codemap::Spanned { ref node, .. }) => {
                 // code copied from ItemKind::Mac:
-                self.print_path(&node.path, false, 0, false)?;
+                self.print_path(&node.path, false, 0)?;
                 self.s.word("! ")?;
                 self.cbox(INDENT_UNIT)?;
                 self.popen()?;
@@ -1819,7 +1815,7 @@ impl<'a> State<'a> {
 
     pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
                      -> io::Result<()> {
-        self.print_path(&m.node.path, false, 0, false)?;
+        self.print_path(&m.node.path, false, 0)?;
         self.s.word("!")?;
         match delim {
             token::Paren => self.popen()?,
@@ -1920,7 +1916,7 @@ impl<'a> State<'a> {
                          fields: &[ast::Field],
                          wth: &Option<P<ast::Expr>>,
                          attrs: &[Attribute]) -> io::Result<()> {
-        self.print_path(path, true, 0, false)?;
+        self.print_path(path, true, 0)?;
         self.s.word("{")?;
         self.print_inner_attributes_inline(attrs)?;
         self.commasep_cmnt(
@@ -2241,7 +2237,7 @@ impl<'a> State<'a> {
                 }
             }
             ast::ExprKind::Path(None, ref path) => {
-                self.print_path(path, true, 0, false)?
+                self.print_path(path, true, 0)?
             }
             ast::ExprKind::Path(Some(ref qself), ref path) => {
                 self.print_qpath(path, qself, true)?
@@ -2377,7 +2373,11 @@ impl<'a> State<'a> {
     }
 
     pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
-        self.s.word(&ident.name.as_str())?;
+        if token::is_raw_guess(ident) {
+            self.s.word(&format!("r#{}", ident))?;
+        } else {
+            self.s.word(&ident.name.as_str())?;
+        }
         self.ann.post(self, NodeIdent(&ident))
     }
 
@@ -2401,17 +2401,12 @@ impl<'a> State<'a> {
     fn print_path(&mut self,
                   path: &ast::Path,
                   colons_before_params: bool,
-                  depth: usize,
-                  defaults_to_global: bool)
+                  depth: usize)
                   -> io::Result<()>
     {
         self.maybe_print_comment(path.span.lo())?;
 
-        let mut segments = path.segments[..path.segments.len()-depth].iter();
-        if defaults_to_global && path.is_global() {
-            segments.next();
-        }
-        for (i, segment) in segments.enumerate() {
+        for (i, segment) in path.segments[..path.segments.len() - depth].iter().enumerate() {
             if i > 0 {
                 self.s.word("::")?
             }
@@ -2450,7 +2445,7 @@ impl<'a> State<'a> {
             self.s.space()?;
             self.word_space("as")?;
             let depth = path.segments.len() - qself.position;
-            self.print_path(path, false, depth, false)?;
+            self.print_path(path, false, depth)?;
         }
         self.s.word(">")?;
         self.s.word("::")?;
@@ -2553,7 +2548,7 @@ impl<'a> State<'a> {
                 }
             }
             PatKind::TupleStruct(ref path, ref elts, ddpos) => {
-                self.print_path(path, true, 0, false)?;
+                self.print_path(path, true, 0)?;
                 self.popen()?;
                 if let Some(ddpos) = ddpos {
                     self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?;
@@ -2571,13 +2566,13 @@ impl<'a> State<'a> {
                 self.pclose()?;
             }
             PatKind::Path(None, ref path) => {
-                self.print_path(path, true, 0, false)?;
+                self.print_path(path, true, 0)?;
             }
             PatKind::Path(Some(ref qself), ref path) => {
                 self.print_qpath(path, qself, false)?;
             }
             PatKind::Struct(ref path, ref fields, etc) => {
-                self.print_path(path, true, 0, false)?;
+                self.print_path(path, true, 0)?;
                 self.nbsp()?;
                 self.word_space("{")?;
                 self.commasep_cmnt(
@@ -2954,18 +2949,17 @@ impl<'a> State<'a> {
 
     pub fn print_use_tree(&mut self, tree: &ast::UseTree) -> io::Result<()> {
         match tree.kind {
-            ast::UseTreeKind::Simple(ref ident) => {
-                self.print_path(&tree.prefix, false, 0, true)?;
-
-                if tree.prefix.segments.last().unwrap().identifier.name != ident.name {
+            ast::UseTreeKind::Simple(rename) => {
+                self.print_path(&tree.prefix, false, 0)?;
+                if let Some(rename) = rename {
                     self.s.space()?;
                     self.word_space("as")?;
-                    self.print_ident(*ident)?;
+                    self.print_ident(rename)?;
                 }
             }
             ast::UseTreeKind::Glob => {
                 if !tree.prefix.segments.is_empty() {
-                    self.print_path(&tree.prefix, false, 0, true)?;
+                    self.print_path(&tree.prefix, false, 0)?;
                     self.s.word("::")?;
                 }
                 self.s.word("*")?;
@@ -2974,7 +2968,7 @@ impl<'a> State<'a> {
                 if tree.prefix.segments.is_empty() {
                     self.s.word("{")?;
                 } else {
-                    self.print_path(&tree.prefix, false, 0, true)?;
+                    self.print_path(&tree.prefix, false, 0)?;
                     self.s.word("::{")?;
                 }
                 self.commasep(Inconsistent, &items[..], |this, &(ref tree, _)| {
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index da24107f4c33b..fdbc795b2d365 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -43,7 +43,7 @@ thread_local! {
     static INJECTED_CRATE_NAME: Cell<Option<&'static str>> = Cell::new(None);
 }
 
-pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<String>) -> ast::Crate {
+pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str>) -> ast::Crate {
     let name = if attr::contains_name(&krate.attrs, "no_core") {
         return krate;
     } else if attr::contains_name(&krate.attrs, "no_std") {
@@ -54,14 +54,12 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<Strin
 
     INJECTED_CRATE_NAME.with(|opt_name| opt_name.set(Some(name)));
 
-    let crate_name = Symbol::intern(&alt_std_name.unwrap_or_else(|| name.to_string()));
-
     krate.module.items.insert(0, P(ast::Item {
         attrs: vec![attr::mk_attr_outer(DUMMY_SP,
                                         attr::mk_attr_id(),
                                         attr::mk_word_item(Symbol::intern("macro_use")))],
         vis: dummy_spanned(ast::VisibilityKind::Inherited),
-        node: ast::ItemKind::ExternCrate(Some(crate_name)),
+        node: ast::ItemKind::ExternCrate(alt_std_name.map(Symbol::intern)),
         ident: ast::Ident::from_str(name),
         id: ast::DUMMY_NODE_ID,
         span: DUMMY_SP,
@@ -78,10 +76,10 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<Strin
             is_sugared_doc: false,
             span,
         }],
-        vis: respan(span.empty(), ast::VisibilityKind::Inherited),
+        vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
         node: ast::ItemKind::Use(P(ast::UseTree {
             prefix: ast::Path {
-                segments: ["{{root}}", name, "prelude", "v1"].into_iter().map(|name| {
+                segments: [name, "prelude", "v1"].into_iter().map(|name| {
                     ast::PathSegment::from_ident(ast::Ident::from_str(name), DUMMY_SP)
                 }).collect(),
                 span,
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 39306229c82b2..67a822e4e02af 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -78,7 +78,7 @@ pub fn modify_for_testing(sess: &ParseSess,
                           span_diagnostic: &errors::Handler,
                           features: &Features) -> ast::Crate {
     // Check for #[reexport_test_harness_main = "some_name"] which
-    // creates a `use some_name = __test::main;`. This needs to be
+    // creates a `use __test::main as some_name;`. This needs to be
     // unconditional, so that the attribute is still marked as used in
     // non-test builds.
     let reexport_test_harness_main =
@@ -240,7 +240,8 @@ fn mk_reexport_mod(cx: &mut TestCtxt,
                                   cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
     }).chain(tested_submods.into_iter().map(|(r, sym)| {
         let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
-        cx.ext_cx.item_use_simple_(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public), r, path)
+        cx.ext_cx.item_use_simple_(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public),
+                                   Some(r), path)
     })).collect();
 
     let reexport_mod = ast::Mod {
@@ -331,7 +332,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
             ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => {
                 // If the termination trait is active, the compiler will check that the output
                 // type implements the `Termination` trait as `libtest` enforces that.
-                let output_matches = if cx.features.termination_trait {
+                let output_matches = if cx.features.termination_trait_test {
                     true
                 } else {
                     let no_output = match decl.output {
@@ -358,7 +359,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
         match has_test_signature(cx, i) {
             Yes => true,
             No => {
-                if cx.features.termination_trait {
+                if cx.features.termination_trait_test {
                     diag.span_err(i.span, "functions used as tests can not have any arguments");
                 } else {
                     diag.span_err(i.span, "functions used as tests must have signature fn() -> ()");
@@ -387,7 +388,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
 
                 // If the termination trait is active, the compiler will check that the output
                 // type implements the `Termination` trait as `libtest` enforces that.
-                let output_matches = if cx.features.termination_trait {
+                let output_matches = if cx.features.termination_trait_test {
                     true
                 } else {
                     let no_output = match decl.output {
@@ -415,7 +416,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
     if has_bench_attr && !has_bench_signature {
         let diag = cx.span_diagnostic;
 
-        if cx.features.termination_trait {
+        if cx.features.termination_trait_test {
             diag.span_err(i.span, "functions used as benches must have signature \
                                    `fn(&mut Bencher) -> impl Termination`");
         } else {
@@ -502,7 +503,7 @@ fn mk_std(cx: &TestCtxt) -> P<ast::Item> {
         (ast::ItemKind::Use(P(ast::UseTree {
             span: DUMMY_SP,
             prefix: path_node(vec![id_test]),
-            kind: ast::UseTreeKind::Simple(id_test),
+            kind: ast::UseTreeKind::Simple(None),
         })),
          ast::VisibilityKind::Public, keywords::Invalid.ident())
     } else {
@@ -546,7 +547,7 @@ fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> {
     // pub fn main() { ... }
     let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![]));
     let main_body = ecx.block(sp, vec![call_test_main]);
-    let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], main_ret_ty),
+    let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)),
                            ast::Unsafety::Normal,
                            dummy_spanned(ast::Constness::NotConst),
                            ::abi::Abi::Rust, ast::Generics::default(), main_body);
@@ -590,13 +591,13 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) {
         tokens: None,
     })).pop().unwrap();
     let reexport = cx.reexport_test_harness_main.map(|s| {
-        // building `use <ident> = __test::main`
-        let reexport_ident = Ident::with_empty_ctxt(s);
+        // building `use __test::main as <ident>;`
+        let rename = Ident::with_empty_ctxt(s);
 
         let use_path = ast::UseTree {
             span: DUMMY_SP,
             prefix: path_node(vec![mod_ident, Ident::from_str("main")]),
-            kind: ast::UseTreeKind::Simple(reexport_ident),
+            kind: ast::UseTreeKind::Simple(Some(rename)),
         };
 
         expander.fold_item(P(ast::Item {
@@ -627,8 +628,15 @@ fn path_node(ids: Vec<Ident>) -> ast::Path {
 }
 
 fn path_name_i(idents: &[Ident]) -> String {
-    // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
-    idents.iter().map(|i| i.to_string()).collect::<Vec<String>>().join("::")
+    let mut path_name = "".to_string();
+    let mut idents_iter = idents.iter().peekable();
+    while let Some(ident) = idents_iter.next() {
+        path_name.push_str(&ident.name.as_str());
+        if let Some(_) = idents_iter.peek() {
+            path_name.push_str("::")
+        }
+    }
+    path_name
 }
 
 fn mk_tests(cx: &TestCtxt) -> P<ast::Item> {
@@ -681,7 +689,6 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
     // gensym information.
 
     let span = ignored_span(cx, test.span);
-    let path = test.path.clone();
     let ecx = &cx.ext_cx;
     let self_id = ecx.ident_of("self");
     let test_id = ecx.ident_of("test");
@@ -693,10 +700,11 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
     // creates $name: $expr
     let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr);
 
-    debug!("encoding {}", path_name_i(&path[..]));
-
     // path to the #[test] function: "foo::bar::baz"
-    let path_string = path_name_i(&path[..]);
+    let path_string = path_name_i(&test.path[..]);
+
+    debug!("encoding {}", path_string);
+
     let name_expr = ecx.expr_str(span, Symbol::intern(&path_string));
 
     // self::test::StaticTestName($name_expr)
@@ -743,7 +751,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
             diag.bug("expected to find top-level re-export name, but found None");
         }
     };
-    visible_path.extend(path);
+    visible_path.extend_from_slice(&test.path[..]);
 
     // Rather than directly give the test function to the test
     // harness, we create a wrapper like one of the following:
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 1219e909e121a..3a7a1b9a66966 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -684,7 +684,7 @@ mod tests {
         with_globals(|| {
             let test0: TokenStream = Vec::<TokenTree>::new().into_iter().collect();
             let test1: TokenStream =
-                TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a"))).into();
+                TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a"), false)).into();
             let test2 = string_to_ts("foo(bar::baz)");
 
             assert_eq!(test0.is_empty(), true);
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 5a24c61cb5aaf..bbf1fe124f1ba 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -213,9 +213,9 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
     visitor.visit_vis(&item.vis);
     visitor.visit_ident(item.span, item.ident);
     match item.node {
-        ItemKind::ExternCrate(opt_name) => {
-            if let Some(name) = opt_name {
-                visitor.visit_name(item.span, name);
+        ItemKind::ExternCrate(orig_name) => {
+            if let Some(orig_name) = orig_name {
+                visitor.visit_name(item.span, orig_name);
             }
         }
         ItemKind::Use(ref use_tree) => {
@@ -354,10 +354,11 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(
     visitor: &mut V, use_tree: &'a UseTree, id: NodeId,
 ) {
     visitor.visit_path(&use_tree.prefix, id);
-
     match use_tree.kind {
-        UseTreeKind::Simple(ident) => {
-            visitor.visit_ident(use_tree.span, ident);
+        UseTreeKind::Simple(rename) => {
+            if let Some(rename) = rename {
+                visitor.visit_ident(use_tree.span, rename);
+            }
         }
         UseTreeKind::Glob => {},
         UseTreeKind::Nested(ref use_trees) => {
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index 8d0104e512bfb..d513008f0e2d3 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -44,7 +44,8 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
             }
         } else {
             match *e {
-                TokenTree::Token(_, token::Ident(ident)) => res_str.push_str(&ident.name.as_str()),
+                TokenTree::Token(_, token::Ident(ident, _)) =>
+                    res_str.push_str(&ident.name.as_str()),
                 _ => {
                     cx.span_err(sp, "concat_idents! requires ident args.");
                     return DummyResult::expr(sp);
diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs
index 743f22b6b3140..88baa22e7fa11 100644
--- a/src/libsyntax_ext/deriving/encodable.rs
+++ b/src/libsyntax_ext/deriving/encodable.rs
@@ -228,13 +228,13 @@ fn encodable_substructure(cx: &mut ExtCtxt,
             }
 
             // unit structs have no fields and need to return Ok()
-            if stmts.is_empty() {
+            let blk = if stmts.is_empty() {
                 let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![]));
-                let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok)));
-                stmts.push(cx.stmt_expr(ret_ok));
-            }
+                cx.lambda1(trait_span, ok, blkarg)
+            } else {
+                cx.lambda_stmts_1(trait_span, stmts, blkarg)
+            };
 
-            let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
             cx.expr_method_call(trait_span,
                                 encoder,
                                 cx.ident_of("emit_struct"),
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 1b3917efdd1e7..3935f1722b615 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -530,7 +530,7 @@ impl<'a> TraitDef<'a> {
                 id: ast::DUMMY_NODE_ID,
                 span: self.span,
                 ident,
-                vis: respan(self.span.empty(), ast::VisibilityKind::Inherited),
+                vis: respan(self.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
                 defaultness: ast::Defaultness::Final,
                 attrs: Vec::new(),
                 generics: Generics::default(),
@@ -962,7 +962,7 @@ impl<'a> MethodDef<'a> {
         let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident);
 
         let method_ident = cx.ident_of(self.name);
-        let fn_decl = cx.fn_decl(args, ret_type);
+        let fn_decl = cx.fn_decl(args, ast::FunctionRetTy::Ty(ret_type));
         let body_block = cx.block_expr(body);
 
         let unsafety = if self.is_unsafe {
@@ -977,7 +977,7 @@ impl<'a> MethodDef<'a> {
             attrs: self.attributes.clone(),
             generics: fn_generics,
             span: trait_.span,
-            vis: respan(trait_.span.empty(), ast::VisibilityKind::Inherited),
+            vis: respan(trait_.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
             defaultness: ast::Defaultness::Final,
             ident: method_ident,
             node: ast::ImplItemKind::Method(ast::MethodSig {
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index fcad065be52bc..ba6d25f7a60a4 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -17,7 +17,7 @@ use syntax::ast::{self, Ident};
 use syntax::ext::base::*;
 use syntax::ext::base;
 use syntax::ext::build::AstBuilder;
-use syntax::symbol::Symbol;
+use syntax::symbol::{keywords, Symbol};
 use syntax_pos::Span;
 use syntax::tokenstream;
 
@@ -35,14 +35,14 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
     let sp = sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark));
     let e = match env::var(&*var.as_str()) {
         Err(..) => {
+            let lt = cx.lifetime(sp, keywords::StaticLifetime.ident());
             cx.expr_path(cx.path_all(sp,
                                      true,
                                      cx.std_path(&["option", "Option", "None"]),
                                      Vec::new(),
                                      vec![cx.ty_rptr(sp,
                                                      cx.ty_ident(sp, Ident::from_str("str")),
-                                                     Some(cx.lifetime(sp,
-                                                                      Ident::from_str("'static"))),
+                                                     Some(lt),
                                                      ast::Mutability::Immutable)],
                                      Vec::new()))
         }
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 8fd95aa1ca861..d9c68e3167bd6 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -149,7 +149,7 @@ fn parse_args(ecx: &mut ExtCtxt,
         if named || (p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq)) {
             named = true;
             let ident = match p.token {
-                token::Ident(i) => {
+                token::Ident(i, _) => {
                     p.bump();
                     i
                 }
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 9605f6b5c5a9d..f01a0aacb0a73 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -60,7 +60,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt,
             asm,
             ctxt: cx.backtrace(),
         })),
-        vis: respan(sp.empty(), ast::VisibilityKind::Inherited),
+        vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
         span: sp,
         tokens: None,
     })))
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 4711d43bfab1a..eb345200f413d 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -21,7 +21,7 @@
 
 #![feature(const_fn)]
 #![feature(custom_attribute)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![feature(optin_builtin_traits)]
 #![allow(unused_attributes)]
 #![feature(specialization)]
@@ -184,8 +184,12 @@ impl SpanData {
     }
 }
 
-// The interner in thread-local, so `Span` shouldn't move between threads.
+// The interner is pointed to by a thread local value which is only set on the main thread
+// with parallelization is disabled. So we don't allow Span to transfer between threads
+// to avoid panics and other errors, even though it would be memory safe to do so.
+#[cfg(not(parallel_queries))]
 impl !Send for Span {}
+#[cfg(not(parallel_queries))]
 impl !Sync for Span {}
 
 impl PartialOrd for Span {
@@ -239,8 +243,15 @@ impl Span {
 
     /// Returns a new span representing an empty span at the beginning of this span
     #[inline]
-    pub fn empty(self) -> Span {
-        self.with_hi(self.lo())
+    pub fn shrink_to_lo(self) -> Span {
+        let span = self.data();
+        span.with_hi(span.lo)
+    }
+    /// Returns a new span representing an empty span at the end of this span
+    #[inline]
+    pub fn shrink_to_hi(self) -> Span {
+        let span = self.data();
+        span.with_lo(span.hi)
     }
 
     /// Returns `self` if `self` is not the dummy span, and `other` otherwise.
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index e95079f7c88dd..098eafef2585c 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -83,8 +83,12 @@ impl Decodable for Ident {
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Symbol(u32);
 
-// The interner in thread-local, so `Symbol` shouldn't move between threads.
+// The interner is pointed to by a thread local value which is only set on the main thread
+// with parallelization is disabled. So we don't allow Symbol to transfer between threads
+// to avoid panics and other errors, even though it would be memory safe to do so.
+#[cfg(not(parallel_queries))]
 impl !Send for Symbol { }
+#[cfg(not(parallel_queries))]
 impl !Sync for Symbol { }
 
 impl Symbol {
@@ -261,73 +265,77 @@ macro_rules! declare_keywords {(
 declare_keywords! {
     // Special reserved identifiers used internally for elided lifetimes,
     // unnamed method parameters, crate root module, error recovery etc.
-    (0,  Invalid,        "")
-    (1,  CrateRoot,      "{{root}}")
-    (2,  DollarCrate,    "$crate")
+    (0,  Invalid,            "")
+    (1,  CrateRoot,          "{{root}}")
+    (2,  DollarCrate,        "$crate")
+    (3,  Underscore,         "_")
 
     // Keywords used in the language.
-    (3,  As,             "as")
-    (4,  Box,            "box")
-    (5,  Break,          "break")
-    (6,  Const,          "const")
-    (7,  Continue,       "continue")
-    (8,  Crate,          "crate")
-    (9,  Else,           "else")
-    (10, Enum,           "enum")
-    (11, Extern,         "extern")
-    (12, False,          "false")
-    (13, Fn,             "fn")
-    (14, For,            "for")
-    (15, If,             "if")
-    (16, Impl,           "impl")
-    (17, In,             "in")
-    (18, Let,            "let")
-    (19, Loop,           "loop")
-    (20, Match,          "match")
-    (21, Mod,            "mod")
-    (22, Move,           "move")
-    (23, Mut,            "mut")
-    (24, Pub,            "pub")
-    (25, Ref,            "ref")
-    (26, Return,         "return")
-    (27, SelfValue,      "self")
-    (28, SelfType,       "Self")
-    (29, Static,         "static")
-    (30, Struct,         "struct")
-    (31, Super,          "super")
-    (32, Trait,          "trait")
-    (33, True,           "true")
-    (34, Type,           "type")
-    (35, Unsafe,         "unsafe")
-    (36, Use,            "use")
-    (37, Where,          "where")
-    (38, While,          "while")
+    (4,  As,                 "as")
+    (5,  Box,                "box")
+    (6,  Break,              "break")
+    (7,  Const,              "const")
+    (8,  Continue,           "continue")
+    (9,  Crate,              "crate")
+    (10, Else,               "else")
+    (11, Enum,               "enum")
+    (12, Extern,             "extern")
+    (13, False,              "false")
+    (14, Fn,                 "fn")
+    (15, For,                "for")
+    (16, If,                 "if")
+    (17, Impl,               "impl")
+    (18, In,                 "in")
+    (19, Let,                "let")
+    (20, Loop,               "loop")
+    (21, Match,              "match")
+    (22, Mod,                "mod")
+    (23, Move,               "move")
+    (24, Mut,                "mut")
+    (25, Pub,                "pub")
+    (26, Ref,                "ref")
+    (27, Return,             "return")
+    (28, SelfValue,          "self")
+    (29, SelfType,           "Self")
+    (30, Static,             "static")
+    (31, Struct,             "struct")
+    (32, Super,              "super")
+    (33, Trait,              "trait")
+    (34, True,               "true")
+    (35, Type,               "type")
+    (36, Unsafe,             "unsafe")
+    (37, Use,                "use")
+    (38, Where,              "where")
+    (39, While,              "while")
 
     // Keywords reserved for future use.
-    (39, Abstract,       "abstract")
-    (40, Alignof,        "alignof")
-    (41, Become,         "become")
-    (42, Do,             "do")
-    (43, Final,          "final")
-    (44, Macro,          "macro")
-    (45, Offsetof,       "offsetof")
-    (46, Override,       "override")
-    (47, Priv,           "priv")
-    (48, Proc,           "proc")
-    (49, Pure,           "pure")
-    (50, Sizeof,         "sizeof")
-    (51, Typeof,         "typeof")
-    (52, Unsized,        "unsized")
-    (53, Virtual,        "virtual")
-    (54, Yield,          "yield")
+    (40, Abstract,           "abstract")
+    (41, Alignof,            "alignof")
+    (42, Become,             "become")
+    (43, Do,                 "do")
+    (44, Final,              "final")
+    (45, Macro,              "macro")
+    (46, Offsetof,           "offsetof")
+    (47, Override,           "override")
+    (48, Priv,               "priv")
+    (49, Proc,               "proc")
+    (50, Pure,               "pure")
+    (51, Sizeof,             "sizeof")
+    (52, Typeof,             "typeof")
+    (53, Unsized,            "unsized")
+    (54, Virtual,            "virtual")
+    (55, Yield,              "yield")
+
+    // Special lifetime names
+    (56, UnderscoreLifetime, "'_")
+    (57, StaticLifetime,     "'static")
 
     // Weak keywords, have special meaning only in specific contexts.
-    (55, Auto,           "auto")
-    (56, Catch,          "catch")
-    (57, Default,        "default")
-    (58, Dyn,            "dyn")
-    (59, StaticLifetime, "'static")
-    (60, Union,          "union")
+    (58, Auto,               "auto")
+    (59, Catch,              "catch")
+    (60, Default,            "default")
+    (61, Dyn,                "dyn")
+    (62, Union,              "union")
 }
 
 // If an interner exists, return it. Otherwise, prepare a fresh one.
diff --git a/src/libtest/formatters/json.rs b/src/libtest/formatters/json.rs
index d323d50f702ba..89235d897bde6 100644
--- a/src/libtest/formatters/json.rs
+++ b/src/libtest/formatters/json.rs
@@ -36,17 +36,12 @@ impl<T: Write> JsonFormatter<T> {
         if let Some(extras) = extra {
             self.write_message(&*format!(
                 r#"{{ "type": "{}", "name": "{}", "event": "{}", {} }}"#,
-                ty,
-                name,
-                evt,
-                extras
+                ty, name, evt, extras
             ))
         } else {
             self.write_message(&*format!(
                 r#"{{ "type": "{}", "name": "{}", "event": "{}" }}"#,
-                ty,
-                name,
-                evt
+                ty, name, evt
             ))
         }
     }
@@ -89,14 +84,12 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
                 self.write_event("test", desc.name.as_slice(), "failed", extra_data)
             }
 
-            TrFailedMsg(ref m) => {
-                self.write_event(
-                    "test",
-                    desc.name.as_slice(),
-                    "failed",
-                    Some(format!(r#""message": "{}""#, EscapedString(m))),
-                )
-            }
+            TrFailedMsg(ref m) => self.write_event(
+                "test",
+                desc.name.as_slice(),
+                "failed",
+                Some(format!(r#""message": "{}""#, EscapedString(m))),
+            ),
 
             TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", None),
 
@@ -116,13 +109,10 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
 
                 let line = format!(
                     "{{ \"type\": \"bench\", \
-                                \"name\": \"{}\", \
-                                \"median\": {}, \
-                                \"deviation\": {}{} }}",
-                    desc.name,
-                    median,
-                    deviation,
-                    mbps
+                     \"name\": \"{}\", \
+                     \"median\": {}, \
+                     \"deviation\": {}{} }}",
+                    desc.name, median, deviation, mbps
                 );
 
                 self.write_message(&*line)
@@ -138,16 +128,15 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
     }
 
     fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
-
         self.write_message(&*format!(
             "{{ \"type\": \"suite\", \
-            \"event\": \"{}\", \
-            \"passed\": {}, \
-            \"failed\": {}, \
-            \"allowed_fail\": {}, \
-            \"ignored\": {}, \
-            \"measured\": {}, \
-            \"filtered_out\": \"{}\" }}",
+             \"event\": \"{}\", \
+             \"passed\": {}, \
+             \"failed\": {}, \
+             \"allowed_fail\": {}, \
+             \"ignored\": {}, \
+             \"measured\": {}, \
+             \"filtered_out\": \"{}\" }}",
             if state.failed == 0 { "ok" } else { "failed" },
             state.passed,
             state.failed + state.allowed_fail,
diff --git a/src/libtest/formatters/pretty.rs b/src/libtest/formatters/pretty.rs
index f2064deefce62..8e5fa00b5f27d 100644
--- a/src/libtest/formatters/pretty.rs
+++ b/src/libtest/formatters/pretty.rs
@@ -196,8 +196,7 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
 
         self.write_plain(&format!(
             "test {} has been running for over {} seconds\n",
-            desc.name,
-            TEST_WARN_TIMEOUT_S
+            desc.name, TEST_WARN_TIMEOUT_S
         ))
     }
 
@@ -232,11 +231,7 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
         } else {
             format!(
                 ". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n",
-                state.passed,
-                state.failed,
-                state.ignored,
-                state.measured,
-                state.filtered_out
+                state.passed, state.failed, state.ignored, state.measured, state.filtered_out
             )
         };
 
diff --git a/src/libtest/formatters/terse.rs b/src/libtest/formatters/terse.rs
index 88689485144c0..85286027d6921 100644
--- a/src/libtest/formatters/terse.rs
+++ b/src/libtest/formatters/terse.rs
@@ -195,8 +195,7 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
     fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
         self.write_plain(&format!(
             "test {} has been running for over {} seconds\n",
-            desc.name,
-            TEST_WARN_TIMEOUT_S
+            desc.name, TEST_WARN_TIMEOUT_S
         ))
     }
 
@@ -231,11 +230,7 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
         } else {
             format!(
                 ". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n",
-                state.passed,
-                state.failed,
-                state.ignored,
-                state.measured,
-                state.filtered_out
+                state.passed, state.failed, state.ignored, state.measured, state.filtered_out
             )
         };
 
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 59d701dd0fbc8..b8be1aeff1742 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -30,10 +30,8 @@
 #![unstable(feature = "test", issue = "27812")]
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
-       html_root_url = "https://doc.rust-lang.org/nightly/",
-       test(attr(deny(warnings))))]
+       html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
 #![deny(warnings)]
-
 #![feature(asm)]
 #![feature(fnbox)]
 #![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))]
@@ -43,10 +41,10 @@
 #![feature(termination_trait_lib)]
 
 extern crate getopts;
-extern crate term;
 #[cfg(any(unix, target_os = "cloudabi"))]
 extern crate libc;
 extern crate panic_unwind;
+extern crate term;
 
 pub use self::TestFn::*;
 pub use self::ColorConfig::*;
@@ -72,7 +70,7 @@ use std::process::Termination;
 use std::sync::mpsc::{channel, Sender};
 use std::sync::{Arc, Mutex};
 use std::thread;
-use std::time::{Instant, Duration};
+use std::time::{Duration, Instant};
 use std::borrow::Cow;
 use std::process;
 
@@ -81,16 +79,16 @@ const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in qu
 
 // to be used by rustc to compile tests in libtest
 pub mod test {
-    pub use {Bencher, TestName, TestResult, TestDesc, TestDescAndFn, TestOpts, TrFailed,
-             TrFailedMsg, TrIgnored, TrOk, Metric, MetricMap, StaticTestFn, StaticTestName,
-             DynTestName, DynTestFn, assert_test_result, run_test, test_main, test_main_static,
-             filter_tests, parse_opts, StaticBenchFn, ShouldPanic, Options};
+    pub use {assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static,
+             Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, ShouldPanic,
+             StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName,
+             TestOpts, TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk};
 }
 
 pub mod stats;
 mod formatters;
 
-use formatters::{OutputFormatter, PrettyFormatter, TerseFormatter, JsonFormatter};
+use formatters::{JsonFormatter, OutputFormatter, PrettyFormatter, TerseFormatter};
 
 // The name of a test. By convention this follows the rules for rust
 // paths; i.e. it should be a series of identifiers separated by double
@@ -255,7 +253,9 @@ pub struct Options {
 
 impl Options {
     pub fn new() -> Options {
-        Options { display_output: false }
+        Options {
+            display_output: false,
+        }
     }
 
     pub fn display_output(mut self, display_output: bool) -> Options {
@@ -272,7 +272,7 @@ pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Options) {
         Some(Err(msg)) => {
             eprintln!("error: {}", msg);
             process::exit(101);
-        },
+        }
         None => return,
     };
 
@@ -289,7 +289,7 @@ pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Options) {
             Err(e) => {
                 eprintln!("error: io error when listing tests: {:?}", e);
                 process::exit(101);
-            },
+            }
         }
     }
 }
@@ -306,18 +306,14 @@ pub fn test_main_static(tests: &[TestDescAndFn]) {
     let owned_tests = tests
         .iter()
         .map(|t| match t.testfn {
-            StaticTestFn(f) => {
-                TestDescAndFn {
-                    testfn: StaticTestFn(f),
-                    desc: t.desc.clone(),
-                }
-            }
-            StaticBenchFn(f) => {
-                TestDescAndFn {
-                    testfn: StaticBenchFn(f),
-                    desc: t.desc.clone(),
-                }
-            }
+            StaticTestFn(f) => TestDescAndFn {
+                testfn: StaticTestFn(f),
+                desc: t.desc.clone(),
+            },
+            StaticBenchFn(f) => TestDescAndFn {
+                testfn: StaticBenchFn(f),
+                desc: t.desc.clone(),
+            },
             _ => panic!("non-static tests passed to test::test_main_static"),
         })
         .collect();
@@ -397,34 +393,34 @@ fn optgroups() -> getopts::Options {
             "",
             "logfile",
             "Write logs to the specified file instead \
-                                of stdout",
+             of stdout",
             "PATH",
         )
         .optflag(
             "",
             "nocapture",
             "don't capture stdout/stderr of each \
-                                   task, allow printing directly",
+             task, allow printing directly",
         )
         .optopt(
             "",
             "test-threads",
             "Number of threads used for running tests \
-                                     in parallel",
+             in parallel",
             "n_threads",
         )
         .optmulti(
             "",
             "skip",
             "Skip tests whose names contain FILTER (this flag can \
-                               be used multiple times)",
+             be used multiple times)",
             "FILTER",
         )
         .optflag(
             "q",
             "quiet",
             "Display one character per test instead of one line. \
-                                Alias to --format=terse",
+             Alias to --format=terse",
         )
         .optflag(
             "",
@@ -516,8 +512,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
     if let Some(opt) = matches.opt_str("Z") {
         if !is_nightly() {
             return Some(Err(
-                "the option `Z` is only accepted on the nightly compiler"
-                    .into(),
+                "the option `Z` is only accepted on the nightly compiler".into(),
             ));
         }
 
@@ -562,19 +557,17 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
     }
 
     let test_threads = match matches.opt_str("test-threads") {
-        Some(n_str) => {
-            match n_str.parse::<usize>() {
-                Ok(0) => return Some(Err(format!("argument for --test-threads must not be 0"))),
-                Ok(n) => Some(n),
-                Err(e) => {
-                    return Some(Err(format!(
-                        "argument for --test-threads must be a number > 0 \
-                                             (error: {})",
-                        e
-                    )))
-                }
+        Some(n_str) => match n_str.parse::<usize>() {
+            Ok(0) => return Some(Err(format!("argument for --test-threads must not be 0"))),
+            Ok(n) => Some(n),
+            Err(e) => {
+                return Some(Err(format!(
+                    "argument for --test-threads must be a number > 0 \
+                     (error: {})",
+                    e
+                )))
             }
-        }
+        },
         None => None,
     };
 
@@ -586,7 +579,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         Some(v) => {
             return Some(Err(format!(
                 "argument for --color must be auto, always, or never (was \
-                                     {})",
+                 {})",
                 v
             )))
         }
@@ -599,8 +592,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         Some("json") => {
             if !allow_unstable {
                 return Some(Err(
-                    "The \"json\" format is only accepted on the nightly compiler"
-                        .into(),
+                    "The \"json\" format is only accepted on the nightly compiler".into(),
                 ));
             }
             OutputFormat::Json
@@ -609,7 +601,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         Some(v) => {
             return Some(Err(format!(
                 "argument for --format must be pretty, terse, or json (was \
-                                     {})",
+                 {})",
                 v
             )))
         }
@@ -811,8 +803,7 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Res
                 ntest += 1;
                 "test"
             }
-            StaticBenchFn(..) |
-            DynBenchFn(..) => {
+            StaticBenchFn(..) | DynBenchFn(..) => {
                 nbench += 1;
                 "benchmark"
             }
@@ -834,7 +825,8 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Res
             writeln!(output, "")?;
         }
 
-        writeln!(output,
+        writeln!(
+            output,
             "{}, {}",
             plural(ntest, "test"),
             plural(nbench, "benchmark")
@@ -851,7 +843,6 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
         st: &mut ConsoleTestState,
         out: &mut OutputFormatter,
     ) -> io::Result<()> {
-
         match (*event).clone() {
             TeFiltered(ref filtered_tests) => {
                 st.total = filtered_tests.len();
@@ -989,8 +980,7 @@ fn use_color(opts: &TestOpts) -> bool {
     }
 }
 
-#[cfg(any(target_os = "cloudabi",
-          target_os = "redox",
+#[cfg(any(target_os = "cloudabi", target_os = "redox",
           all(target_arch = "wasm32", not(target_os = "emscripten"))))]
 fn stdout_isatty() -> bool {
     // FIXME: Implement isatty on Redox
@@ -1089,10 +1079,12 @@ where
         let now = Instant::now();
         let timed_out = running_tests
             .iter()
-            .filter_map(|(desc, timeout)| if &now >= timeout {
-                Some(desc.clone())
-            } else {
-                None
+            .filter_map(|(desc, timeout)| {
+                if &now >= timeout {
+                    Some(desc.clone())
+                } else {
+                    None
+                }
             })
             .collect();
         for test in &timed_out {
@@ -1174,12 +1166,10 @@ fn get_concurrency() -> usize {
             let opt_n: Option<usize> = s.parse().ok();
             match opt_n {
                 Some(n) if n > 0 => n,
-                _ => {
-                    panic!(
-                        "RUST_TEST_THREADS is `{}`, should be a positive integer.",
-                        s
-                    )
-                }
+                _ => panic!(
+                    "RUST_TEST_THREADS is `{}`, should be a positive integer.",
+                    s
+                ),
             }
         }
         Err(..) => num_cpus(),
@@ -1223,20 +1213,15 @@ fn get_concurrency() -> usize {
         1
     }
 
-    #[cfg(any(target_os = "android",
-              target_os = "cloudabi",
-              target_os = "emscripten",
-              target_os = "fuchsia",
-              target_os = "ios",
-              target_os = "linux",
-              target_os = "macos",
-              target_os = "solaris"))]
+    #[cfg(any(target_os = "android", target_os = "cloudabi", target_os = "emscripten",
+              target_os = "fuchsia", target_os = "ios", target_os = "linux",
+              target_os = "macos", target_os = "solaris"))]
     fn num_cpus() -> usize {
         unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize }
     }
 
     #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig",
-                target_os = "netbsd"))]
+              target_os = "netbsd"))]
     fn num_cpus() -> usize {
         use std::ptr;
 
@@ -1308,26 +1293,28 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
     // Remove tests that don't match the test filter
     filtered = match opts.filter {
         None => filtered,
-        Some(ref filter) => {
-            filtered
-                .into_iter()
-                .filter(|test| if opts.filter_exact {
+        Some(ref filter) => filtered
+            .into_iter()
+            .filter(|test| {
+                if opts.filter_exact {
                     test.desc.name.as_slice() == &filter[..]
                 } else {
                     test.desc.name.as_slice().contains(&filter[..])
-                })
-                .collect()
-        }
+                }
+            })
+            .collect(),
     };
 
     // Skip tests that match any of the skip filters
     filtered = filtered
         .into_iter()
         .filter(|t| {
-            !opts.skip.iter().any(|sf| if opts.filter_exact {
-                t.desc.name.as_slice() == &sf[..]
-            } else {
-                t.desc.name.as_slice().contains(&sf[..])
+            !opts.skip.iter().any(|sf| {
+                if opts.filter_exact {
+                    t.desc.name.as_slice() == &sf[..]
+                } else {
+                    t.desc.name.as_slice().contains(&sf[..])
+                }
             })
         })
         .collect();
@@ -1354,31 +1341,23 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
     };
 
     // Sort the tests alphabetically
-    filtered.sort_by(|t1, t2| {
-        t1.desc.name.as_slice().cmp(t2.desc.name.as_slice())
-    });
+    filtered.sort_by(|t1, t2| t1.desc.name.as_slice().cmp(t2.desc.name.as_slice()));
 
     filtered
 }
 
 pub fn convert_benchmarks_to_tests(tests: Vec<TestDescAndFn>) -> Vec<TestDescAndFn> {
     // convert benchmarks to tests, if we're not benchmarking them
-    tests.into_iter().map(|x| {
-        let testfn = match x.testfn {
-            DynBenchFn(bench) => {
-                DynTestFn(Box::new(move || {
-                    bench::run_once(|b| {
-                        __rust_begin_short_backtrace(|| bench.run(b))
-                    })
-                }))
-            }
-            StaticBenchFn(benchfn) => {
-                DynTestFn(Box::new(move || {
-                    bench::run_once(|b| {
-                        __rust_begin_short_backtrace(|| benchfn(b))
-                    })
-                }))
-            }
+    tests
+        .into_iter()
+        .map(|x| {
+            let testfn = match x.testfn {
+                DynBenchFn(bench) => DynTestFn(Box::new(move || {
+                    bench::run_once(|b| __rust_begin_short_backtrace(|| bench.run(b)))
+                })),
+                StaticBenchFn(benchfn) => DynTestFn(Box::new(move || {
+                    bench::run_once(|b| __rust_begin_short_backtrace(|| benchfn(b)))
+                })),
                 f => f,
             };
             TestDescAndFn {
@@ -1395,22 +1374,22 @@ pub fn run_test(
     test: TestDescAndFn,
     monitor_ch: Sender<MonitorMsg>,
 ) {
-
     let TestDescAndFn { desc, testfn } = test;
 
-    let ignore_because_panic_abort = cfg!(target_arch = "wasm32") &&
-        !cfg!(target_os = "emscripten") &&
-        desc.should_panic != ShouldPanic::No;
+    let ignore_because_panic_abort = cfg!(target_arch = "wasm32") && !cfg!(target_os = "emscripten")
+        && desc.should_panic != ShouldPanic::No;
 
     if force_ignore || desc.ignore || ignore_because_panic_abort {
         monitor_ch.send((desc, TrIgnored, Vec::new())).unwrap();
         return;
     }
 
-    fn run_test_inner(desc: TestDesc,
-                      monitor_ch: Sender<MonitorMsg>,
-                      nocapture: bool,
-                      testfn: Box<FnBox() + Send>) {
+    fn run_test_inner(
+        desc: TestDesc,
+        monitor_ch: Sender<MonitorMsg>,
+        nocapture: bool,
+        testfn: Box<FnBox() + Send>,
+    ) {
         // Buffer for capturing standard I/O
         let data = Arc::new(Mutex::new(Vec::new()));
         let data2 = data.clone();
@@ -1440,7 +1419,6 @@ pub fn run_test(
                 .unwrap();
         };
 
-
         // If the platform is single-threaded we're just going to run
         // the test synchronously, regardless of the concurrency
         // level.
@@ -1455,27 +1433,25 @@ pub fn run_test(
 
     match testfn {
         DynBenchFn(bencher) => {
-            ::bench::benchmark(desc,
-                                monitor_ch,
-                                opts.nocapture,
-                                |harness| bencher.run(harness));
+            ::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| {
+                bencher.run(harness)
+            });
         }
         StaticBenchFn(benchfn) => {
-            ::bench::benchmark(desc,
-                                monitor_ch,
-                                opts.nocapture,
-                                |harness| (benchfn.clone())(harness));
+            ::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| {
+                (benchfn.clone())(harness)
+            });
         }
         DynTestFn(f) => {
-            let cb = move || {
-                __rust_begin_short_backtrace(f)
-            };
+            let cb = move || __rust_begin_short_backtrace(f);
             run_test_inner(desc, monitor_ch, opts.nocapture, Box::new(cb))
         }
-        StaticTestFn(f) => {
-            run_test_inner(desc, monitor_ch, opts.nocapture,
-                           Box::new(move || __rust_begin_short_backtrace(f)))
-        }
+        StaticTestFn(f) => run_test_inner(
+            desc,
+            monitor_ch,
+            opts.nocapture,
+            Box::new(move || __rust_begin_short_backtrace(f)),
+        ),
     }
 }
 
@@ -1487,8 +1463,7 @@ fn __rust_begin_short_backtrace<F: FnOnce()>(f: F) {
 
 fn calc_result(desc: &TestDesc, task_result: Result<(), Box<Any + Send>>) -> TestResult {
     match (&desc.should_panic, task_result) {
-        (&ShouldPanic::No, Ok(())) |
-        (&ShouldPanic::Yes, Err(_)) => TrOk,
+        (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TrOk,
         (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => {
             if err.downcast_ref::<String>()
                 .map(|e| &**e)
@@ -1545,7 +1520,6 @@ impl MetricMap {
     }
 }
 
-
 // Benchmarking
 
 /// A function that is opaque to the optimizer, to allow benchmarks to
@@ -1566,7 +1540,6 @@ pub fn black_box<T>(dummy: T) -> T {
     dummy
 }
 
-
 impl Bencher {
     /// Callback for benchmark functions to run in their body.
     pub fn iter<T, F>(&mut self, mut inner: F)
@@ -1605,7 +1578,6 @@ where
     return ns_from_dur(start.elapsed());
 }
 
-
 pub fn iter<T, F>(inner: &mut F) -> stats::Summary
 where
     F: FnMut() -> T,
@@ -1649,8 +1621,8 @@ where
 
         // If we've run for 100ms and seem to have converged to a
         // stable median.
-        if loop_run > Duration::from_millis(100) && summ.median_abs_dev_pct < 1.0 &&
-            summ.median - summ5.median < summ5.median_abs_dev
+        if loop_run > Duration::from_millis(100) && summ.median_abs_dev_pct < 1.0
+            && summ.median - summ5.median < summ5.median_abs_dev
         {
             return summ5;
         }
@@ -1680,7 +1652,7 @@ pub mod bench {
     use std::io;
     use std::sync::{Arc, Mutex};
     use stats;
-    use super::{Bencher, BenchSamples, BenchMode, Sink, MonitorMsg, TestDesc, Sender, TestResult};
+    use super::{BenchMode, BenchSamples, Bencher, MonitorMsg, Sender, Sink, TestDesc, TestResult};
 
     pub fn benchmark<F>(desc: TestDesc, monitor_ch: Sender<MonitorMsg>, nocapture: bool, f: F)
     where
@@ -1711,7 +1683,8 @@ pub mod bench {
             io::set_panic(panicio);
         };
 
-        let test_result = match result { //bs.bench(f) {
+        let test_result = match result {
+            //bs.bench(f) {
             Ok(Some(ns_iter_summ)) => {
                 let ns_iter = cmp::max(ns_iter_summ.median as u64, 1);
                 let mb_s = bs.bytes * 1000 / ns_iter;
@@ -1732,9 +1705,7 @@ pub mod bench {
                 };
                 TestResult::TrBench(bs)
             }
-            Err(_) => {
-                TestResult::TrFailed
-            }
+            Err(_) => TestResult::TrFailed,
         };
 
         let stdout = data.lock().unwrap().to_vec();
@@ -1756,9 +1727,9 @@ pub mod bench {
 
 #[cfg(test)]
 mod tests {
-    use test::{TrFailed, TrFailedMsg, TrIgnored, TrOk, filter_tests, parse_opts, TestDesc,
-               TestDescAndFn, TestOpts, run_test, MetricMap, StaticTestName, DynTestName,
-               DynTestFn, ShouldPanic};
+    use test::{filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, ShouldPanic,
+               StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg,
+               TrIgnored, TrOk};
     use std::sync::mpsc::channel;
     use bench;
     use Bencher;
@@ -1904,25 +1875,26 @@ mod tests {
         opts.run_tests = true;
         opts.run_ignored = true;
 
-        let tests =
-            vec![TestDescAndFn {
-                             desc: TestDesc {
-                                 name: StaticTestName("1"),
-                                 ignore: true,
-                                 should_panic: ShouldPanic::No,
-                                 allow_fail: false,
-                             },
-                             testfn: DynTestFn(Box::new(move || {})),
-                         },
-                         TestDescAndFn {
-                             desc: TestDesc {
-                                 name: StaticTestName("2"),
-                                 ignore: false,
-                                 should_panic: ShouldPanic::No,
-                                 allow_fail: false,
-                             },
-                             testfn: DynTestFn(Box::new(move || {})),
-                         }];
+        let tests = vec![
+            TestDescAndFn {
+                desc: TestDesc {
+                    name: StaticTestName("1"),
+                    ignore: true,
+                    should_panic: ShouldPanic::No,
+                    allow_fail: false,
+                },
+                testfn: DynTestFn(Box::new(move || {})),
+            },
+            TestDescAndFn {
+                desc: TestDesc {
+                    name: StaticTestName("2"),
+                    ignore: false,
+                    should_panic: ShouldPanic::No,
+                    allow_fail: false,
+                },
+                testfn: DynTestFn(Box::new(move || {})),
+            },
+        ];
         let filtered = filter_tests(&opts, tests);
 
         assert_eq!(filtered.len(), 1);
@@ -1935,17 +1907,16 @@ mod tests {
         fn tests() -> Vec<TestDescAndFn> {
             vec!["base", "base::test", "base::test1", "base::test2"]
                 .into_iter()
-                .map(|name| {
-                    TestDescAndFn {
-                        desc: TestDesc {
-                            name: StaticTestName(name),
-                            ignore: false,
-                            should_panic: ShouldPanic::No,
-                            allow_fail: false,
-                        },
-                        testfn: DynTestFn(Box::new(move || {}))
-                    }
-                }).collect()
+                .map(|name| TestDescAndFn {
+                    desc: TestDesc {
+                        name: StaticTestName(name),
+                        ignore: false,
+                        should_panic: ShouldPanic::No,
+                        allow_fail: false,
+                    },
+                    testfn: DynTestFn(Box::new(move || {})),
+                })
+                .collect()
         }
 
         let substr = filter_tests(
@@ -2127,10 +2098,7 @@ mod tests {
             allow_fail: false,
         };
 
-        ::bench::benchmark(desc,
-                            tx,
-                            true,
-                            f);
+        ::bench::benchmark(desc, tx, true, f);
         rx.recv().unwrap();
     }
 
@@ -2149,10 +2117,7 @@ mod tests {
             allow_fail: false,
         };
 
-        ::bench::benchmark(desc,
-                            tx,
-                            true,
-                            f);
+        ::bench::benchmark(desc, tx, true, f);
         rx.recv().unwrap();
     }
 }
diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs
index e22fdf77fc171..ddb5dcf2a1cd3 100644
--- a/src/libtest/stats.rs
+++ b/src/libtest/stats.rs
@@ -279,7 +279,6 @@ impl Stats for [f64] {
     }
 }
 
-
 // Helper function: extract a value representing the `pct` percentile of a sorted sample-set, using
 // linear interpolation. If samples are not sorted, return nonsensical value.
 fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 {
@@ -304,7 +303,6 @@ fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 {
     lo + (hi - lo) * d
 }
 
-
 /// Winsorize a set of samples, replacing values above the `100-pct` percentile
 /// and below the `pct` percentile with those percentiles themselves. This is a
 /// way of minimizing the effect of outliers, at the cost of biasing the sample.
@@ -338,15 +336,18 @@ mod tests {
     use std::io;
 
     macro_rules! assert_approx_eq {
-        ($a:expr, $b:expr) => ({
+        ($a: expr, $b: expr) => {{
             let (a, b) = (&$a, &$b);
-            assert!((*a - *b).abs() < 1.0e-6,
-                    "{} is not approximately equal to {}", *a, *b);
-        })
+            assert!(
+                (*a - *b).abs() < 1.0e-6,
+                "{} is not approximately equal to {}",
+                *a,
+                *b
+            );
+        }};
     }
 
     fn check(samples: &[f64], summ: &Summary) {
-
         let summ2 = Summary::new(samples);
 
         let mut w = io::sink();
@@ -911,14 +912,18 @@ mod bench {
 
     #[bench]
     pub fn sum_three_items(b: &mut Bencher) {
-        b.iter(|| { [1e20f64, 1.5f64, -1e20f64].sum(); })
+        b.iter(|| {
+            [1e20f64, 1.5f64, -1e20f64].sum();
+        })
     }
     #[bench]
     pub fn sum_many_f64(b: &mut Bencher) {
         let nums = [-1e30f64, 1e60, 1e30, 1.0, -1e60];
         let v = (0..500).map(|i| nums[i % 5]).collect::<Vec<_>>();
 
-        b.iter(|| { v.sum(); })
+        b.iter(|| {
+            v.sum();
+        })
     }
 
     #[bench]
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 06d1301d70003..3d5cce81278ac 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -44,6 +44,10 @@
 
 #include "llvm-c/Transforms/PassManagerBuilder.h"
 
+#if LLVM_VERSION_GE(4, 0)
+#define PGO_AVAILABLE
+#endif
+
 using namespace llvm;
 using namespace llvm::legacy;
 
@@ -428,12 +432,27 @@ extern "C" void LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
 
 extern "C" void LLVMRustConfigurePassManagerBuilder(
     LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
-    bool MergeFunctions, bool SLPVectorize, bool LoopVectorize) {
+    bool MergeFunctions, bool SLPVectorize, bool LoopVectorize,
+    const char* PGOGenPath, const char* PGOUsePath) {
   // Ignore mergefunc for now as enabling it causes crashes.
   // unwrap(PMBR)->MergeFunctions = MergeFunctions;
   unwrap(PMBR)->SLPVectorize = SLPVectorize;
   unwrap(PMBR)->OptLevel = fromRust(OptLevel);
   unwrap(PMBR)->LoopVectorize = LoopVectorize;
+
+#ifdef PGO_AVAILABLE
+  if (PGOGenPath) {
+    assert(!PGOUsePath);
+    unwrap(PMBR)->EnablePGOInstrGen = true;
+    unwrap(PMBR)->PGOInstrGen = PGOGenPath;
+  }
+  if (PGOUsePath) {
+    assert(!PGOGenPath);
+    unwrap(PMBR)->PGOInstrUse = PGOUsePath;
+  }
+#else
+  assert(!PGOGenPath && !PGOUsePath && "Should've caught earlier");
+#endif
 }
 
 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
@@ -766,6 +785,15 @@ LLVMRustThinLTOAvailable() {
 #endif
 }
 
+extern "C" bool
+LLVMRustPGOAvailable() {
+#ifdef PGO_AVAILABLE
+  return true;
+#else
+  return false;
+#endif
+}
+
 #if LLVM_VERSION_GE(4, 0)
 
 // Here you'll find an implementation of ThinLTO as used by the Rust compiler
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index a5644d6f9e2e1..df8602d0803a4 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -1021,6 +1021,7 @@ enum class LLVMRustDiagnosticKind {
   OptimizationRemarkAnalysisAliasing,
   OptimizationRemarkOther,
   OptimizationFailure,
+  PGOProfile,
 };
 
 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
@@ -1043,6 +1044,8 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
   case DK_OptimizationRemarkAnalysisAliasing:
     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
+  case DK_PGOProfile:
+    return LLVMRustDiagnosticKind::PGOProfile;
   default:
     return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
                ? LLVMRustDiagnosticKind::OptimizationRemarkOther
@@ -1492,3 +1495,31 @@ LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef, bool) {
   return nullptr;
 }
 #endif
+
+#if LLVM_VERSION_LT(4, 0)
+extern "C" LLVMValueRef
+LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS,
+                   LLVMValueRef RHS, const char *Name) {
+  return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name));
+}
+#endif
+
+#if LLVM_VERSION_GE(6, 0)
+extern "C" LLVMValueRef
+LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
+    return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
+}
+extern "C" LLVMValueRef
+LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
+    return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
+}
+#else
+extern "C" LLVMValueRef
+LLVMRustBuildMinNum(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) {
+   return nullptr;
+}
+extern "C" LLVMValueRef
+LLVMRustBuildMaxNum(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) {
+   return nullptr;
+}
+#endif
diff --git a/src/stage0.txt b/src/stage0.txt
index b9578386ce5bc..96ec1e6834dff 100644
--- a/src/stage0.txt
+++ b/src/stage0.txt
@@ -12,7 +12,7 @@
 # source tarball for a stable release you'll likely see `1.x.0` for rustc and
 # `0.x.0` for Cargo where they were released on `date`.
 
-date: 2018-02-20
+date: 2018-03-18
 rustc: beta
 cargo: beta
 
diff --git a/src/stdsimd b/src/stdsimd
index ab9356f2af650..bcb720e55861c 160000
--- a/src/stdsimd
+++ b/src/stdsimd
@@ -1 +1 @@
-Subproject commit ab9356f2af650815d339d77306f0d09c44d531ad
+Subproject commit bcb720e55861c38db47f2ebdf26b7198338cb39d
diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md
index c255294e790b7..8553665c01797 100644
--- a/src/test/COMPILER_TESTS.md
+++ b/src/test/COMPILER_TESTS.md
@@ -54,6 +54,8 @@ be compiled or run.
 * `ignore-test` always ignores the test
 * `ignore-lldb` and `ignore-gdb` will skip a debuginfo test on that debugger.
 
+`only-X` is the opposite. The test will run only when `X` matches.
+
 Some examples of `X` in `ignore-X`:
 
 * Architecture: `aarch64`, `arm`, `asmjs`, `mips`, `wasm32`, `x86_64`, `x86`, ...
diff --git a/src/test/codegen/abi-main-signature-16bit-c-int.rs b/src/test/codegen/abi-main-signature-16bit-c-int.rs
index 707531bf376a7..367d509cadfe3 100644
--- a/src/test/codegen/abi-main-signature-16bit-c-int.rs
+++ b/src/test/codegen/abi-main-signature-16bit-c-int.rs
@@ -19,6 +19,7 @@
 // ignore-mips
 // ignore-mips64
 // ignore-powerpc
+// ignore-powerpc64
 // ignore-s390x
 // ignore-sparc
 // ignore-wasm32
diff --git a/src/test/codegen/exact_div.rs b/src/test/codegen/exact_div.rs
new file mode 100644
index 0000000000000..9ba6c0c000637
--- /dev/null
+++ b/src/test/codegen/exact_div.rs
@@ -0,0 +1,30 @@
+// Copyright 2018 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.
+
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::exact_div;
+
+// CHECK-LABEL: @exact_sdiv
+#[no_mangle]
+pub unsafe fn exact_sdiv(x: i32, y: i32) -> i32 {
+// CHECK: sdiv exact
+    exact_div(x, y)
+}
+
+// CHECK-LABEL: @exact_udiv
+#[no_mangle]
+pub unsafe fn exact_udiv(x: u32, y: u32) -> u32 {
+// CHECK: udiv exact
+    exact_div(x, y)
+}
diff --git a/src/test/codegen/fastcall-inreg.rs b/src/test/codegen/fastcall-inreg.rs
index 9bfe47d0a1f28..d6dd3f356b5fe 100644
--- a/src/test/codegen/fastcall-inreg.rs
+++ b/src/test/codegen/fastcall-inreg.rs
@@ -23,6 +23,8 @@
 // ignore-mips
 // ignore-mips64
 // ignore-msp430
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-powerpc
 // ignore-r600
 // ignore-amdgcn
diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs
index 0e98d3f9050a8..de302c69056f6 100644
--- a/src/test/codegen/function-arguments.rs
+++ b/src/test/codegen/function-arguments.rs
@@ -133,6 +133,12 @@ pub fn trait_borrow(_: &Drop) {
 pub fn trait_box(_: Box<Drop>) {
 }
 
+// CHECK: { i8*, i8* } @trait_option(i8* noalias %x.0, i8* %x.1)
+#[no_mangle]
+pub fn trait_option(x: Option<Box<Drop>>) -> Option<Box<Drop>> {
+  x
+}
+
 // CHECK: { [0 x i16]*, [[USIZE]] } @return_slice([0 x i16]* noalias nonnull readonly %x.0, [[USIZE]] %x.1)
 #[no_mangle]
 pub fn return_slice(x: &[u16]) -> &[u16] {
diff --git a/src/test/codegen/global_asm.rs b/src/test/codegen/global_asm.rs
index 94b69a6cab583..6b79e79fa0080 100644
--- a/src/test/codegen/global_asm.rs
+++ b/src/test/codegen/global_asm.rs
@@ -19,6 +19,8 @@
 // ignore-mips
 // ignore-mips64
 // ignore-msp430
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-powerpc
 // ignore-r600
 // ignore-amdgcn
diff --git a/src/test/codegen/global_asm_include.rs b/src/test/codegen/global_asm_include.rs
index c3688077f221b..3f73a1cabbf19 100644
--- a/src/test/codegen/global_asm_include.rs
+++ b/src/test/codegen/global_asm_include.rs
@@ -19,6 +19,8 @@
 // ignore-mips
 // ignore-mips64
 // ignore-msp430
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-powerpc
 // ignore-r600
 // ignore-amdgcn
diff --git a/src/test/codegen/global_asm_x2.rs b/src/test/codegen/global_asm_x2.rs
index 3b8fe43fa048a..3e118a50d454e 100644
--- a/src/test/codegen/global_asm_x2.rs
+++ b/src/test/codegen/global_asm_x2.rs
@@ -19,6 +19,8 @@
 // ignore-mips
 // ignore-mips64
 // ignore-msp430
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-powerpc
 // ignore-r600
 // ignore-amdgcn
diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs
index 655e67cf7eefe..2eeed2b788ce2 100644
--- a/src/test/codegen/repr-transparent-aggregates-1.rs
+++ b/src/test/codegen/repr-transparent-aggregates-1.rs
@@ -14,6 +14,7 @@
 // ignore-mips
 // ignore-mips64
 // ignore-powerpc
+// ignore-powerpc64
 // See repr-transparent.rs
 
 #![crate_type="lib"]
diff --git a/src/test/codegen/simd-intrinsic-float-minmax.rs b/src/test/codegen/simd-intrinsic-float-minmax.rs
new file mode 100644
index 0000000000000..6663b841808f1
--- /dev/null
+++ b/src/test/codegen/simd-intrinsic-float-minmax.rs
@@ -0,0 +1,43 @@
+// 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.
+
+// ignore-emscripten
+// min-llvm-version 6.0
+
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+
+#![feature(repr_simd, platform_intrinsics)]
+#[allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+extern "platform-intrinsic" {
+    fn simd_fmin<T>(x: T, y: T) -> T;
+    fn simd_fmax<T>(x: T, y: T) -> T;
+}
+
+// CHECK-LABEL: @fmin
+#[no_mangle]
+pub unsafe fn fmin(a: f32x4, b: f32x4) -> f32x4 {
+    // CHECK: call <4 x float> @llvm.minnum.v4f32
+    simd_fmin(a, b)
+}
+
+// FIXME(49261)
+// // C_HECK-LABEL: @fmax
+// #[no_mangle]
+// pub unsafe fn fmax(a: f32x4, b: f32x4) -> f32x4 {
+// // C_HECK: call <4 x float> @llvm.maxnum.v4f32
+//     simd_fmax(a, b)
+// }
diff --git a/src/test/codegen/simd-intrinsic-generic-select.rs b/src/test/codegen/simd-intrinsic-generic-select.rs
new file mode 100644
index 0000000000000..8a64d7437d84d
--- /dev/null
+++ b/src/test/codegen/simd-intrinsic-generic-select.rs
@@ -0,0 +1,35 @@
+// 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.
+
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+
+#![feature(repr_simd, platform_intrinsics)]
+#[allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct b8x4(pub i8, pub i8, pub i8, pub i8);
+
+extern "platform-intrinsic" {
+    fn simd_select<T, U>(x: T, a: U, b: U) -> U;
+}
+
+// CHECK-LABEL: @select
+#[no_mangle]
+pub unsafe fn select(m: b8x4, a: f32x4, b: f32x4) -> f32x4 {
+    // CHECK: select <4 x i1>
+    simd_select(m, a, b)
+}
diff --git a/src/test/codegen/unchecked-float-casts.rs b/src/test/codegen/unchecked-float-casts.rs
index c2fc296617098..87ebaaeec320c 100644
--- a/src/test/codegen/unchecked-float-casts.rs
+++ b/src/test/codegen/unchecked-float-casts.rs
@@ -14,7 +14,6 @@
 // -Z saturating-float-casts is not enabled.
 
 #![crate_type = "lib"]
-#![feature(i128_type)]
 
 // CHECK-LABEL: @f32_to_u32
 #[no_mangle]
diff --git a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
index 1d08b80746582..fa475949b36b0 100644
--- a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
+++ b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
@@ -13,7 +13,6 @@
 //[mir]compile-flags: -Z borrowck=mir
 
 #![feature(slice_patterns)]
-#![feature(advanced_slice_patterns)]
 
 pub struct Foo {
   x: u32
diff --git a/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs b/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs
index 32a573911ecec..30047f84041f1 100644
--- a/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs
+++ b/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs
@@ -13,8 +13,6 @@
 
 // Test that immutable pattern bindings cannot be reassigned.
 
-#![feature(slice_patterns)]
-
 enum E {
     Foo(isize)
 }
diff --git a/src/test/compile-fail/borrowck/borrowck-move-out-from-array.rs b/src/test/compile-fail/borrowck/borrowck-move-out-from-array.rs
index e011617346232..0db31cef0ed77 100644
--- a/src/test/compile-fail/borrowck/borrowck-move-out-from-array.rs
+++ b/src/test/compile-fail/borrowck/borrowck-move-out-from-array.rs
@@ -11,7 +11,8 @@
 // revisions: ast mir
 //[mir]compile-flags: -Z borrowck=mir
 
-#![feature(box_syntax, slice_patterns, advanced_slice_patterns)]
+#![feature(box_syntax)]
+#![feature(slice_patterns)]
 
 fn move_out_from_begin_and_end() {
     let a = [box 1, box 2];
diff --git a/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs b/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs
index eb5d69d49bd6a..0fd6923326ab3 100644
--- a/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs
+++ b/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(advanced_slice_patterns)]
 #![feature(slice_patterns)]
 
 fn a<'a>() -> &'a [isize] {
diff --git a/src/test/compile-fail/conservative_impl_trait.rs b/src/test/compile-fail/conservative_impl_trait.rs
index 7fb0ec52f29f8..30895bce357bb 100644
--- a/src/test/compile-fail/conservative_impl_trait.rs
+++ b/src/test/compile-fail/conservative_impl_trait.rs
@@ -10,7 +10,6 @@
 
 // #39872, #39553
 
-#![feature(conservative_impl_trait)]
 fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
     //~^ ERROR the trait bound `(): std::iter::Iterator` is not satisfied [E0277]
 }
diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs b/src/test/compile-fail/edition-raw-pointer-method-2015.rs
similarity index 85%
rename from src/test/compile-fail/epoch-raw-pointer-method-2015.rs
rename to src/test/compile-fail/edition-raw-pointer-method-2015.rs
index 6aa83a38b7ee9..fdc9b4f704cd1 100644
--- a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs
+++ b/src/test/compile-fail/edition-raw-pointer-method-2015.rs
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// compile-flags: -Zepoch=2015 -Zunstable-options
+// compile-flags: -Zedition=2015 -Zunstable-options
 
-// tests that epochs work with the tyvar warning-turned-error
+// tests that editions work with the tyvar warning-turned-error
 
 #[deny(warnings)]
 fn main() {
diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs b/src/test/compile-fail/edition-raw-pointer-method-2018.rs
similarity index 85%
rename from src/test/compile-fail/epoch-raw-pointer-method-2018.rs
rename to src/test/compile-fail/edition-raw-pointer-method-2018.rs
index c4815de2306e9..58b34591029ba 100644
--- a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs
+++ b/src/test/compile-fail/edition-raw-pointer-method-2018.rs
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// compile-flags: -Zepoch=2018 -Zunstable-options
+// compile-flags: -Zedition=2018 -Zunstable-options
 
-// tests that epochs work with the tyvar warning-turned-error
+// tests that editions work with the tyvar warning-turned-error
 
 #[deny(warnings)]
 fn main() {
diff --git a/src/test/ui/feature-gate-universal.rs b/src/test/compile-fail/feature-gate-termination_trait_test.rs
similarity index 71%
rename from src/test/ui/feature-gate-universal.rs
rename to src/test/compile-fail/feature-gate-termination_trait_test.rs
index e5bdf3a42eb3e..4af7e94671627 100644
--- a/src/test/ui/feature-gate-universal.rs
+++ b/src/test/compile-fail/feature-gate-termination_trait_test.rs
@@ -8,9 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// gate-test-universal_impl_trait
-
-fn foo(x: impl std::fmt::Debug) { print!("{:?}", x); }
-//~^ ERROR `impl Trait` in argument position is experimental
+// compile-flags: --test
 
 fn main() {}
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn it_works() -> Result<(), ()> {
+    //~^ ERROR functions used as tests must have signature fn() -> ()
+        Ok(())
+    }
+}
diff --git a/src/test/compile-fail/impl-trait/impl-generic-mismatch-ab.rs b/src/test/compile-fail/impl-trait/impl-generic-mismatch-ab.rs
index 43b47e9e915f0..23549918ff1b3 100644
--- a/src/test/compile-fail/impl-trait/impl-generic-mismatch-ab.rs
+++ b/src/test/compile-fail/impl-trait/impl-generic-mismatch-ab.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
 use std::fmt::Debug;
 
 trait Foo {
diff --git a/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs b/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs
index a95da61aa4c00..eea7ca2095780 100644
--- a/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs
+++ b/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
 use std::fmt::Debug;
 
 trait Foo {
diff --git a/src/test/compile-fail/impl-trait/infinite-impl-trait-issue-38064.rs b/src/test/compile-fail/impl-trait/infinite-impl-trait-issue-38064.rs
index abde9689bd6b6..653ef1723e0b6 100644
--- a/src/test/compile-fail/impl-trait/infinite-impl-trait-issue-38064.rs
+++ b/src/test/compile-fail/impl-trait/infinite-impl-trait-issue-38064.rs
@@ -15,8 +15,6 @@
 
 // error-pattern:overflow evaluating the requirement `impl Quux`
 
-#![feature(conservative_impl_trait)]
-
 trait Quux {}
 
 fn foo() -> impl Quux {
diff --git a/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs
index 0eb99ca0fc3f1..537fc975bcf92 100644
--- a/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs
+++ b/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 use std::fmt::Debug;
 
 fn elided(x: &i32) -> impl Copy { x }
diff --git a/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs b/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs
index 2a06580fe605d..6c0a0b800ce33 100644
--- a/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs
+++ b/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 use std::fmt::Debug;
 
 trait MultiRegionTrait<'a, 'b> {}
diff --git a/src/test/compile-fail/impl-trait/no-trait.rs b/src/test/compile-fail/impl-trait/no-trait.rs
index ce61c5bf63d83..5299ba297d0a6 100644
--- a/src/test/compile-fail/impl-trait/no-trait.rs
+++ b/src/test/compile-fail/impl-trait/no-trait.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 fn f() -> impl 'static {} //~ ERROR at least one trait must be specified
 
 fn main() {}
diff --git a/src/test/compile-fail/impl-trait/type_parameters_captured.rs b/src/test/compile-fail/impl-trait/type_parameters_captured.rs
index c6ff762b9050a..7c3430ab90e52 100644
--- a/src/test/compile-fail/impl-trait/type_parameters_captured.rs
+++ b/src/test/compile-fail/impl-trait/type_parameters_captured.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 use std::fmt::Debug;
 
 trait Any {}
diff --git a/src/test/compile-fail/impl-trait/where-allowed.rs b/src/test/compile-fail/impl-trait/where-allowed.rs
index 52c5471681df3..038eacaf1103e 100644
--- a/src/test/compile-fail/impl-trait/where-allowed.rs
+++ b/src/test/compile-fail/impl-trait/where-allowed.rs
@@ -10,7 +10,7 @@
 
 //! A simple test for testing many permutations of allowedness of
 //! impl Trait
-#![feature(conservative_impl_trait, universal_impl_trait, dyn_trait)]
+#![feature(dyn_trait)]
 use std::fmt::Debug;
 
 // Allowed
diff --git a/src/test/compile-fail/issue-12369.rs b/src/test/compile-fail/issue-12369.rs
index 4df1e24dcfbd5..1b9af393ccce4 100644
--- a/src/test/compile-fail/issue-12369.rs
+++ b/src/test/compile-fail/issue-12369.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![feature(slice_patterns)]
-#![allow(unused_variables)]
 #![deny(unreachable_patterns)]
 
 fn main() {
diff --git a/src/test/compile-fail/issue-13482-2.rs b/src/test/compile-fail/issue-13482-2.rs
index 6885c8d94c6b4..fe7fbb176cc5e 100644
--- a/src/test/compile-fail/issue-13482-2.rs
+++ b/src/test/compile-fail/issue-13482-2.rs
@@ -10,8 +10,6 @@
 
 // compile-flags:-Z verbose
 
-#![feature(slice_patterns)]
-
 fn main() {
     let x = [1,2];
     let y = match x {
diff --git a/src/test/compile-fail/issue-13482.rs b/src/test/compile-fail/issue-13482.rs
index 82e82df31861f..32a63b79a32dd 100644
--- a/src/test/compile-fail/issue-13482.rs
+++ b/src/test/compile-fail/issue-13482.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns)]
-
 fn main() {
   let x = [1,2];
   let y = match x {
diff --git a/src/test/compile-fail/issue-15381.rs b/src/test/compile-fail/issue-15381.rs
index d0964d2aabea7..1cdd803971b4b 100644
--- a/src/test/compile-fail/issue-15381.rs
+++ b/src/test/compile-fail/issue-15381.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns)]
-
 fn main() {
     let values: Vec<u8> = vec![1,2,3,4,5,6,7,8];
 
diff --git a/src/test/compile-fail/issue-16338.rs b/src/test/compile-fail/issue-16338.rs
index 6fdf8802e385e..438073e3b2f82 100644
--- a/src/test/compile-fail/issue-16338.rs
+++ b/src/test/compile-fail/issue-16338.rs
@@ -17,5 +17,4 @@ fn main() {
     let Slice { data: data, len: len } = "foo";
     //~^ ERROR mismatched types
     //~| found type `Slice<_>`
-    //~| ERROR non-reference pattern used to match a reference
 }
diff --git a/src/test/compile-fail/issue-17994.rs b/src/test/compile-fail/issue-17994.rs
index 0f30e2461cf3b..25141b9b82557 100644
--- a/src/test/compile-fail/issue-17994.rs
+++ b/src/test/compile-fail/issue-17994.rs
@@ -10,5 +10,4 @@
 
 trait Tr {}
 type Huh<T> where T: Tr = isize; //~  ERROR type parameter `T` is unused
-                                 //~| WARNING where clauses are ignored in type aliases
 fn main() {}
diff --git a/src/test/compile-fail/issue-20261.rs b/src/test/compile-fail/issue-20261.rs
index 092aaa7695505..bb4dbdcd0cba7 100644
--- a/src/test/compile-fail/issue-20261.rs
+++ b/src/test/compile-fail/issue-20261.rs
@@ -11,7 +11,7 @@
 fn main() {
     // NB: this (almost) typechecks when default binding modes are enabled.
     for (ref i,) in [].iter() {
-        //~^ ERROR non-reference pattern used to match a reference
         i.clone();
+        //~^ ERROR type annotations needed
     }
 }
diff --git a/src/test/compile-fail/issue-32995-2.rs b/src/test/compile-fail/issue-32995-2.rs
index 0e917ad95d95b..18424fcc9e0af 100644
--- a/src/test/compile-fail/issue-32995-2.rs
+++ b/src/test/compile-fail/issue-32995-2.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
 #![allow(unused)]
 
 fn main() {
diff --git a/src/test/compile-fail/issue-35668.rs b/src/test/compile-fail/issue-35668.rs
index c9323db054c86..17fd77b6df3a2 100644
--- a/src/test/compile-fail/issue-35668.rs
+++ b/src/test/compile-fail/issue-35668.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 fn func<'a, T>(a: &'a [T]) -> impl Iterator<Item=&'a T> {
     a.iter().map(|a| a*a)
     //~^ ERROR binary operation `*` cannot be applied to type `&T`
diff --git a/src/test/compile-fail/issue-36379.rs b/src/test/compile-fail/issue-36379.rs
index 2f513b034c36d..b20765815e0b2 100644
--- a/src/test/compile-fail/issue-36379.rs
+++ b/src/test/compile-fail/issue-36379.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait, rustc_attrs)]
+#![feature(rustc_attrs)]
 
 fn _test() -> impl Default { }
 
diff --git a/src/test/compile-fail/issue-41255.rs b/src/test/compile-fail/issue-41255.rs
index ac85e43cf4f05..bdd502d442036 100644
--- a/src/test/compile-fail/issue-41255.rs
+++ b/src/test/compile-fail/issue-41255.rs
@@ -10,7 +10,6 @@
 
 // Matching against float literals should result in a linter error
 
-#![feature(slice_patterns)]
 #![feature(exclusive_range_pattern)]
 #![allow(unused)]
 #![forbid(illegal_floating_point_literal_pattern)]
diff --git a/src/test/compile-fail/issue-6804.rs b/src/test/compile-fail/issue-6804.rs
index 9191dfa155c65..fffa27ab842ad 100644
--- a/src/test/compile-fail/issue-6804.rs
+++ b/src/test/compile-fail/issue-6804.rs
@@ -10,7 +10,6 @@
 
 // Matching against NaN should result in a warning
 
-#![feature(slice_patterns)]
 #![allow(unused)]
 #![deny(illegal_floating_point_literal_pattern)]
 
diff --git a/src/test/compile-fail/lint-unnecessary-import-braces.rs b/src/test/compile-fail/lint-unnecessary-import-braces.rs
index 1c0401ec56b85..214a03c13f4e5 100644
--- a/src/test/compile-fail/lint-unnecessary-import-braces.rs
+++ b/src/test/compile-fail/lint-unnecessary-import-braces.rs
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 #![deny(unused_import_braces)]
-#![allow(dead_code)]
-#![allow(unused_imports)]
 
 use test::{A}; //~ ERROR braces around A is unnecessary
 
 mod test {
+    use test::{self}; // OK
+    use test::{self as rename}; // OK
     pub struct A;
 }
 
diff --git a/src/test/compile-fail/match-byte-array-patterns-2.rs b/src/test/compile-fail/match-byte-array-patterns-2.rs
index ad7e931a0ec97..abb770df107f1 100644
--- a/src/test/compile-fail/match-byte-array-patterns-2.rs
+++ b/src/test/compile-fail/match-byte-array-patterns-2.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(advanced_slice_patterns, slice_patterns)]
-
 fn main() {
     let buf = &[0, 1, 2, 3];
 
diff --git a/src/test/compile-fail/match-byte-array-patterns.rs b/src/test/compile-fail/match-byte-array-patterns.rs
index 1ff07eae1c9c0..9db4319b78682 100644
--- a/src/test/compile-fail/match-byte-array-patterns.rs
+++ b/src/test/compile-fail/match-byte-array-patterns.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(advanced_slice_patterns, slice_patterns)]
+#![feature(slice_patterns)]
 #![deny(unreachable_patterns)]
 
 fn main() {
diff --git a/src/test/compile-fail/match-range-fail.rs b/src/test/compile-fail/match-range-fail.rs
index 355ff6404cea7..f89b3e39390d3 100644
--- a/src/test/compile-fail/match-range-fail.rs
+++ b/src/test/compile-fail/match-range-fail.rs
@@ -15,7 +15,6 @@ fn main() {
     //~^^ ERROR only char and numeric types are allowed in range
     //~| start type: &'static str
     //~| end type: &'static str
-    //~| ERROR non-reference pattern used to match a reference
 
     match "wow" {
         10 ... "what" => ()
@@ -23,7 +22,6 @@ fn main() {
     //~^^ ERROR only char and numeric types are allowed in range
     //~| start type: {integer}
     //~| end type: &'static str
-    //~| ERROR non-reference pattern used to match a reference
 
     match 5 {
         'c' ... 100 => { }
diff --git a/src/test/compile-fail/match-ref-ice.rs b/src/test/compile-fail/match-ref-ice.rs
index 1cdbba17f658a..cb8f8fad532fa 100644
--- a/src/test/compile-fail/match-ref-ice.rs
+++ b/src/test/compile-fail/match-ref-ice.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns)]
 #![deny(unreachable_patterns)]
 
 // The arity of `ref x` is always 1. If the pattern is compared to some non-structural type whose
diff --git a/src/test/compile-fail/match-slice-patterns.rs b/src/test/compile-fail/match-slice-patterns.rs
index fd4bd1c7b944b..a8ec95da3d872 100644
--- a/src/test/compile-fail/match-slice-patterns.rs
+++ b/src/test/compile-fail/match-slice-patterns.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(advanced_slice_patterns, slice_patterns)]
+#![feature(slice_patterns)]
 
 fn check(list: &[Option<()>]) {
     match list {
diff --git a/src/test/compile-fail/match-vec-fixed.rs b/src/test/compile-fail/match-vec-fixed.rs
index dd9379c756d12..05971d70167bd 100644
--- a/src/test/compile-fail/match-vec-fixed.rs
+++ b/src/test/compile-fail/match-vec-fixed.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns)]
 #![deny(unreachable_patterns)]
 
 fn a() {
diff --git a/src/test/compile-fail/match-vec-mismatch-2.rs b/src/test/compile-fail/match-vec-mismatch-2.rs
index 375d855d1fd31..52c5375f4e7d1 100644
--- a/src/test/compile-fail/match-vec-mismatch-2.rs
+++ b/src/test/compile-fail/match-vec-mismatch-2.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns)]
-
 fn main() {
     match () {
         [()] => { }
diff --git a/src/test/compile-fail/match-vec-mismatch.rs b/src/test/compile-fail/match-vec-mismatch.rs
index 998c11979953c..d737aa0029bf8 100644
--- a/src/test/compile-fail/match-vec-mismatch.rs
+++ b/src/test/compile-fail/match-vec-mismatch.rs
@@ -19,7 +19,7 @@ fn main() {
 
     // Note that this one works with default binding modes.
     match &[0, 1, 2] {
-        [..] => {} //~ ERROR non-reference pattern used to match a reference
+        [..] => {}
     };
 
     match &[0, 1, 2] {
diff --git a/src/test/compile-fail/match-vec-unreachable.rs b/src/test/compile-fail/match-vec-unreachable.rs
index 472b054b08777..d6e3fdbe08844 100644
--- a/src/test/compile-fail/match-vec-unreachable.rs
+++ b/src/test/compile-fail/match-vec-unreachable.rs
@@ -10,7 +10,6 @@
 
 #![feature(slice_patterns)]
 #![deny(unreachable_patterns)]
-#![allow(unused_variables)]
 
 fn main() {
     let x: Vec<(isize, isize)> = Vec::new();
diff --git a/src/test/compile-fail/move-out-of-slice-1.rs b/src/test/compile-fail/move-out-of-slice-1.rs
index 9ca9e0984e476..5efbef549ddca 100644
--- a/src/test/compile-fail/move-out-of-slice-1.rs
+++ b/src/test/compile-fail/move-out-of-slice-1.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns, box_patterns)]
+#![feature(box_patterns)]
 
 struct A;
 
diff --git a/src/test/compile-fail/not-clone-closure.rs b/src/test/compile-fail/not-clone-closure.rs
index 2a30dc4fdd49c..967cb3610ca5f 100644
--- a/src/test/compile-fail/not-clone-closure.rs
+++ b/src/test/compile-fail/not-clone-closure.rs
@@ -10,8 +10,6 @@
 
 // Check that closures do not implement `Clone` if their environment is not `Clone`.
 
-#![feature(clone_closures)]
-
 struct S(i32);
 
 fn main() {
diff --git a/src/test/compile-fail/not-copy-closure.rs b/src/test/compile-fail/not-copy-closure.rs
index 271e6d5fc90fc..10567c5c961a2 100644
--- a/src/test/compile-fail/not-copy-closure.rs
+++ b/src/test/compile-fail/not-copy-closure.rs
@@ -10,9 +10,6 @@
 
 // Check that closures do not implement `Copy` if their environment is not `Copy`.
 
-#![feature(copy_closures)]
-#![feature(clone_closures)]
-
 fn main() {
     let mut a = 5;
     let hello = || {
diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs
index cc9eed7e65426..6eeb14638e759 100644
--- a/src/test/compile-fail/private-in-public-warn.rs
+++ b/src/test/compile-fail/private-in-public-warn.rs
@@ -58,7 +58,6 @@ mod traits {
     pub trait PubTr {}
 
     pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface
-    //~^ WARNING bounds on generic parameters are ignored
     //~| WARNING hard error
     pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface
     //~^ WARNING hard error
@@ -85,7 +84,6 @@ mod traits_where {
     pub type Alias<T> where T: PrivTr = T;
         //~^ ERROR private trait `traits_where::PrivTr` in public interface
         //~| WARNING hard error
-        //~| WARNING where clauses are ignored in type aliases
     pub trait Tr2<T> where T: PrivTr {}
         //~^ ERROR private trait `traits_where::PrivTr` in public interface
         //~| WARNING hard error
diff --git a/src/test/compile-fail/private-inferred-type.rs b/src/test/compile-fail/private-inferred-type.rs
index 351dc6b776b21..5af8b063c1629 100644
--- a/src/test/compile-fail/private-inferred-type.rs
+++ b/src/test/compile-fail/private-inferred-type.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![feature(associated_consts)]
-#![feature(conservative_impl_trait)]
 #![feature(decl_macro)]
 #![allow(private_in_public)]
 
diff --git a/src/test/compile-fail/private-type-in-interface.rs b/src/test/compile-fail/private-type-in-interface.rs
index eb8c40a7dd5e8..1842790a1405f 100644
--- a/src/test/compile-fail/private-type-in-interface.rs
+++ b/src/test/compile-fail/private-type-in-interface.rs
@@ -10,7 +10,6 @@
 
 // aux-build:private-inferred-type.rs
 
-#![feature(conservative_impl_trait)]
 #![allow(warnings)]
 
 extern crate private_inferred_type as ext;
diff --git a/src/test/compile-fail/regions-pattern-typing-issue-19552.rs b/src/test/compile-fail/regions-pattern-typing-issue-19552.rs
index 8e83177090bb5..3401dd1becdd8 100644
--- a/src/test/compile-fail/regions-pattern-typing-issue-19552.rs
+++ b/src/test/compile-fail/regions-pattern-typing-issue-19552.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns)]
-
 fn assert_static<T: 'static>(_t: T) {}
 
 fn main() {
diff --git a/src/test/ui/feature-gate-match_default_bindings.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs
similarity index 70%
rename from src/test/ui/feature-gate-match_default_bindings.rs
rename to src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs
index 4ee2c1e2936a8..49f5621de1b29 100644
--- a/src/test/ui/feature-gate-match_default_bindings.rs
+++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs
@@ -8,10 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn main() {
-    match &Some(3) {
-        Some(n) => {},
-        //~^ ERROR non-reference pattern used to match a reference
-        _ => panic!(),
-    }
+fn main() -> i32 {
+//~^ ERROR `main` has invalid return type `i32`
+//~| NOTE `main` can only return types that implement `std::process::Termination`
+//~| HELP consider using `()`, or a `Result`
+    0
 }
diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs
index e87e0ceebf1b1..b5f5472b49290 100644
--- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs
+++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs
@@ -8,10 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(termination_trait)]
-
 struct ReturnType {}
 
-fn main() -> ReturnType { //~ ERROR `ReturnType: std::process::Termination` is not satisfied
+fn main() -> ReturnType { //~ ERROR `main` has invalid return type `ReturnType`
     ReturnType {}
 }
diff --git a/src/test/compile-fail/simd-intrinsic-generic-select.rs b/src/test/compile-fail/simd-intrinsic-generic-select.rs
new file mode 100644
index 0000000000000..d74d6815d5f5e
--- /dev/null
+++ b/src/test/compile-fail/simd-intrinsic-generic-select.rs
@@ -0,0 +1,56 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the simd_select intrinsic produces ok-ish error
+// messages when misused.
+
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq)]
+struct b8x4(pub i8, pub i8, pub i8, pub i8);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq)]
+struct b8x8(pub i8, pub i8, pub i8, pub i8,
+            pub i8, pub i8, pub i8, pub i8);
+
+extern "platform-intrinsic" {
+    fn simd_select<T, U>(x: T, a: U, b: U) -> U;
+}
+
+fn main() {
+    let m4 = b8x4(0, 0, 0, 0);
+    let m8 = b8x8(0, 0, 0, 0, 0, 0, 0, 0);
+    let x = u32x4(0, 0, 0, 0);
+    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+
+    unsafe {
+        simd_select(m4, x, x);
+
+        simd_select(m8, x, x);
+        //~^ ERROR mismatched lengths: mask length `8` != other vector length `4`
+
+        simd_select(x, x, x);
+        //~^ ERROR mask element type is `u32`, expected `i_`
+
+        simd_select(z, z, z);
+        //~^ ERROR mask element type is `f32`, expected `i_`
+    }
+}
diff --git a/src/test/compile-fail/struct-pat-derived-error.rs b/src/test/compile-fail/struct-pat-derived-error.rs
index f525ec373753d..d3130c4e831f6 100644
--- a/src/test/compile-fail/struct-pat-derived-error.rs
+++ b/src/test/compile-fail/struct-pat-derived-error.rs
@@ -16,10 +16,8 @@ struct a {
 impl a {
     fn foo(&self) {
         let a { x, y } = self.d; //~ ERROR no field `d` on type `&a`
-        //~^ ERROR struct `a` does not have a field named `x`
-        //~^^ ERROR struct `a` does not have a field named `y`
-        //~^^^ ERROR pattern does not mention field `b`
-        //~^^^^ ERROR pattern does not mention field `c`
+        //~^ ERROR struct `a` does not have fields named `x`, `y`
+        //~| ERROR pattern does not mention fields `b`, `c`
     }
 }
 
diff --git a/src/test/compile-fail/uninhabited-matches-feature-gated.rs b/src/test/compile-fail/uninhabited-matches-feature-gated.rs
index 0c3ea53a903ae..1d3f8ff12d865 100644
--- a/src/test/compile-fail/uninhabited-matches-feature-gated.rs
+++ b/src/test/compile-fail/uninhabited-matches-feature-gated.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns)]
-
 enum Void {}
 
 fn main() {
diff --git a/src/test/compile-fail/uninhabited-patterns.rs b/src/test/compile-fail/uninhabited-patterns.rs
index 9f943f08232d6..e130df5c845b5 100644
--- a/src/test/compile-fail/uninhabited-patterns.rs
+++ b/src/test/compile-fail/uninhabited-patterns.rs
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 #![feature(box_patterns)]
-#![feature(slice_patterns)]
 #![feature(box_syntax)]
 #![feature(exhaustive_patterns)]
+#![feature(slice_patterns)]
 #![deny(unreachable_patterns)]
 
 mod foo {
diff --git a/src/test/incremental/extern_static/issue-49153.rs b/src/test/incremental/extern_static/issue-49153.rs
new file mode 100644
index 0000000000000..e0538e09c6470
--- /dev/null
+++ b/src/test/incremental/extern_static/issue-49153.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+// https://github.com/rust-lang/rust/issues/49153
+
+// revisions:rpass1 rpass2
+
+extern "C" {
+    pub static __ImageBase: u8;
+}
+
+pub static FOO: &'static u8 = unsafe { &__ImageBase };
+
+fn main() {}
diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs
index abe0586efcd7f..6c4e11be1e43e 100644
--- a/src/test/incremental/hashes/function_interfaces.rs
+++ b/src/test/incremental/hashes/function_interfaces.rs
@@ -22,7 +22,6 @@
 
 
 #![allow(warnings)]
-#![feature(conservative_impl_trait)]
 #![feature(intrinsics)]
 #![feature(linkage)]
 #![feature(rustc_attrs)]
diff --git a/src/test/incremental/hashes/let_expressions.rs b/src/test/incremental/hashes/let_expressions.rs
index 851b13c705516..2f49500c3910b 100644
--- a/src/test/incremental/hashes/let_expressions.rs
+++ b/src/test/incremental/hashes/let_expressions.rs
@@ -49,7 +49,7 @@ pub fn add_type() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,TypeckTables")]
+    except="HirBody,TypeckTables,MirValidated")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_type() {
     let _x: u32 = 2u32;
diff --git a/src/test/ui/pat-slice-old-style.rs b/src/test/incremental/issue-49043.rs
similarity index 52%
rename from src/test/ui/pat-slice-old-style.rs
rename to src/test/incremental/issue-49043.rs
index 4ff1e94b08721..118027b190e29 100644
--- a/src/test/ui/pat-slice-old-style.rs
+++ b/src/test/incremental/issue-49043.rs
@@ -8,20 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns)]
+// Regression test for hashing involving canonical variables.  In this
+// test -- which has an intensional error -- the type of the value
+// being dropped winds up including a type variable. Canonicalization
+// would then produce a `?0` which -- in turn -- triggered an ICE in
+// hashing.
 
-// NB: this test was introduced in #23121 and will have to change when default match binding modes
-// stabilizes.
-
-fn slice_pat(x: &[u8]) {
-    // OLD!
-    match x {
-        [a, b..] => {},
-        //~^ ERROR non-reference pattern used to match a reference
-        _ => panic!(),
-    }
-}
+// revisions:cfail1
 
 fn main() {
-    slice_pat("foo".as_bytes());
+    println!("Hello, world! {}",*thread_rng().choose(&[0, 1, 2, 3]).unwrap());
+    //[cfail1]~^ ERROR cannot find function `thread_rng`
 }
diff --git a/src/test/ui/feature-gate-i128_type.rs b/src/test/incremental/static_refering_to_other_static/issue-49081.rs
similarity index 66%
rename from src/test/ui/feature-gate-i128_type.rs
rename to src/test/incremental/static_refering_to_other_static/issue-49081.rs
index ddb49a3e5d92a..6345b456523ed 100644
--- a/src/test/ui/feature-gate-i128_type.rs
+++ b/src/test/incremental/static_refering_to_other_static/issue-49081.rs
@@ -1,4 +1,4 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn test2() {
-    0i128; //~ ERROR 128-bit integers are not stable
-}
+// https://github.com/rust-lang/rust/issues/49081
 
-fn test2_2() {
-    0u128; //~ ERROR 128-bit integers are not stable
-}
+// revisions:rpass1 rpass2
 
+pub static A: i32 = 42;
+pub static B: &i32 = &A;
+
+fn main() {}
diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs
index 321c05c490356..3c236ddcf0409 100644
--- a/src/test/mir-opt/basic_assignment.rs
+++ b/src/test/mir-opt/basic_assignment.rs
@@ -23,6 +23,8 @@
 // tend to be absent in simple code, so subtle breakage in them can
 // leave a quite hard-to-find trail of destruction.
 
+// ignore-tidy-linelength
+
 fn main() {
     let nodrop_x = false;
     let nodrop_y;
@@ -46,6 +48,7 @@ fn main() {
 //         _2 = move _3;
 //         StorageDead(_3);
 //         StorageLive(_4);
+//         UserAssertTy(Canonical { variables: Slice([]), value: std::option::Option<std::boxed::Box<u32>> }, _4);
 //         _4 = std::option::Option<std::boxed::Box<u32>>::None;
 //         StorageLive(_5);
 //         StorageLive(_6);
diff --git a/src/test/mir-opt/end_region_8.rs b/src/test/mir-opt/end_region_8.rs
index 405864aba9436..d621cdb4d58f8 100644
--- a/src/test/mir-opt/end_region_8.rs
+++ b/src/test/mir-opt/end_region_8.rs
@@ -36,7 +36,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 //    let _2: &'21_1rs D;
 //    ...
 //    let mut _3: ();
-//    let mut _4: [closure@NodeId(22) r:&'21_1rs D];
+//    let mut _4: [closure@NodeId(22) r:&'19s D];
 //    let mut _5: &'21_1rs D;
 //    bb0: {
 //        StorageLive(_1);
@@ -54,6 +54,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 //        resume;
 //    }
 //    bb2: {
+//        EndRegion('19s);
 //        StorageDead(_4);
 //        _0 = ();
 //        EndRegion('21_1rs);
@@ -61,6 +62,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 //        drop(_1) -> [return: bb4, unwind: bb1];
 //    }
 //    bb3: {
+//        EndRegion('19s);
 //        EndRegion('21_1rs);
 //        drop(_1) -> bb1;
 //    }
@@ -72,7 +74,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 // END rustc.main.SimplifyCfg-qualify-consts.after.mir
 
 // START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir
-// fn main::{{closure}}(_1: [closure@NodeId(22) r:&'21_1rs D]) -> i32 {
+// fn main::{{closure}}(_1: [closure@NodeId(22) r:&'19s D]) -> i32 {
 //     let mut _0: i32;
 //     let mut _2: i32;
 //
diff --git a/src/test/mir-opt/lower_128bit_debug_test.rs b/src/test/mir-opt/lower_128bit_debug_test.rs
index 1752445a141c3..d7586b1aa4b10 100644
--- a/src/test/mir-opt/lower_128bit_debug_test.rs
+++ b/src/test/mir-opt/lower_128bit_debug_test.rs
@@ -15,7 +15,6 @@
 
 // compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=yes
 
-#![feature(i128_type)]
 #![feature(const_fn)]
 
 static TEST_SIGNED: i128 = const_signed(-222);
diff --git a/src/test/mir-opt/lower_128bit_test.rs b/src/test/mir-opt/lower_128bit_test.rs
index 4058eaef9b0a4..341682debeb35 100644
--- a/src/test/mir-opt/lower_128bit_test.rs
+++ b/src/test/mir-opt/lower_128bit_test.rs
@@ -15,7 +15,6 @@
 
 // compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=no
 
-#![feature(i128_type)]
 #![feature(const_fn)]
 
 static TEST_SIGNED: i128 = const_signed(-222);
diff --git a/src/test/mir-opt/nll/reborrow-basic.rs b/src/test/mir-opt/nll/reborrow-basic.rs
index f69c51c3562dc..92e42a73bbb6a 100644
--- a/src/test/mir-opt/nll/reborrow-basic.rs
+++ b/src/test/mir-opt/nll/reborrow-basic.rs
@@ -28,9 +28,9 @@ fn main() {
 
 // END RUST SOURCE
 // START rustc.main.nll.0.mir
-// | '_#7r    | {bb0[6..=14]}
+// | '_#7r    | {bb0[4], bb0[8..=17]}
 // ...
-// | '_#9r    | {bb0[11..=14]}
+// | '_#9r    | {bb0[10], bb0[14..=17]}
 // ...
 // let _2: &'_#7r mut i32;
 // ...
diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs
index 482b69a59ddbc..fa5f62f89f63c 100644
--- a/src/test/mir-opt/uniform_array_move_out.rs
+++ b/src/test/mir-opt/uniform_array_move_out.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax, slice_patterns, advanced_slice_patterns)]
+#![feature(box_syntax)]
+#![feature(slice_patterns)]
 
 fn move_out_from_end() {
     let a = [box 1, box 2];
diff --git a/src/test/parse-fail/issue-32501.rs b/src/test/parse-fail/issue-32501.rs
index f29c1fa279400..21db2f5051703 100644
--- a/src/test/parse-fail/issue-32501.rs
+++ b/src/test/parse-fail/issue-32501.rs
@@ -16,7 +16,5 @@ fn main() {
     let _ = 0;
     let mut b = 0;
     let mut _b = 0;
-    let mut _ = 0; //~ ERROR expected identifier, found `_`
-    //~^ NOTE `_` is a wildcard pattern, not an identifier
-    //~| NOTE expected identifier
+    let mut _ = 0; //~ ERROR expected identifier, found reserved identifier `_`
 }
diff --git a/src/test/parse-fail/raw-str-delim.rs b/src/test/parse-fail/raw-str-delim.rs
index 3fc5f8aae1876..8c0027287dece 100644
--- a/src/test/parse-fail/raw-str-delim.rs
+++ b/src/test/parse-fail/raw-str-delim.rs
@@ -11,5 +11,5 @@
 // compile-flags: -Z parse-only
 
 static s: &'static str =
-    r#x"#"x# //~ ERROR found invalid character; only `#` is allowed in raw string delimitation
+    r#~"#"~# //~ ERROR found invalid character; only `#` is allowed in raw string delimitation
 ;
diff --git a/src/test/parse-fail/recover-enum2.rs b/src/test/parse-fail/recover-enum2.rs
index 49380a03e156a..6fd32f842f135 100644
--- a/src/test/parse-fail/recover-enum2.rs
+++ b/src/test/parse-fail/recover-enum2.rs
@@ -39,5 +39,5 @@ fn main() {
         }
     }
     // still recover later
-    let bad_syntax = _; //~ ERROR: found `_`
+    let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_`
 }
diff --git a/src/test/parse-fail/underscore-suffix-for-float.rs b/src/test/parse-fail/underscore-suffix-for-float.rs
index df7d9aa374dce..8327217e6f286 100644
--- a/src/test/parse-fail/underscore-suffix-for-float.rs
+++ b/src/test/parse-fail/underscore-suffix-for-float.rs
@@ -9,5 +9,6 @@
 // except according to those terms.
 
 fn main() {
-    let a = 42._; //~ ERROR unexpected token: `_`
+    let a = 42._; //~ ERROR expected identifier, found reserved identifier `_`
+                  //~^ ERROR `{integer}` is a primitive type and therefore doesn't have fields
 }
diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs
index c1dd44a91765e..863de85af88fb 100644
--- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs
+++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(termination_trait)]
-
 // error-pattern:oh, dear
 
 fn main() -> ! {
diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs
index 8ce27c0a06250..0c6cb4de9567d 100644
--- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs
+++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs
@@ -11,8 +11,6 @@
 // must-compile-successfully
 // failure-status: 1
 
-#![feature(termination_trait)]
-
 use std::io::{Error, ErrorKind};
 
 fn main() -> Result<(), Box<Error>> {
diff --git a/src/test/run-fail/simd-intrinsic-float-minmax.rs b/src/test/run-fail/simd-intrinsic-float-minmax.rs
new file mode 100644
index 0000000000000..f4fb8e12250b5
--- /dev/null
+++ b/src/test/run-fail/simd-intrinsic-float-minmax.rs
@@ -0,0 +1,57 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-emscripten
+// min-llvm-version 6.0
+// error-pattern: panicked
+
+// Test that the simd_f{min,max} intrinsics produce the correct results.
+
+#![feature(repr_simd, platform_intrinsics)]
+#[allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+extern "platform-intrinsic" {
+    fn simd_fmin<T>(x: T, y: T) -> T;
+    fn simd_fmax<T>(x: T, y: T) -> T;
+}
+
+fn main() {
+    let x = f32x4(1.0, 2.0, 3.0, 4.0);
+    let y = f32x4(2.0, 1.0, 4.0, 3.0);
+    let nan = ::std::f32::NAN;
+    let n = f32x4(nan, nan, nan, nan);
+
+    unsafe {
+        let min0 = simd_fmin(x, y);
+        let min1 = simd_fmin(y, x);
+        assert_eq!(min0, min1);
+        let e = f32x4(1.0, 1.0, 3.0, 3.0);
+        assert_eq!(min0, e);
+        let minn = simd_fmin(x, n);
+        assert_eq!(minn, x);
+        let minn = simd_fmin(y, n);
+        assert_eq!(minn, y);
+
+        // FIXME(49261)
+        let max0 = simd_fmax(x, y);
+        let max1 = simd_fmax(y, x);
+        assert_eq!(max0, max1);
+        let e = f32x4(2.0, 2.0, 4.0, 4.0);
+        assert_eq!(max0, e);
+        let maxn = simd_fmax(x, n);
+        assert_eq!(maxn, x);
+        let maxn = simd_fmax(y, n);
+        assert_eq!(maxn, y);
+    }
+}
diff --git a/src/test/run-make/a-b-a-linker-guard/Makefile b/src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile
similarity index 100%
rename from src/test/run-make/a-b-a-linker-guard/Makefile
rename to src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile
diff --git a/src/test/run-make/a-b-a-linker-guard/a.rs b/src/test/run-make-fulldeps/a-b-a-linker-guard/a.rs
similarity index 100%
rename from src/test/run-make/a-b-a-linker-guard/a.rs
rename to src/test/run-make-fulldeps/a-b-a-linker-guard/a.rs
diff --git a/src/test/run-make/a-b-a-linker-guard/b.rs b/src/test/run-make-fulldeps/a-b-a-linker-guard/b.rs
similarity index 100%
rename from src/test/run-make/a-b-a-linker-guard/b.rs
rename to src/test/run-make-fulldeps/a-b-a-linker-guard/b.rs
diff --git a/src/test/run-make/alloc-extern-crates/Makefile b/src/test/run-make-fulldeps/alloc-extern-crates/Makefile
similarity index 100%
rename from src/test/run-make/alloc-extern-crates/Makefile
rename to src/test/run-make-fulldeps/alloc-extern-crates/Makefile
diff --git a/src/test/run-make/alloc-extern-crates/fakealloc.rs b/src/test/run-make-fulldeps/alloc-extern-crates/fakealloc.rs
similarity index 100%
rename from src/test/run-make/alloc-extern-crates/fakealloc.rs
rename to src/test/run-make-fulldeps/alloc-extern-crates/fakealloc.rs
diff --git a/src/test/run-make/allow-non-lint-warnings-cmdline/Makefile b/src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile
similarity index 100%
rename from src/test/run-make/allow-non-lint-warnings-cmdline/Makefile
rename to src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile
diff --git a/src/test/run-make/allow-non-lint-warnings-cmdline/foo.rs b/src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/foo.rs
similarity index 100%
rename from src/test/run-make/allow-non-lint-warnings-cmdline/foo.rs
rename to src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/foo.rs
diff --git a/src/test/run-make/allow-warnings-cmdline-stability/Makefile b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile
similarity index 100%
rename from src/test/run-make/allow-warnings-cmdline-stability/Makefile
rename to src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile
diff --git a/src/test/run-make/allow-warnings-cmdline-stability/bar.rs b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/bar.rs
similarity index 100%
rename from src/test/run-make/allow-warnings-cmdline-stability/bar.rs
rename to src/test/run-make-fulldeps/allow-warnings-cmdline-stability/bar.rs
diff --git a/src/test/run-make/allow-warnings-cmdline-stability/foo.rs b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/foo.rs
similarity index 100%
rename from src/test/run-make/allow-warnings-cmdline-stability/foo.rs
rename to src/test/run-make-fulldeps/allow-warnings-cmdline-stability/foo.rs
diff --git a/src/test/run-make/archive-duplicate-names/Makefile b/src/test/run-make-fulldeps/archive-duplicate-names/Makefile
similarity index 100%
rename from src/test/run-make/archive-duplicate-names/Makefile
rename to src/test/run-make-fulldeps/archive-duplicate-names/Makefile
diff --git a/src/test/run-make/archive-duplicate-names/bar.c b/src/test/run-make-fulldeps/archive-duplicate-names/bar.c
similarity index 100%
rename from src/test/run-make/archive-duplicate-names/bar.c
rename to src/test/run-make-fulldeps/archive-duplicate-names/bar.c
diff --git a/src/test/run-make/archive-duplicate-names/bar.rs b/src/test/run-make-fulldeps/archive-duplicate-names/bar.rs
similarity index 100%
rename from src/test/run-make/archive-duplicate-names/bar.rs
rename to src/test/run-make-fulldeps/archive-duplicate-names/bar.rs
diff --git a/src/test/run-make/archive-duplicate-names/foo.c b/src/test/run-make-fulldeps/archive-duplicate-names/foo.c
similarity index 100%
rename from src/test/run-make/archive-duplicate-names/foo.c
rename to src/test/run-make-fulldeps/archive-duplicate-names/foo.c
diff --git a/src/test/run-make/archive-duplicate-names/foo.rs b/src/test/run-make-fulldeps/archive-duplicate-names/foo.rs
similarity index 100%
rename from src/test/run-make/archive-duplicate-names/foo.rs
rename to src/test/run-make-fulldeps/archive-duplicate-names/foo.rs
diff --git a/src/test/run-make/atomic-lock-free/Makefile b/src/test/run-make-fulldeps/atomic-lock-free/Makefile
similarity index 100%
rename from src/test/run-make/atomic-lock-free/Makefile
rename to src/test/run-make-fulldeps/atomic-lock-free/Makefile
diff --git a/src/test/run-make/atomic-lock-free/atomic_lock_free.rs b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs
similarity index 100%
rename from src/test/run-make/atomic-lock-free/atomic_lock_free.rs
rename to src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs
diff --git a/src/test/run-make/bare-outfile/Makefile b/src/test/run-make-fulldeps/bare-outfile/Makefile
similarity index 100%
rename from src/test/run-make/bare-outfile/Makefile
rename to src/test/run-make-fulldeps/bare-outfile/Makefile
diff --git a/src/test/run-make/bare-outfile/foo.rs b/src/test/run-make-fulldeps/bare-outfile/foo.rs
similarity index 100%
rename from src/test/run-make/bare-outfile/foo.rs
rename to src/test/run-make-fulldeps/bare-outfile/foo.rs
diff --git a/src/test/run-make/c-dynamic-dylib/Makefile b/src/test/run-make-fulldeps/c-dynamic-dylib/Makefile
similarity index 100%
rename from src/test/run-make/c-dynamic-dylib/Makefile
rename to src/test/run-make-fulldeps/c-dynamic-dylib/Makefile
diff --git a/src/test/run-make/c-dynamic-dylib/bar.rs b/src/test/run-make-fulldeps/c-dynamic-dylib/bar.rs
similarity index 100%
rename from src/test/run-make/c-dynamic-dylib/bar.rs
rename to src/test/run-make-fulldeps/c-dynamic-dylib/bar.rs
diff --git a/src/test/run-make/c-dynamic-dylib/cfoo.c b/src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c
similarity index 100%
rename from src/test/run-make/c-dynamic-dylib/cfoo.c
rename to src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c
diff --git a/src/test/run-make/c-dynamic-dylib/foo.rs b/src/test/run-make-fulldeps/c-dynamic-dylib/foo.rs
similarity index 100%
rename from src/test/run-make/c-dynamic-dylib/foo.rs
rename to src/test/run-make-fulldeps/c-dynamic-dylib/foo.rs
diff --git a/src/test/run-make/c-dynamic-rlib/Makefile b/src/test/run-make-fulldeps/c-dynamic-rlib/Makefile
similarity index 100%
rename from src/test/run-make/c-dynamic-rlib/Makefile
rename to src/test/run-make-fulldeps/c-dynamic-rlib/Makefile
diff --git a/src/test/run-make/c-dynamic-rlib/bar.rs b/src/test/run-make-fulldeps/c-dynamic-rlib/bar.rs
similarity index 100%
rename from src/test/run-make/c-dynamic-rlib/bar.rs
rename to src/test/run-make-fulldeps/c-dynamic-rlib/bar.rs
diff --git a/src/test/run-make/c-dynamic-rlib/cfoo.c b/src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c
similarity index 100%
rename from src/test/run-make/c-dynamic-rlib/cfoo.c
rename to src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c
diff --git a/src/test/run-make/c-dynamic-rlib/foo.rs b/src/test/run-make-fulldeps/c-dynamic-rlib/foo.rs
similarity index 100%
rename from src/test/run-make/c-dynamic-rlib/foo.rs
rename to src/test/run-make-fulldeps/c-dynamic-rlib/foo.rs
diff --git a/src/test/run-make/c-link-to-rust-dylib/Makefile b/src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile
similarity index 100%
rename from src/test/run-make/c-link-to-rust-dylib/Makefile
rename to src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile
diff --git a/src/test/run-make/c-link-to-rust-dylib/bar.c b/src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c
similarity index 100%
rename from src/test/run-make/c-link-to-rust-dylib/bar.c
rename to src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c
diff --git a/src/test/run-make/c-link-to-rust-dylib/foo.rs b/src/test/run-make-fulldeps/c-link-to-rust-dylib/foo.rs
similarity index 100%
rename from src/test/run-make/c-link-to-rust-dylib/foo.rs
rename to src/test/run-make-fulldeps/c-link-to-rust-dylib/foo.rs
diff --git a/src/test/run-make/c-link-to-rust-staticlib/Makefile b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile
similarity index 100%
rename from src/test/run-make/c-link-to-rust-staticlib/Makefile
rename to src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile
diff --git a/src/test/run-make/c-link-to-rust-staticlib/bar.c b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c
similarity index 100%
rename from src/test/run-make/c-link-to-rust-staticlib/bar.c
rename to src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c
diff --git a/src/test/run-make/c-link-to-rust-staticlib/foo.rs b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/foo.rs
similarity index 100%
rename from src/test/run-make/c-link-to-rust-staticlib/foo.rs
rename to src/test/run-make-fulldeps/c-link-to-rust-staticlib/foo.rs
diff --git a/src/test/run-make/c-static-dylib/Makefile b/src/test/run-make-fulldeps/c-static-dylib/Makefile
similarity index 100%
rename from src/test/run-make/c-static-dylib/Makefile
rename to src/test/run-make-fulldeps/c-static-dylib/Makefile
diff --git a/src/test/run-make/c-static-dylib/bar.rs b/src/test/run-make-fulldeps/c-static-dylib/bar.rs
similarity index 100%
rename from src/test/run-make/c-static-dylib/bar.rs
rename to src/test/run-make-fulldeps/c-static-dylib/bar.rs
diff --git a/src/test/run-make/c-static-dylib/cfoo.c b/src/test/run-make-fulldeps/c-static-dylib/cfoo.c
similarity index 100%
rename from src/test/run-make/c-static-dylib/cfoo.c
rename to src/test/run-make-fulldeps/c-static-dylib/cfoo.c
diff --git a/src/test/run-make/c-static-dylib/foo.rs b/src/test/run-make-fulldeps/c-static-dylib/foo.rs
similarity index 100%
rename from src/test/run-make/c-static-dylib/foo.rs
rename to src/test/run-make-fulldeps/c-static-dylib/foo.rs
diff --git a/src/test/run-make/c-static-rlib/Makefile b/src/test/run-make-fulldeps/c-static-rlib/Makefile
similarity index 100%
rename from src/test/run-make/c-static-rlib/Makefile
rename to src/test/run-make-fulldeps/c-static-rlib/Makefile
diff --git a/src/test/run-make/c-static-rlib/bar.rs b/src/test/run-make-fulldeps/c-static-rlib/bar.rs
similarity index 100%
rename from src/test/run-make/c-static-rlib/bar.rs
rename to src/test/run-make-fulldeps/c-static-rlib/bar.rs
diff --git a/src/test/run-make/c-static-rlib/cfoo.c b/src/test/run-make-fulldeps/c-static-rlib/cfoo.c
similarity index 100%
rename from src/test/run-make/c-static-rlib/cfoo.c
rename to src/test/run-make-fulldeps/c-static-rlib/cfoo.c
diff --git a/src/test/run-make/c-static-rlib/foo.rs b/src/test/run-make-fulldeps/c-static-rlib/foo.rs
similarity index 100%
rename from src/test/run-make/c-static-rlib/foo.rs
rename to src/test/run-make-fulldeps/c-static-rlib/foo.rs
diff --git a/src/test/run-make/cat-and-grep-sanity-check/Makefile b/src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile
similarity index 100%
rename from src/test/run-make/cat-and-grep-sanity-check/Makefile
rename to src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile
diff --git a/src/test/run-make/cdylib-fewer-symbols/Makefile b/src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile
similarity index 100%
rename from src/test/run-make/cdylib-fewer-symbols/Makefile
rename to src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile
diff --git a/src/test/run-make/cdylib-fewer-symbols/foo.rs b/src/test/run-make-fulldeps/cdylib-fewer-symbols/foo.rs
similarity index 100%
rename from src/test/run-make/cdylib-fewer-symbols/foo.rs
rename to src/test/run-make-fulldeps/cdylib-fewer-symbols/foo.rs
diff --git a/src/test/run-make/cdylib/Makefile b/src/test/run-make-fulldeps/cdylib/Makefile
similarity index 100%
rename from src/test/run-make/cdylib/Makefile
rename to src/test/run-make-fulldeps/cdylib/Makefile
diff --git a/src/test/run-make/cdylib/bar.rs b/src/test/run-make-fulldeps/cdylib/bar.rs
similarity index 100%
rename from src/test/run-make/cdylib/bar.rs
rename to src/test/run-make-fulldeps/cdylib/bar.rs
diff --git a/src/test/run-make/cdylib/foo.c b/src/test/run-make-fulldeps/cdylib/foo.c
similarity index 100%
rename from src/test/run-make/cdylib/foo.c
rename to src/test/run-make-fulldeps/cdylib/foo.c
diff --git a/src/test/run-make/cdylib/foo.rs b/src/test/run-make-fulldeps/cdylib/foo.rs
similarity index 100%
rename from src/test/run-make/cdylib/foo.rs
rename to src/test/run-make-fulldeps/cdylib/foo.rs
diff --git a/src/test/run-make/codegen-options-parsing/Makefile b/src/test/run-make-fulldeps/codegen-options-parsing/Makefile
similarity index 100%
rename from src/test/run-make/codegen-options-parsing/Makefile
rename to src/test/run-make-fulldeps/codegen-options-parsing/Makefile
diff --git a/src/test/run-make/codegen-options-parsing/dummy.rs b/src/test/run-make-fulldeps/codegen-options-parsing/dummy.rs
similarity index 100%
rename from src/test/run-make/codegen-options-parsing/dummy.rs
rename to src/test/run-make-fulldeps/codegen-options-parsing/dummy.rs
diff --git a/src/test/run-make/compile-stdin/Makefile b/src/test/run-make-fulldeps/compile-stdin/Makefile
similarity index 100%
rename from src/test/run-make/compile-stdin/Makefile
rename to src/test/run-make-fulldeps/compile-stdin/Makefile
diff --git a/src/test/run-make/compiler-lookup-paths-2/Makefile b/src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths-2/Makefile
rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile
diff --git a/src/test/run-make/compiler-lookup-paths-2/a.rs b/src/test/run-make-fulldeps/compiler-lookup-paths-2/a.rs
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths-2/a.rs
rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/a.rs
diff --git a/src/test/run-make/compiler-lookup-paths-2/b.rs b/src/test/run-make-fulldeps/compiler-lookup-paths-2/b.rs
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths-2/b.rs
rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/b.rs
diff --git a/src/test/run-make/compiler-lookup-paths-2/c.rs b/src/test/run-make-fulldeps/compiler-lookup-paths-2/c.rs
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths-2/c.rs
rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/c.rs
diff --git a/src/test/run-make/compiler-lookup-paths/Makefile b/src/test/run-make-fulldeps/compiler-lookup-paths/Makefile
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths/Makefile
rename to src/test/run-make-fulldeps/compiler-lookup-paths/Makefile
diff --git a/src/test/run-make/compiler-lookup-paths/a.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/a.rs
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths/a.rs
rename to src/test/run-make-fulldeps/compiler-lookup-paths/a.rs
diff --git a/src/test/run-make/compiler-lookup-paths/b.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/b.rs
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths/b.rs
rename to src/test/run-make-fulldeps/compiler-lookup-paths/b.rs
diff --git a/src/test/run-make/compiler-lookup-paths/c.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/c.rs
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths/c.rs
rename to src/test/run-make-fulldeps/compiler-lookup-paths/c.rs
diff --git a/src/test/run-make/compiler-lookup-paths/d.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/d.rs
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths/d.rs
rename to src/test/run-make-fulldeps/compiler-lookup-paths/d.rs
diff --git a/src/test/run-make/compiler-lookup-paths/e.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/e.rs
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths/e.rs
rename to src/test/run-make-fulldeps/compiler-lookup-paths/e.rs
diff --git a/src/test/run-make/compiler-lookup-paths/e2.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/e2.rs
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths/e2.rs
rename to src/test/run-make-fulldeps/compiler-lookup-paths/e2.rs
diff --git a/src/test/run-make/compiler-lookup-paths/f.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/f.rs
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths/f.rs
rename to src/test/run-make-fulldeps/compiler-lookup-paths/f.rs
diff --git a/src/test/run-make/compiler-lookup-paths/native.c b/src/test/run-make-fulldeps/compiler-lookup-paths/native.c
similarity index 100%
rename from src/test/run-make/compiler-lookup-paths/native.c
rename to src/test/run-make-fulldeps/compiler-lookup-paths/native.c
diff --git a/src/test/run-make/compiler-rt-works-on-mingw/Makefile b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile
similarity index 100%
rename from src/test/run-make/compiler-rt-works-on-mingw/Makefile
rename to src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile
diff --git a/src/test/run-make/compiler-rt-works-on-mingw/foo.cpp b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp
similarity index 100%
rename from src/test/run-make/compiler-rt-works-on-mingw/foo.cpp
rename to src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp
diff --git a/src/test/run-make/compiler-rt-works-on-mingw/foo.rs b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.rs
similarity index 100%
rename from src/test/run-make/compiler-rt-works-on-mingw/foo.rs
rename to src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.rs
diff --git a/src/test/run-make/crate-data-smoke/Makefile b/src/test/run-make-fulldeps/crate-data-smoke/Makefile
similarity index 100%
rename from src/test/run-make/crate-data-smoke/Makefile
rename to src/test/run-make-fulldeps/crate-data-smoke/Makefile
diff --git a/src/test/run-make/crate-data-smoke/crate.rs b/src/test/run-make-fulldeps/crate-data-smoke/crate.rs
similarity index 100%
rename from src/test/run-make/crate-data-smoke/crate.rs
rename to src/test/run-make-fulldeps/crate-data-smoke/crate.rs
diff --git a/src/test/run-make/crate-data-smoke/lib.rs b/src/test/run-make-fulldeps/crate-data-smoke/lib.rs
similarity index 100%
rename from src/test/run-make/crate-data-smoke/lib.rs
rename to src/test/run-make-fulldeps/crate-data-smoke/lib.rs
diff --git a/src/test/run-make/crate-data-smoke/rlib.rs b/src/test/run-make-fulldeps/crate-data-smoke/rlib.rs
similarity index 100%
rename from src/test/run-make/crate-data-smoke/rlib.rs
rename to src/test/run-make-fulldeps/crate-data-smoke/rlib.rs
diff --git a/src/test/run-make/crate-name-priority/Makefile b/src/test/run-make-fulldeps/crate-name-priority/Makefile
similarity index 100%
rename from src/test/run-make/crate-name-priority/Makefile
rename to src/test/run-make-fulldeps/crate-name-priority/Makefile
diff --git a/src/test/run-make/crate-name-priority/foo.rs b/src/test/run-make-fulldeps/crate-name-priority/foo.rs
similarity index 100%
rename from src/test/run-make/crate-name-priority/foo.rs
rename to src/test/run-make-fulldeps/crate-name-priority/foo.rs
diff --git a/src/test/run-make/crate-name-priority/foo1.rs b/src/test/run-make-fulldeps/crate-name-priority/foo1.rs
similarity index 100%
rename from src/test/run-make/crate-name-priority/foo1.rs
rename to src/test/run-make-fulldeps/crate-name-priority/foo1.rs
diff --git a/src/test/run-make/debug-assertions/Makefile b/src/test/run-make-fulldeps/debug-assertions/Makefile
similarity index 100%
rename from src/test/run-make/debug-assertions/Makefile
rename to src/test/run-make-fulldeps/debug-assertions/Makefile
diff --git a/src/test/run-make/debug-assertions/debug.rs b/src/test/run-make-fulldeps/debug-assertions/debug.rs
similarity index 100%
rename from src/test/run-make/debug-assertions/debug.rs
rename to src/test/run-make-fulldeps/debug-assertions/debug.rs
diff --git a/src/test/run-make/dep-info-doesnt-run-much/Makefile b/src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile
similarity index 100%
rename from src/test/run-make/dep-info-doesnt-run-much/Makefile
rename to src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile
diff --git a/src/test/run-make/dep-info-doesnt-run-much/foo.rs b/src/test/run-make-fulldeps/dep-info-doesnt-run-much/foo.rs
similarity index 100%
rename from src/test/run-make/dep-info-doesnt-run-much/foo.rs
rename to src/test/run-make-fulldeps/dep-info-doesnt-run-much/foo.rs
diff --git a/src/test/run-make/dep-info-spaces/Makefile b/src/test/run-make-fulldeps/dep-info-spaces/Makefile
similarity index 100%
rename from src/test/run-make/dep-info-spaces/Makefile
rename to src/test/run-make-fulldeps/dep-info-spaces/Makefile
diff --git a/src/test/run-make/dep-info-spaces/Makefile.foo b/src/test/run-make-fulldeps/dep-info-spaces/Makefile.foo
similarity index 100%
rename from src/test/run-make/dep-info-spaces/Makefile.foo
rename to src/test/run-make-fulldeps/dep-info-spaces/Makefile.foo
diff --git a/src/test/run-make/dep-info-spaces/bar.rs b/src/test/run-make-fulldeps/dep-info-spaces/bar.rs
similarity index 100%
rename from src/test/run-make/dep-info-spaces/bar.rs
rename to src/test/run-make-fulldeps/dep-info-spaces/bar.rs
diff --git a/src/test/run-make/dep-info-spaces/foo foo.rs b/src/test/run-make-fulldeps/dep-info-spaces/foo foo.rs
similarity index 100%
rename from src/test/run-make/dep-info-spaces/foo foo.rs
rename to src/test/run-make-fulldeps/dep-info-spaces/foo foo.rs
diff --git a/src/test/run-make/dep-info-spaces/lib.rs b/src/test/run-make-fulldeps/dep-info-spaces/lib.rs
similarity index 100%
rename from src/test/run-make/dep-info-spaces/lib.rs
rename to src/test/run-make-fulldeps/dep-info-spaces/lib.rs
diff --git a/src/test/run-make/dep-info/Makefile b/src/test/run-make-fulldeps/dep-info/Makefile
similarity index 100%
rename from src/test/run-make/dep-info/Makefile
rename to src/test/run-make-fulldeps/dep-info/Makefile
diff --git a/src/test/run-make/dep-info/Makefile.foo b/src/test/run-make-fulldeps/dep-info/Makefile.foo
similarity index 100%
rename from src/test/run-make/dep-info/Makefile.foo
rename to src/test/run-make-fulldeps/dep-info/Makefile.foo
diff --git a/src/test/run-make/dep-info/bar.rs b/src/test/run-make-fulldeps/dep-info/bar.rs
similarity index 100%
rename from src/test/run-make/dep-info/bar.rs
rename to src/test/run-make-fulldeps/dep-info/bar.rs
diff --git a/src/test/run-make/dep-info/foo.rs b/src/test/run-make-fulldeps/dep-info/foo.rs
similarity index 100%
rename from src/test/run-make/dep-info/foo.rs
rename to src/test/run-make-fulldeps/dep-info/foo.rs
diff --git a/src/test/run-make/dep-info/lib.rs b/src/test/run-make-fulldeps/dep-info/lib.rs
similarity index 100%
rename from src/test/run-make/dep-info/lib.rs
rename to src/test/run-make-fulldeps/dep-info/lib.rs
diff --git a/src/test/run-make/dep-info/lib2.rs b/src/test/run-make-fulldeps/dep-info/lib2.rs
similarity index 100%
rename from src/test/run-make/dep-info/lib2.rs
rename to src/test/run-make-fulldeps/dep-info/lib2.rs
diff --git a/src/test/run-make/duplicate-output-flavors/Makefile b/src/test/run-make-fulldeps/duplicate-output-flavors/Makefile
similarity index 100%
rename from src/test/run-make/duplicate-output-flavors/Makefile
rename to src/test/run-make-fulldeps/duplicate-output-flavors/Makefile
diff --git a/src/test/run-make/duplicate-output-flavors/foo.rs b/src/test/run-make-fulldeps/duplicate-output-flavors/foo.rs
similarity index 100%
rename from src/test/run-make/duplicate-output-flavors/foo.rs
rename to src/test/run-make-fulldeps/duplicate-output-flavors/foo.rs
diff --git a/src/test/run-make/dylib-chain/Makefile b/src/test/run-make-fulldeps/dylib-chain/Makefile
similarity index 100%
rename from src/test/run-make/dylib-chain/Makefile
rename to src/test/run-make-fulldeps/dylib-chain/Makefile
diff --git a/src/test/run-make/dylib-chain/m1.rs b/src/test/run-make-fulldeps/dylib-chain/m1.rs
similarity index 100%
rename from src/test/run-make/dylib-chain/m1.rs
rename to src/test/run-make-fulldeps/dylib-chain/m1.rs
diff --git a/src/test/run-make/dylib-chain/m2.rs b/src/test/run-make-fulldeps/dylib-chain/m2.rs
similarity index 100%
rename from src/test/run-make/dylib-chain/m2.rs
rename to src/test/run-make-fulldeps/dylib-chain/m2.rs
diff --git a/src/test/run-make/dylib-chain/m3.rs b/src/test/run-make-fulldeps/dylib-chain/m3.rs
similarity index 100%
rename from src/test/run-make/dylib-chain/m3.rs
rename to src/test/run-make-fulldeps/dylib-chain/m3.rs
diff --git a/src/test/run-make/dylib-chain/m4.rs b/src/test/run-make-fulldeps/dylib-chain/m4.rs
similarity index 100%
rename from src/test/run-make/dylib-chain/m4.rs
rename to src/test/run-make-fulldeps/dylib-chain/m4.rs
diff --git a/src/test/run-make/emit/Makefile b/src/test/run-make-fulldeps/emit/Makefile
similarity index 100%
rename from src/test/run-make/emit/Makefile
rename to src/test/run-make-fulldeps/emit/Makefile
diff --git a/src/test/run-make/emit/test-24876.rs b/src/test/run-make-fulldeps/emit/test-24876.rs
similarity index 100%
rename from src/test/run-make/emit/test-24876.rs
rename to src/test/run-make-fulldeps/emit/test-24876.rs
diff --git a/src/test/run-make/emit/test-26235.rs b/src/test/run-make-fulldeps/emit/test-26235.rs
similarity index 100%
rename from src/test/run-make/emit/test-26235.rs
rename to src/test/run-make-fulldeps/emit/test-26235.rs
diff --git a/src/test/run-make/error-found-staticlib-instead-crate/Makefile b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile
similarity index 100%
rename from src/test/run-make/error-found-staticlib-instead-crate/Makefile
rename to src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile
diff --git a/src/test/run-make/error-found-staticlib-instead-crate/bar.rs b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/bar.rs
similarity index 100%
rename from src/test/run-make/error-found-staticlib-instead-crate/bar.rs
rename to src/test/run-make-fulldeps/error-found-staticlib-instead-crate/bar.rs
diff --git a/src/test/run-make/error-found-staticlib-instead-crate/foo.rs b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/foo.rs
similarity index 100%
rename from src/test/run-make/error-found-staticlib-instead-crate/foo.rs
rename to src/test/run-make-fulldeps/error-found-staticlib-instead-crate/foo.rs
diff --git a/src/test/run-make/error-writing-dependencies/Makefile b/src/test/run-make-fulldeps/error-writing-dependencies/Makefile
similarity index 100%
rename from src/test/run-make/error-writing-dependencies/Makefile
rename to src/test/run-make-fulldeps/error-writing-dependencies/Makefile
diff --git a/src/test/run-make/error-writing-dependencies/foo.rs b/src/test/run-make-fulldeps/error-writing-dependencies/foo.rs
similarity index 100%
rename from src/test/run-make/error-writing-dependencies/foo.rs
rename to src/test/run-make-fulldeps/error-writing-dependencies/foo.rs
diff --git a/src/test/run-make/extern-diff-internal-name/Makefile b/src/test/run-make-fulldeps/extern-diff-internal-name/Makefile
similarity index 100%
rename from src/test/run-make/extern-diff-internal-name/Makefile
rename to src/test/run-make-fulldeps/extern-diff-internal-name/Makefile
diff --git a/src/test/run-make/extern-diff-internal-name/lib.rs b/src/test/run-make-fulldeps/extern-diff-internal-name/lib.rs
similarity index 100%
rename from src/test/run-make/extern-diff-internal-name/lib.rs
rename to src/test/run-make-fulldeps/extern-diff-internal-name/lib.rs
diff --git a/src/test/run-make/extern-diff-internal-name/test.rs b/src/test/run-make-fulldeps/extern-diff-internal-name/test.rs
similarity index 100%
rename from src/test/run-make/extern-diff-internal-name/test.rs
rename to src/test/run-make-fulldeps/extern-diff-internal-name/test.rs
diff --git a/src/test/run-make/extern-flag-disambiguates/Makefile b/src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile
similarity index 100%
rename from src/test/run-make/extern-flag-disambiguates/Makefile
rename to src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile
diff --git a/src/test/run-make/extern-flag-disambiguates/a.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/a.rs
similarity index 100%
rename from src/test/run-make/extern-flag-disambiguates/a.rs
rename to src/test/run-make-fulldeps/extern-flag-disambiguates/a.rs
diff --git a/src/test/run-make/extern-flag-disambiguates/b.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/b.rs
similarity index 100%
rename from src/test/run-make/extern-flag-disambiguates/b.rs
rename to src/test/run-make-fulldeps/extern-flag-disambiguates/b.rs
diff --git a/src/test/run-make/extern-flag-disambiguates/c.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/c.rs
similarity index 100%
rename from src/test/run-make/extern-flag-disambiguates/c.rs
rename to src/test/run-make-fulldeps/extern-flag-disambiguates/c.rs
diff --git a/src/test/run-make/extern-flag-disambiguates/d.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/d.rs
similarity index 100%
rename from src/test/run-make/extern-flag-disambiguates/d.rs
rename to src/test/run-make-fulldeps/extern-flag-disambiguates/d.rs
diff --git a/src/test/run-make/extern-flag-fun/Makefile b/src/test/run-make-fulldeps/extern-flag-fun/Makefile
similarity index 100%
rename from src/test/run-make/extern-flag-fun/Makefile
rename to src/test/run-make-fulldeps/extern-flag-fun/Makefile
diff --git a/src/test/run-make/extern-flag-fun/bar-alt.rs b/src/test/run-make-fulldeps/extern-flag-fun/bar-alt.rs
similarity index 100%
rename from src/test/run-make/extern-flag-fun/bar-alt.rs
rename to src/test/run-make-fulldeps/extern-flag-fun/bar-alt.rs
diff --git a/src/test/run-make/extern-flag-fun/bar.rs b/src/test/run-make-fulldeps/extern-flag-fun/bar.rs
similarity index 100%
rename from src/test/run-make/extern-flag-fun/bar.rs
rename to src/test/run-make-fulldeps/extern-flag-fun/bar.rs
diff --git a/src/test/run-make/extern-flag-fun/foo.rs b/src/test/run-make-fulldeps/extern-flag-fun/foo.rs
similarity index 100%
rename from src/test/run-make/extern-flag-fun/foo.rs
rename to src/test/run-make-fulldeps/extern-flag-fun/foo.rs
diff --git a/src/test/run-make/extern-fn-generic/Makefile b/src/test/run-make-fulldeps/extern-fn-generic/Makefile
similarity index 100%
rename from src/test/run-make/extern-fn-generic/Makefile
rename to src/test/run-make-fulldeps/extern-fn-generic/Makefile
diff --git a/src/test/run-make/extern-fn-generic/test.c b/src/test/run-make-fulldeps/extern-fn-generic/test.c
similarity index 100%
rename from src/test/run-make/extern-fn-generic/test.c
rename to src/test/run-make-fulldeps/extern-fn-generic/test.c
diff --git a/src/test/run-make/extern-fn-generic/test.rs b/src/test/run-make-fulldeps/extern-fn-generic/test.rs
similarity index 100%
rename from src/test/run-make/extern-fn-generic/test.rs
rename to src/test/run-make-fulldeps/extern-fn-generic/test.rs
diff --git a/src/test/run-make/extern-fn-generic/testcrate.rs b/src/test/run-make-fulldeps/extern-fn-generic/testcrate.rs
similarity index 100%
rename from src/test/run-make/extern-fn-generic/testcrate.rs
rename to src/test/run-make-fulldeps/extern-fn-generic/testcrate.rs
diff --git a/src/test/run-make/extern-fn-mangle/Makefile b/src/test/run-make-fulldeps/extern-fn-mangle/Makefile
similarity index 100%
rename from src/test/run-make/extern-fn-mangle/Makefile
rename to src/test/run-make-fulldeps/extern-fn-mangle/Makefile
diff --git a/src/test/run-make/extern-fn-mangle/test.c b/src/test/run-make-fulldeps/extern-fn-mangle/test.c
similarity index 100%
rename from src/test/run-make/extern-fn-mangle/test.c
rename to src/test/run-make-fulldeps/extern-fn-mangle/test.c
diff --git a/src/test/run-make/extern-fn-mangle/test.rs b/src/test/run-make-fulldeps/extern-fn-mangle/test.rs
similarity index 100%
rename from src/test/run-make/extern-fn-mangle/test.rs
rename to src/test/run-make-fulldeps/extern-fn-mangle/test.rs
diff --git a/src/test/run-make/extern-fn-reachable/Makefile b/src/test/run-make-fulldeps/extern-fn-reachable/Makefile
similarity index 100%
rename from src/test/run-make/extern-fn-reachable/Makefile
rename to src/test/run-make-fulldeps/extern-fn-reachable/Makefile
diff --git a/src/test/run-make/extern-fn-reachable/dylib.rs b/src/test/run-make-fulldeps/extern-fn-reachable/dylib.rs
similarity index 100%
rename from src/test/run-make/extern-fn-reachable/dylib.rs
rename to src/test/run-make-fulldeps/extern-fn-reachable/dylib.rs
diff --git a/src/test/run-make/extern-fn-reachable/main.rs b/src/test/run-make-fulldeps/extern-fn-reachable/main.rs
similarity index 100%
rename from src/test/run-make/extern-fn-reachable/main.rs
rename to src/test/run-make-fulldeps/extern-fn-reachable/main.rs
diff --git a/src/test/run-make/extern-fn-struct-passing-abi/Makefile b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile
similarity index 100%
rename from src/test/run-make/extern-fn-struct-passing-abi/Makefile
rename to src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile
diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.c b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.c
similarity index 100%
rename from src/test/run-make/extern-fn-struct-passing-abi/test.c
rename to src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.c
diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.rs b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.rs
similarity index 100%
rename from src/test/run-make/extern-fn-struct-passing-abi/test.rs
rename to src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.rs
diff --git a/src/test/run-make/extern-fn-with-extern-types/Makefile b/src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile
similarity index 100%
rename from src/test/run-make/extern-fn-with-extern-types/Makefile
rename to src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile
diff --git a/src/test/run-make/extern-fn-with-extern-types/ctest.c b/src/test/run-make-fulldeps/extern-fn-with-extern-types/ctest.c
similarity index 100%
rename from src/test/run-make/extern-fn-with-extern-types/ctest.c
rename to src/test/run-make-fulldeps/extern-fn-with-extern-types/ctest.c
diff --git a/src/test/run-make/extern-fn-with-extern-types/test.rs b/src/test/run-make-fulldeps/extern-fn-with-extern-types/test.rs
similarity index 100%
rename from src/test/run-make/extern-fn-with-extern-types/test.rs
rename to src/test/run-make-fulldeps/extern-fn-with-extern-types/test.rs
diff --git a/src/test/run-make/extern-fn-with-packed-struct/Makefile b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile
similarity index 100%
rename from src/test/run-make/extern-fn-with-packed-struct/Makefile
rename to src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile
diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.c b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c
similarity index 100%
rename from src/test/run-make/extern-fn-with-packed-struct/test.c
rename to src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c
diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.rs b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.rs
similarity index 100%
rename from src/test/run-make/extern-fn-with-packed-struct/test.rs
rename to src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.rs
diff --git a/src/test/run-make/extern-fn-with-union/Makefile b/src/test/run-make-fulldeps/extern-fn-with-union/Makefile
similarity index 100%
rename from src/test/run-make/extern-fn-with-union/Makefile
rename to src/test/run-make-fulldeps/extern-fn-with-union/Makefile
diff --git a/src/test/run-make/extern-fn-with-union/ctest.c b/src/test/run-make-fulldeps/extern-fn-with-union/ctest.c
similarity index 100%
rename from src/test/run-make/extern-fn-with-union/ctest.c
rename to src/test/run-make-fulldeps/extern-fn-with-union/ctest.c
diff --git a/src/test/run-make/extern-fn-with-union/test.rs b/src/test/run-make-fulldeps/extern-fn-with-union/test.rs
similarity index 100%
rename from src/test/run-make/extern-fn-with-union/test.rs
rename to src/test/run-make-fulldeps/extern-fn-with-union/test.rs
diff --git a/src/test/run-make/extern-fn-with-union/testcrate.rs b/src/test/run-make-fulldeps/extern-fn-with-union/testcrate.rs
similarity index 100%
rename from src/test/run-make/extern-fn-with-union/testcrate.rs
rename to src/test/run-make-fulldeps/extern-fn-with-union/testcrate.rs
diff --git a/src/test/run-make/extern-multiple-copies/Makefile b/src/test/run-make-fulldeps/extern-multiple-copies/Makefile
similarity index 100%
rename from src/test/run-make/extern-multiple-copies/Makefile
rename to src/test/run-make-fulldeps/extern-multiple-copies/Makefile
diff --git a/src/test/run-make/extern-multiple-copies/bar.rs b/src/test/run-make-fulldeps/extern-multiple-copies/bar.rs
similarity index 100%
rename from src/test/run-make/extern-multiple-copies/bar.rs
rename to src/test/run-make-fulldeps/extern-multiple-copies/bar.rs
diff --git a/src/test/run-make/extern-multiple-copies/foo1.rs b/src/test/run-make-fulldeps/extern-multiple-copies/foo1.rs
similarity index 100%
rename from src/test/run-make/extern-multiple-copies/foo1.rs
rename to src/test/run-make-fulldeps/extern-multiple-copies/foo1.rs
diff --git a/src/test/run-make/extern-multiple-copies/foo2.rs b/src/test/run-make-fulldeps/extern-multiple-copies/foo2.rs
similarity index 100%
rename from src/test/run-make/extern-multiple-copies/foo2.rs
rename to src/test/run-make-fulldeps/extern-multiple-copies/foo2.rs
diff --git a/src/test/run-make/extern-multiple-copies2/Makefile b/src/test/run-make-fulldeps/extern-multiple-copies2/Makefile
similarity index 100%
rename from src/test/run-make/extern-multiple-copies2/Makefile
rename to src/test/run-make-fulldeps/extern-multiple-copies2/Makefile
diff --git a/src/test/run-make/extern-multiple-copies2/bar.rs b/src/test/run-make-fulldeps/extern-multiple-copies2/bar.rs
similarity index 100%
rename from src/test/run-make/extern-multiple-copies2/bar.rs
rename to src/test/run-make-fulldeps/extern-multiple-copies2/bar.rs
diff --git a/src/test/run-make/extern-multiple-copies2/foo1.rs b/src/test/run-make-fulldeps/extern-multiple-copies2/foo1.rs
similarity index 100%
rename from src/test/run-make/extern-multiple-copies2/foo1.rs
rename to src/test/run-make-fulldeps/extern-multiple-copies2/foo1.rs
diff --git a/src/test/run-make/extern-multiple-copies2/foo2.rs b/src/test/run-make-fulldeps/extern-multiple-copies2/foo2.rs
similarity index 100%
rename from src/test/run-make/extern-multiple-copies2/foo2.rs
rename to src/test/run-make-fulldeps/extern-multiple-copies2/foo2.rs
diff --git a/src/test/run-make/extern-overrides-distribution/Makefile b/src/test/run-make-fulldeps/extern-overrides-distribution/Makefile
similarity index 100%
rename from src/test/run-make/extern-overrides-distribution/Makefile
rename to src/test/run-make-fulldeps/extern-overrides-distribution/Makefile
diff --git a/src/test/run-make/extern-overrides-distribution/libc.rs b/src/test/run-make-fulldeps/extern-overrides-distribution/libc.rs
similarity index 100%
rename from src/test/run-make/extern-overrides-distribution/libc.rs
rename to src/test/run-make-fulldeps/extern-overrides-distribution/libc.rs
diff --git a/src/test/run-make/extern-overrides-distribution/main.rs b/src/test/run-make-fulldeps/extern-overrides-distribution/main.rs
similarity index 100%
rename from src/test/run-make/extern-overrides-distribution/main.rs
rename to src/test/run-make-fulldeps/extern-overrides-distribution/main.rs
diff --git a/src/test/run-make/extra-filename-with-temp-outputs/Makefile b/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile
similarity index 100%
rename from src/test/run-make/extra-filename-with-temp-outputs/Makefile
rename to src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile
diff --git a/src/test/run-make/extra-filename-with-temp-outputs/foo.rs b/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/foo.rs
similarity index 100%
rename from src/test/run-make/extra-filename-with-temp-outputs/foo.rs
rename to src/test/run-make-fulldeps/extra-filename-with-temp-outputs/foo.rs
diff --git a/src/test/run-make/fpic/Makefile b/src/test/run-make-fulldeps/fpic/Makefile
similarity index 100%
rename from src/test/run-make/fpic/Makefile
rename to src/test/run-make-fulldeps/fpic/Makefile
diff --git a/src/test/run-make/fpic/hello.rs b/src/test/run-make-fulldeps/fpic/hello.rs
similarity index 100%
rename from src/test/run-make/fpic/hello.rs
rename to src/test/run-make-fulldeps/fpic/hello.rs
diff --git a/src/test/run-make/hir-tree/Makefile b/src/test/run-make-fulldeps/hir-tree/Makefile
similarity index 100%
rename from src/test/run-make/hir-tree/Makefile
rename to src/test/run-make-fulldeps/hir-tree/Makefile
diff --git a/src/test/run-make/hir-tree/input.rs b/src/test/run-make-fulldeps/hir-tree/input.rs
similarity index 100%
rename from src/test/run-make/hir-tree/input.rs
rename to src/test/run-make-fulldeps/hir-tree/input.rs
diff --git a/src/test/run-make/hotplug_codegen_backend/Makefile b/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile
similarity index 100%
rename from src/test/run-make/hotplug_codegen_backend/Makefile
rename to src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile
diff --git a/src/test/run-make/hotplug_codegen_backend/some_crate.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs
similarity index 100%
rename from src/test/run-make/hotplug_codegen_backend/some_crate.rs
rename to src/test/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs
diff --git a/src/test/run-make/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
similarity index 100%
rename from src/test/run-make/hotplug_codegen_backend/the_backend.rs
rename to src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
diff --git a/src/test/run-make/include_bytes_deps/Makefile b/src/test/run-make-fulldeps/include_bytes_deps/Makefile
similarity index 100%
rename from src/test/run-make/include_bytes_deps/Makefile
rename to src/test/run-make-fulldeps/include_bytes_deps/Makefile
diff --git a/src/test/run-make/include_bytes_deps/input.bin b/src/test/run-make-fulldeps/include_bytes_deps/input.bin
similarity index 100%
rename from src/test/run-make/include_bytes_deps/input.bin
rename to src/test/run-make-fulldeps/include_bytes_deps/input.bin
diff --git a/src/test/run-make/include_bytes_deps/input.md b/src/test/run-make-fulldeps/include_bytes_deps/input.md
similarity index 100%
rename from src/test/run-make/include_bytes_deps/input.md
rename to src/test/run-make-fulldeps/include_bytes_deps/input.md
diff --git a/src/test/run-make/include_bytes_deps/input.txt b/src/test/run-make-fulldeps/include_bytes_deps/input.txt
similarity index 100%
rename from src/test/run-make/include_bytes_deps/input.txt
rename to src/test/run-make-fulldeps/include_bytes_deps/input.txt
diff --git a/src/test/run-make/include_bytes_deps/main.rs b/src/test/run-make-fulldeps/include_bytes_deps/main.rs
similarity index 100%
rename from src/test/run-make/include_bytes_deps/main.rs
rename to src/test/run-make-fulldeps/include_bytes_deps/main.rs
diff --git a/src/test/run-make/inline-always-many-cgu/Makefile b/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile
similarity index 100%
rename from src/test/run-make/inline-always-many-cgu/Makefile
rename to src/test/run-make-fulldeps/inline-always-many-cgu/Makefile
diff --git a/src/test/run-make/inline-always-many-cgu/foo.rs b/src/test/run-make-fulldeps/inline-always-many-cgu/foo.rs
similarity index 100%
rename from src/test/run-make/inline-always-many-cgu/foo.rs
rename to src/test/run-make-fulldeps/inline-always-many-cgu/foo.rs
diff --git a/src/test/run-make/interdependent-c-libraries/Makefile b/src/test/run-make-fulldeps/interdependent-c-libraries/Makefile
similarity index 100%
rename from src/test/run-make/interdependent-c-libraries/Makefile
rename to src/test/run-make-fulldeps/interdependent-c-libraries/Makefile
diff --git a/src/test/run-make/interdependent-c-libraries/bar.c b/src/test/run-make-fulldeps/interdependent-c-libraries/bar.c
similarity index 100%
rename from src/test/run-make/interdependent-c-libraries/bar.c
rename to src/test/run-make-fulldeps/interdependent-c-libraries/bar.c
diff --git a/src/test/run-make/interdependent-c-libraries/bar.rs b/src/test/run-make-fulldeps/interdependent-c-libraries/bar.rs
similarity index 100%
rename from src/test/run-make/interdependent-c-libraries/bar.rs
rename to src/test/run-make-fulldeps/interdependent-c-libraries/bar.rs
diff --git a/src/test/run-make/interdependent-c-libraries/foo.c b/src/test/run-make-fulldeps/interdependent-c-libraries/foo.c
similarity index 100%
rename from src/test/run-make/interdependent-c-libraries/foo.c
rename to src/test/run-make-fulldeps/interdependent-c-libraries/foo.c
diff --git a/src/test/run-make/interdependent-c-libraries/foo.rs b/src/test/run-make-fulldeps/interdependent-c-libraries/foo.rs
similarity index 100%
rename from src/test/run-make/interdependent-c-libraries/foo.rs
rename to src/test/run-make-fulldeps/interdependent-c-libraries/foo.rs
diff --git a/src/test/run-make/interdependent-c-libraries/main.rs b/src/test/run-make-fulldeps/interdependent-c-libraries/main.rs
similarity index 100%
rename from src/test/run-make/interdependent-c-libraries/main.rs
rename to src/test/run-make-fulldeps/interdependent-c-libraries/main.rs
diff --git a/src/test/run-make/intrinsic-unreachable/Makefile b/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile
similarity index 100%
rename from src/test/run-make/intrinsic-unreachable/Makefile
rename to src/test/run-make-fulldeps/intrinsic-unreachable/Makefile
diff --git a/src/test/run-make/intrinsic-unreachable/exit-ret.rs b/src/test/run-make-fulldeps/intrinsic-unreachable/exit-ret.rs
similarity index 100%
rename from src/test/run-make/intrinsic-unreachable/exit-ret.rs
rename to src/test/run-make-fulldeps/intrinsic-unreachable/exit-ret.rs
diff --git a/src/test/run-make/intrinsic-unreachable/exit-unreachable.rs b/src/test/run-make-fulldeps/intrinsic-unreachable/exit-unreachable.rs
similarity index 100%
rename from src/test/run-make/intrinsic-unreachable/exit-unreachable.rs
rename to src/test/run-make-fulldeps/intrinsic-unreachable/exit-unreachable.rs
diff --git a/src/test/run-make/invalid-library/Makefile b/src/test/run-make-fulldeps/invalid-library/Makefile
similarity index 100%
rename from src/test/run-make/invalid-library/Makefile
rename to src/test/run-make-fulldeps/invalid-library/Makefile
diff --git a/src/test/run-make/invalid-library/foo.rs b/src/test/run-make-fulldeps/invalid-library/foo.rs
similarity index 100%
rename from src/test/run-make/invalid-library/foo.rs
rename to src/test/run-make-fulldeps/invalid-library/foo.rs
diff --git a/src/test/run-make/invalid-staticlib/Makefile b/src/test/run-make-fulldeps/invalid-staticlib/Makefile
similarity index 100%
rename from src/test/run-make/invalid-staticlib/Makefile
rename to src/test/run-make-fulldeps/invalid-staticlib/Makefile
diff --git a/src/test/run-make/issue-11908/Makefile b/src/test/run-make-fulldeps/issue-11908/Makefile
similarity index 100%
rename from src/test/run-make/issue-11908/Makefile
rename to src/test/run-make-fulldeps/issue-11908/Makefile
diff --git a/src/test/run-make/issue-11908/bar.rs b/src/test/run-make-fulldeps/issue-11908/bar.rs
similarity index 100%
rename from src/test/run-make/issue-11908/bar.rs
rename to src/test/run-make-fulldeps/issue-11908/bar.rs
diff --git a/src/test/run-make/issue-11908/foo.rs b/src/test/run-make-fulldeps/issue-11908/foo.rs
similarity index 100%
rename from src/test/run-make/issue-11908/foo.rs
rename to src/test/run-make-fulldeps/issue-11908/foo.rs
diff --git a/src/test/run-make/issue-14500/Makefile b/src/test/run-make-fulldeps/issue-14500/Makefile
similarity index 100%
rename from src/test/run-make/issue-14500/Makefile
rename to src/test/run-make-fulldeps/issue-14500/Makefile
diff --git a/src/test/run-make/issue-14500/bar.rs b/src/test/run-make-fulldeps/issue-14500/bar.rs
similarity index 100%
rename from src/test/run-make/issue-14500/bar.rs
rename to src/test/run-make-fulldeps/issue-14500/bar.rs
diff --git a/src/test/run-make/issue-14500/foo.c b/src/test/run-make-fulldeps/issue-14500/foo.c
similarity index 100%
rename from src/test/run-make/issue-14500/foo.c
rename to src/test/run-make-fulldeps/issue-14500/foo.c
diff --git a/src/test/run-make/issue-14500/foo.rs b/src/test/run-make-fulldeps/issue-14500/foo.rs
similarity index 100%
rename from src/test/run-make/issue-14500/foo.rs
rename to src/test/run-make-fulldeps/issue-14500/foo.rs
diff --git a/src/test/run-make/issue-14698/Makefile b/src/test/run-make-fulldeps/issue-14698/Makefile
similarity index 100%
rename from src/test/run-make/issue-14698/Makefile
rename to src/test/run-make-fulldeps/issue-14698/Makefile
diff --git a/src/test/run-make/issue-14698/foo.rs b/src/test/run-make-fulldeps/issue-14698/foo.rs
similarity index 100%
rename from src/test/run-make/issue-14698/foo.rs
rename to src/test/run-make-fulldeps/issue-14698/foo.rs
diff --git a/src/test/run-make/issue-15460/Makefile b/src/test/run-make-fulldeps/issue-15460/Makefile
similarity index 100%
rename from src/test/run-make/issue-15460/Makefile
rename to src/test/run-make-fulldeps/issue-15460/Makefile
diff --git a/src/test/run-make/issue-15460/bar.rs b/src/test/run-make-fulldeps/issue-15460/bar.rs
similarity index 100%
rename from src/test/run-make/issue-15460/bar.rs
rename to src/test/run-make-fulldeps/issue-15460/bar.rs
diff --git a/src/test/run-make/issue-15460/foo.c b/src/test/run-make-fulldeps/issue-15460/foo.c
similarity index 100%
rename from src/test/run-make/issue-15460/foo.c
rename to src/test/run-make-fulldeps/issue-15460/foo.c
diff --git a/src/test/run-make/issue-15460/foo.rs b/src/test/run-make-fulldeps/issue-15460/foo.rs
similarity index 100%
rename from src/test/run-make/issue-15460/foo.rs
rename to src/test/run-make-fulldeps/issue-15460/foo.rs
diff --git a/src/test/run-make/issue-18943/Makefile b/src/test/run-make-fulldeps/issue-18943/Makefile
similarity index 100%
rename from src/test/run-make/issue-18943/Makefile
rename to src/test/run-make-fulldeps/issue-18943/Makefile
diff --git a/src/test/run-make/issue-18943/foo.rs b/src/test/run-make-fulldeps/issue-18943/foo.rs
similarity index 100%
rename from src/test/run-make/issue-18943/foo.rs
rename to src/test/run-make-fulldeps/issue-18943/foo.rs
diff --git a/src/test/run-make/issue-19371/Makefile b/src/test/run-make-fulldeps/issue-19371/Makefile
similarity index 100%
rename from src/test/run-make/issue-19371/Makefile
rename to src/test/run-make-fulldeps/issue-19371/Makefile
diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs
similarity index 100%
rename from src/test/run-make/issue-19371/foo.rs
rename to src/test/run-make-fulldeps/issue-19371/foo.rs
diff --git a/src/test/run-make/issue-20626/Makefile b/src/test/run-make-fulldeps/issue-20626/Makefile
similarity index 100%
rename from src/test/run-make/issue-20626/Makefile
rename to src/test/run-make-fulldeps/issue-20626/Makefile
diff --git a/src/test/run-make/issue-20626/foo.rs b/src/test/run-make-fulldeps/issue-20626/foo.rs
similarity index 100%
rename from src/test/run-make/issue-20626/foo.rs
rename to src/test/run-make-fulldeps/issue-20626/foo.rs
diff --git a/src/test/run-make/issue-22131/Makefile b/src/test/run-make-fulldeps/issue-22131/Makefile
similarity index 100%
rename from src/test/run-make/issue-22131/Makefile
rename to src/test/run-make-fulldeps/issue-22131/Makefile
diff --git a/src/test/run-make/issue-22131/foo.rs b/src/test/run-make-fulldeps/issue-22131/foo.rs
similarity index 100%
rename from src/test/run-make/issue-22131/foo.rs
rename to src/test/run-make-fulldeps/issue-22131/foo.rs
diff --git a/src/test/run-make/issue-24445/Makefile b/src/test/run-make-fulldeps/issue-24445/Makefile
similarity index 100%
rename from src/test/run-make/issue-24445/Makefile
rename to src/test/run-make-fulldeps/issue-24445/Makefile
diff --git a/src/test/run-make/issue-24445/foo.c b/src/test/run-make-fulldeps/issue-24445/foo.c
similarity index 100%
rename from src/test/run-make/issue-24445/foo.c
rename to src/test/run-make-fulldeps/issue-24445/foo.c
diff --git a/src/test/run-make/issue-24445/foo.rs b/src/test/run-make-fulldeps/issue-24445/foo.rs
similarity index 100%
rename from src/test/run-make/issue-24445/foo.rs
rename to src/test/run-make-fulldeps/issue-24445/foo.rs
diff --git a/src/test/run-make/issue-25581/Makefile b/src/test/run-make-fulldeps/issue-25581/Makefile
similarity index 100%
rename from src/test/run-make/issue-25581/Makefile
rename to src/test/run-make-fulldeps/issue-25581/Makefile
diff --git a/src/test/run-make/issue-25581/test.c b/src/test/run-make-fulldeps/issue-25581/test.c
similarity index 100%
rename from src/test/run-make/issue-25581/test.c
rename to src/test/run-make-fulldeps/issue-25581/test.c
diff --git a/src/test/run-make/issue-25581/test.rs b/src/test/run-make-fulldeps/issue-25581/test.rs
similarity index 100%
rename from src/test/run-make/issue-25581/test.rs
rename to src/test/run-make-fulldeps/issue-25581/test.rs
diff --git a/src/test/run-make/issue-26006/Makefile b/src/test/run-make-fulldeps/issue-26006/Makefile
similarity index 100%
rename from src/test/run-make/issue-26006/Makefile
rename to src/test/run-make-fulldeps/issue-26006/Makefile
diff --git a/src/test/run-make/issue-26006/in/libc/lib.rs b/src/test/run-make-fulldeps/issue-26006/in/libc/lib.rs
similarity index 100%
rename from src/test/run-make/issue-26006/in/libc/lib.rs
rename to src/test/run-make-fulldeps/issue-26006/in/libc/lib.rs
diff --git a/src/test/run-make/issue-26006/in/time/lib.rs b/src/test/run-make-fulldeps/issue-26006/in/time/lib.rs
similarity index 100%
rename from src/test/run-make/issue-26006/in/time/lib.rs
rename to src/test/run-make-fulldeps/issue-26006/in/time/lib.rs
diff --git a/src/test/run-make/issue-26092/Makefile b/src/test/run-make-fulldeps/issue-26092/Makefile
similarity index 100%
rename from src/test/run-make/issue-26092/Makefile
rename to src/test/run-make-fulldeps/issue-26092/Makefile
diff --git a/src/test/run-make/issue-26092/blank.rs b/src/test/run-make-fulldeps/issue-26092/blank.rs
similarity index 100%
rename from src/test/run-make/issue-26092/blank.rs
rename to src/test/run-make-fulldeps/issue-26092/blank.rs
diff --git a/src/test/run-make/issue-28595/Makefile b/src/test/run-make-fulldeps/issue-28595/Makefile
similarity index 100%
rename from src/test/run-make/issue-28595/Makefile
rename to src/test/run-make-fulldeps/issue-28595/Makefile
diff --git a/src/test/run-make/issue-28595/a.c b/src/test/run-make-fulldeps/issue-28595/a.c
similarity index 100%
rename from src/test/run-make/issue-28595/a.c
rename to src/test/run-make-fulldeps/issue-28595/a.c
diff --git a/src/test/run-make/issue-28595/a.rs b/src/test/run-make-fulldeps/issue-28595/a.rs
similarity index 100%
rename from src/test/run-make/issue-28595/a.rs
rename to src/test/run-make-fulldeps/issue-28595/a.rs
diff --git a/src/test/run-make/issue-28595/b.c b/src/test/run-make-fulldeps/issue-28595/b.c
similarity index 100%
rename from src/test/run-make/issue-28595/b.c
rename to src/test/run-make-fulldeps/issue-28595/b.c
diff --git a/src/test/run-make/issue-28595/b.rs b/src/test/run-make-fulldeps/issue-28595/b.rs
similarity index 100%
rename from src/test/run-make/issue-28595/b.rs
rename to src/test/run-make-fulldeps/issue-28595/b.rs
diff --git a/src/test/run-make/issue-28766/Makefile b/src/test/run-make-fulldeps/issue-28766/Makefile
similarity index 100%
rename from src/test/run-make/issue-28766/Makefile
rename to src/test/run-make-fulldeps/issue-28766/Makefile
diff --git a/src/test/run-make/issue-28766/foo.rs b/src/test/run-make-fulldeps/issue-28766/foo.rs
similarity index 100%
rename from src/test/run-make/issue-28766/foo.rs
rename to src/test/run-make-fulldeps/issue-28766/foo.rs
diff --git a/src/test/run-make/issue-28766/main.rs b/src/test/run-make-fulldeps/issue-28766/main.rs
similarity index 100%
rename from src/test/run-make/issue-28766/main.rs
rename to src/test/run-make-fulldeps/issue-28766/main.rs
diff --git a/src/test/run-make/issue-30063/Makefile b/src/test/run-make-fulldeps/issue-30063/Makefile
similarity index 100%
rename from src/test/run-make/issue-30063/Makefile
rename to src/test/run-make-fulldeps/issue-30063/Makefile
diff --git a/src/test/run-make/issue-30063/foo.rs b/src/test/run-make-fulldeps/issue-30063/foo.rs
similarity index 100%
rename from src/test/run-make/issue-30063/foo.rs
rename to src/test/run-make-fulldeps/issue-30063/foo.rs
diff --git a/src/test/run-make/issue-33329/Makefile b/src/test/run-make-fulldeps/issue-33329/Makefile
similarity index 100%
rename from src/test/run-make/issue-33329/Makefile
rename to src/test/run-make-fulldeps/issue-33329/Makefile
diff --git a/src/test/run-make/issue-33329/main.rs b/src/test/run-make-fulldeps/issue-33329/main.rs
similarity index 100%
rename from src/test/run-make/issue-33329/main.rs
rename to src/test/run-make-fulldeps/issue-33329/main.rs
diff --git a/src/test/run-make/issue-35164/Makefile b/src/test/run-make-fulldeps/issue-35164/Makefile
similarity index 100%
rename from src/test/run-make/issue-35164/Makefile
rename to src/test/run-make-fulldeps/issue-35164/Makefile
diff --git a/src/test/run-make/issue-35164/main.rs b/src/test/run-make-fulldeps/issue-35164/main.rs
similarity index 100%
rename from src/test/run-make/issue-35164/main.rs
rename to src/test/run-make-fulldeps/issue-35164/main.rs
diff --git a/src/test/run-make/issue-35164/submodule/mod.rs b/src/test/run-make-fulldeps/issue-35164/submodule/mod.rs
similarity index 100%
rename from src/test/run-make/issue-35164/submodule/mod.rs
rename to src/test/run-make-fulldeps/issue-35164/submodule/mod.rs
diff --git a/src/test/run-make/issue-37839/Makefile b/src/test/run-make-fulldeps/issue-37839/Makefile
similarity index 100%
rename from src/test/run-make/issue-37839/Makefile
rename to src/test/run-make-fulldeps/issue-37839/Makefile
diff --git a/src/test/run-make/issue-37839/a.rs b/src/test/run-make-fulldeps/issue-37839/a.rs
similarity index 100%
rename from src/test/run-make/issue-37839/a.rs
rename to src/test/run-make-fulldeps/issue-37839/a.rs
diff --git a/src/test/run-make/issue-37839/b.rs b/src/test/run-make-fulldeps/issue-37839/b.rs
similarity index 100%
rename from src/test/run-make/issue-37839/b.rs
rename to src/test/run-make-fulldeps/issue-37839/b.rs
diff --git a/src/test/run-make/issue-37839/c.rs b/src/test/run-make-fulldeps/issue-37839/c.rs
similarity index 100%
rename from src/test/run-make/issue-37839/c.rs
rename to src/test/run-make-fulldeps/issue-37839/c.rs
diff --git a/src/test/run-make/issue-37893/Makefile b/src/test/run-make-fulldeps/issue-37893/Makefile
similarity index 100%
rename from src/test/run-make/issue-37893/Makefile
rename to src/test/run-make-fulldeps/issue-37893/Makefile
diff --git a/src/test/run-make/issue-37893/a.rs b/src/test/run-make-fulldeps/issue-37893/a.rs
similarity index 100%
rename from src/test/run-make/issue-37893/a.rs
rename to src/test/run-make-fulldeps/issue-37893/a.rs
diff --git a/src/test/run-make/issue-37893/b.rs b/src/test/run-make-fulldeps/issue-37893/b.rs
similarity index 100%
rename from src/test/run-make/issue-37893/b.rs
rename to src/test/run-make-fulldeps/issue-37893/b.rs
diff --git a/src/test/run-make/issue-37893/c.rs b/src/test/run-make-fulldeps/issue-37893/c.rs
similarity index 100%
rename from src/test/run-make/issue-37893/c.rs
rename to src/test/run-make-fulldeps/issue-37893/c.rs
diff --git a/src/test/run-make/issue-38237/Makefile b/src/test/run-make-fulldeps/issue-38237/Makefile
similarity index 100%
rename from src/test/run-make/issue-38237/Makefile
rename to src/test/run-make-fulldeps/issue-38237/Makefile
diff --git a/src/test/run-make/issue-38237/bar.rs b/src/test/run-make-fulldeps/issue-38237/bar.rs
similarity index 100%
rename from src/test/run-make/issue-38237/bar.rs
rename to src/test/run-make-fulldeps/issue-38237/bar.rs
diff --git a/src/test/run-make/issue-38237/baz.rs b/src/test/run-make-fulldeps/issue-38237/baz.rs
similarity index 100%
rename from src/test/run-make/issue-38237/baz.rs
rename to src/test/run-make-fulldeps/issue-38237/baz.rs
diff --git a/src/test/run-make/issue-38237/foo.rs b/src/test/run-make-fulldeps/issue-38237/foo.rs
similarity index 100%
rename from src/test/run-make/issue-38237/foo.rs
rename to src/test/run-make-fulldeps/issue-38237/foo.rs
diff --git a/src/test/run-make/issue-40535/Makefile b/src/test/run-make-fulldeps/issue-40535/Makefile
similarity index 100%
rename from src/test/run-make/issue-40535/Makefile
rename to src/test/run-make-fulldeps/issue-40535/Makefile
diff --git a/src/test/run-make/issue-40535/bar.rs b/src/test/run-make-fulldeps/issue-40535/bar.rs
similarity index 100%
rename from src/test/run-make/issue-40535/bar.rs
rename to src/test/run-make-fulldeps/issue-40535/bar.rs
diff --git a/src/test/run-make/issue-40535/baz.rs b/src/test/run-make-fulldeps/issue-40535/baz.rs
similarity index 100%
rename from src/test/run-make/issue-40535/baz.rs
rename to src/test/run-make-fulldeps/issue-40535/baz.rs
diff --git a/src/test/run-make/issue-40535/foo.rs b/src/test/run-make-fulldeps/issue-40535/foo.rs
similarity index 100%
rename from src/test/run-make/issue-40535/foo.rs
rename to src/test/run-make-fulldeps/issue-40535/foo.rs
diff --git a/src/test/run-make/issue-46239/Makefile b/src/test/run-make-fulldeps/issue-46239/Makefile
similarity index 100%
rename from src/test/run-make/issue-46239/Makefile
rename to src/test/run-make-fulldeps/issue-46239/Makefile
diff --git a/src/test/run-make/issue-46239/main.rs b/src/test/run-make-fulldeps/issue-46239/main.rs
similarity index 100%
rename from src/test/run-make/issue-46239/main.rs
rename to src/test/run-make-fulldeps/issue-46239/main.rs
diff --git a/src/test/run-make/issue-7349/Makefile b/src/test/run-make-fulldeps/issue-7349/Makefile
similarity index 100%
rename from src/test/run-make/issue-7349/Makefile
rename to src/test/run-make-fulldeps/issue-7349/Makefile
diff --git a/src/test/run-make/issue-7349/foo.rs b/src/test/run-make-fulldeps/issue-7349/foo.rs
similarity index 100%
rename from src/test/run-make/issue-7349/foo.rs
rename to src/test/run-make-fulldeps/issue-7349/foo.rs
diff --git a/src/test/run-make/issues-41478-43796/Makefile b/src/test/run-make-fulldeps/issues-41478-43796/Makefile
similarity index 100%
rename from src/test/run-make/issues-41478-43796/Makefile
rename to src/test/run-make-fulldeps/issues-41478-43796/Makefile
diff --git a/src/test/run-make/issues-41478-43796/a.rs b/src/test/run-make-fulldeps/issues-41478-43796/a.rs
similarity index 100%
rename from src/test/run-make/issues-41478-43796/a.rs
rename to src/test/run-make-fulldeps/issues-41478-43796/a.rs
diff --git a/src/test/run-make/libs-and-bins/Makefile b/src/test/run-make-fulldeps/libs-and-bins/Makefile
similarity index 100%
rename from src/test/run-make/libs-and-bins/Makefile
rename to src/test/run-make-fulldeps/libs-and-bins/Makefile
diff --git a/src/test/run-make/libs-and-bins/foo.rs b/src/test/run-make-fulldeps/libs-and-bins/foo.rs
similarity index 100%
rename from src/test/run-make/libs-and-bins/foo.rs
rename to src/test/run-make-fulldeps/libs-and-bins/foo.rs
diff --git a/src/test/run-make/libs-through-symlinks/Makefile b/src/test/run-make-fulldeps/libs-through-symlinks/Makefile
similarity index 100%
rename from src/test/run-make/libs-through-symlinks/Makefile
rename to src/test/run-make-fulldeps/libs-through-symlinks/Makefile
diff --git a/src/test/run-make/libs-through-symlinks/bar.rs b/src/test/run-make-fulldeps/libs-through-symlinks/bar.rs
similarity index 100%
rename from src/test/run-make/libs-through-symlinks/bar.rs
rename to src/test/run-make-fulldeps/libs-through-symlinks/bar.rs
diff --git a/src/test/run-make/libs-through-symlinks/foo.rs b/src/test/run-make-fulldeps/libs-through-symlinks/foo.rs
similarity index 100%
rename from src/test/run-make/libs-through-symlinks/foo.rs
rename to src/test/run-make-fulldeps/libs-through-symlinks/foo.rs
diff --git a/src/test/run-make/libtest-json/Makefile b/src/test/run-make-fulldeps/libtest-json/Makefile
similarity index 100%
rename from src/test/run-make/libtest-json/Makefile
rename to src/test/run-make-fulldeps/libtest-json/Makefile
diff --git a/src/test/run-make/libtest-json/f.rs b/src/test/run-make-fulldeps/libtest-json/f.rs
similarity index 100%
rename from src/test/run-make/libtest-json/f.rs
rename to src/test/run-make-fulldeps/libtest-json/f.rs
diff --git a/src/test/run-make/libtest-json/output.json b/src/test/run-make-fulldeps/libtest-json/output.json
similarity index 100%
rename from src/test/run-make/libtest-json/output.json
rename to src/test/run-make-fulldeps/libtest-json/output.json
diff --git a/src/test/run-make/libtest-json/validate_json.py b/src/test/run-make-fulldeps/libtest-json/validate_json.py
similarity index 100%
rename from src/test/run-make/libtest-json/validate_json.py
rename to src/test/run-make-fulldeps/libtest-json/validate_json.py
diff --git a/src/test/run-make/link-arg/Makefile b/src/test/run-make-fulldeps/link-arg/Makefile
similarity index 100%
rename from src/test/run-make/link-arg/Makefile
rename to src/test/run-make-fulldeps/link-arg/Makefile
diff --git a/src/test/run-make/link-arg/empty.rs b/src/test/run-make-fulldeps/link-arg/empty.rs
similarity index 100%
rename from src/test/run-make/link-arg/empty.rs
rename to src/test/run-make-fulldeps/link-arg/empty.rs
diff --git a/src/test/run-make/link-cfg/Makefile b/src/test/run-make-fulldeps/link-cfg/Makefile
similarity index 100%
rename from src/test/run-make/link-cfg/Makefile
rename to src/test/run-make-fulldeps/link-cfg/Makefile
diff --git a/src/test/run-make/link-cfg/dep-with-staticlib.rs b/src/test/run-make-fulldeps/link-cfg/dep-with-staticlib.rs
similarity index 100%
rename from src/test/run-make/link-cfg/dep-with-staticlib.rs
rename to src/test/run-make-fulldeps/link-cfg/dep-with-staticlib.rs
diff --git a/src/test/run-make/link-cfg/dep.rs b/src/test/run-make-fulldeps/link-cfg/dep.rs
similarity index 100%
rename from src/test/run-make/link-cfg/dep.rs
rename to src/test/run-make-fulldeps/link-cfg/dep.rs
diff --git a/src/test/run-make/link-cfg/no-deps.rs b/src/test/run-make-fulldeps/link-cfg/no-deps.rs
similarity index 100%
rename from src/test/run-make/link-cfg/no-deps.rs
rename to src/test/run-make-fulldeps/link-cfg/no-deps.rs
diff --git a/src/test/run-make/link-cfg/return1.c b/src/test/run-make-fulldeps/link-cfg/return1.c
similarity index 100%
rename from src/test/run-make/link-cfg/return1.c
rename to src/test/run-make-fulldeps/link-cfg/return1.c
diff --git a/src/test/run-make/link-cfg/return2.c b/src/test/run-make-fulldeps/link-cfg/return2.c
similarity index 100%
rename from src/test/run-make/link-cfg/return2.c
rename to src/test/run-make-fulldeps/link-cfg/return2.c
diff --git a/src/test/run-make/link-cfg/return3.c b/src/test/run-make-fulldeps/link-cfg/return3.c
similarity index 100%
rename from src/test/run-make/link-cfg/return3.c
rename to src/test/run-make-fulldeps/link-cfg/return3.c
diff --git a/src/test/run-make/link-cfg/with-deps.rs b/src/test/run-make-fulldeps/link-cfg/with-deps.rs
similarity index 100%
rename from src/test/run-make/link-cfg/with-deps.rs
rename to src/test/run-make-fulldeps/link-cfg/with-deps.rs
diff --git a/src/test/run-make/link-cfg/with-staticlib-deps.rs b/src/test/run-make-fulldeps/link-cfg/with-staticlib-deps.rs
similarity index 100%
rename from src/test/run-make/link-cfg/with-staticlib-deps.rs
rename to src/test/run-make-fulldeps/link-cfg/with-staticlib-deps.rs
diff --git a/src/test/run-make/link-path-order/Makefile b/src/test/run-make-fulldeps/link-path-order/Makefile
similarity index 100%
rename from src/test/run-make/link-path-order/Makefile
rename to src/test/run-make-fulldeps/link-path-order/Makefile
diff --git a/src/test/run-make/link-path-order/correct.c b/src/test/run-make-fulldeps/link-path-order/correct.c
similarity index 100%
rename from src/test/run-make/link-path-order/correct.c
rename to src/test/run-make-fulldeps/link-path-order/correct.c
diff --git a/src/test/run-make/link-path-order/main.rs b/src/test/run-make-fulldeps/link-path-order/main.rs
similarity index 100%
rename from src/test/run-make/link-path-order/main.rs
rename to src/test/run-make-fulldeps/link-path-order/main.rs
diff --git a/src/test/run-make/link-path-order/wrong.c b/src/test/run-make-fulldeps/link-path-order/wrong.c
similarity index 100%
rename from src/test/run-make/link-path-order/wrong.c
rename to src/test/run-make-fulldeps/link-path-order/wrong.c
diff --git a/src/test/run-make/linkage-attr-on-static/Makefile b/src/test/run-make-fulldeps/linkage-attr-on-static/Makefile
similarity index 100%
rename from src/test/run-make/linkage-attr-on-static/Makefile
rename to src/test/run-make-fulldeps/linkage-attr-on-static/Makefile
diff --git a/src/test/run-make/linkage-attr-on-static/bar.rs b/src/test/run-make-fulldeps/linkage-attr-on-static/bar.rs
similarity index 100%
rename from src/test/run-make/linkage-attr-on-static/bar.rs
rename to src/test/run-make-fulldeps/linkage-attr-on-static/bar.rs
diff --git a/src/test/run-make/linkage-attr-on-static/foo.c b/src/test/run-make-fulldeps/linkage-attr-on-static/foo.c
similarity index 100%
rename from src/test/run-make/linkage-attr-on-static/foo.c
rename to src/test/run-make-fulldeps/linkage-attr-on-static/foo.c
diff --git a/src/test/run-make/linker-output-non-utf8/Makefile b/src/test/run-make-fulldeps/linker-output-non-utf8/Makefile
similarity index 100%
rename from src/test/run-make/linker-output-non-utf8/Makefile
rename to src/test/run-make-fulldeps/linker-output-non-utf8/Makefile
diff --git a/src/test/run-make/linker-output-non-utf8/exec.rs b/src/test/run-make-fulldeps/linker-output-non-utf8/exec.rs
similarity index 100%
rename from src/test/run-make/linker-output-non-utf8/exec.rs
rename to src/test/run-make-fulldeps/linker-output-non-utf8/exec.rs
diff --git a/src/test/run-make/linker-output-non-utf8/library.rs b/src/test/run-make-fulldeps/linker-output-non-utf8/library.rs
similarity index 100%
rename from src/test/run-make/linker-output-non-utf8/library.rs
rename to src/test/run-make-fulldeps/linker-output-non-utf8/library.rs
diff --git a/src/test/run-make/llvm-pass/Makefile b/src/test/run-make-fulldeps/llvm-pass/Makefile
similarity index 100%
rename from src/test/run-make/llvm-pass/Makefile
rename to src/test/run-make-fulldeps/llvm-pass/Makefile
diff --git a/src/test/run-make/llvm-pass/llvm-function-pass.so.cc b/src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc
similarity index 100%
rename from src/test/run-make/llvm-pass/llvm-function-pass.so.cc
rename to src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc
diff --git a/src/test/run-make/llvm-pass/llvm-module-pass.so.cc b/src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc
similarity index 100%
rename from src/test/run-make/llvm-pass/llvm-module-pass.so.cc
rename to src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc
diff --git a/src/test/run-make/llvm-pass/main.rs b/src/test/run-make-fulldeps/llvm-pass/main.rs
similarity index 100%
rename from src/test/run-make/llvm-pass/main.rs
rename to src/test/run-make-fulldeps/llvm-pass/main.rs
diff --git a/src/test/run-make/llvm-pass/plugin.rs b/src/test/run-make-fulldeps/llvm-pass/plugin.rs
similarity index 100%
rename from src/test/run-make/llvm-pass/plugin.rs
rename to src/test/run-make-fulldeps/llvm-pass/plugin.rs
diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/Makefile b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile
similarity index 100%
rename from src/test/run-make/long-linker-command-lines-cmd-exe/Makefile
rename to src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile
diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.bat b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.bat
similarity index 100%
rename from src/test/run-make/long-linker-command-lines-cmd-exe/foo.bat
rename to src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.bat
diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.rs
similarity index 100%
rename from src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs
rename to src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.rs
diff --git a/src/test/run-make/long-linker-command-lines/Makefile b/src/test/run-make-fulldeps/long-linker-command-lines/Makefile
similarity index 100%
rename from src/test/run-make/long-linker-command-lines/Makefile
rename to src/test/run-make-fulldeps/long-linker-command-lines/Makefile
diff --git a/src/test/run-make/long-linker-command-lines/foo.rs b/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs
similarity index 100%
rename from src/test/run-make/long-linker-command-lines/foo.rs
rename to src/test/run-make-fulldeps/long-linker-command-lines/foo.rs
diff --git a/src/test/run-make/longjmp-across-rust/Makefile b/src/test/run-make-fulldeps/longjmp-across-rust/Makefile
similarity index 100%
rename from src/test/run-make/longjmp-across-rust/Makefile
rename to src/test/run-make-fulldeps/longjmp-across-rust/Makefile
diff --git a/src/test/run-make/longjmp-across-rust/foo.c b/src/test/run-make-fulldeps/longjmp-across-rust/foo.c
similarity index 100%
rename from src/test/run-make/longjmp-across-rust/foo.c
rename to src/test/run-make-fulldeps/longjmp-across-rust/foo.c
diff --git a/src/test/run-make/longjmp-across-rust/main.rs b/src/test/run-make-fulldeps/longjmp-across-rust/main.rs
similarity index 100%
rename from src/test/run-make/longjmp-across-rust/main.rs
rename to src/test/run-make-fulldeps/longjmp-across-rust/main.rs
diff --git a/src/test/run-make/ls-metadata/Makefile b/src/test/run-make-fulldeps/ls-metadata/Makefile
similarity index 100%
rename from src/test/run-make/ls-metadata/Makefile
rename to src/test/run-make-fulldeps/ls-metadata/Makefile
diff --git a/src/test/run-make/ls-metadata/foo.rs b/src/test/run-make-fulldeps/ls-metadata/foo.rs
similarity index 100%
rename from src/test/run-make/ls-metadata/foo.rs
rename to src/test/run-make-fulldeps/ls-metadata/foo.rs
diff --git a/src/test/run-make/lto-no-link-whole-rlib/Makefile b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile
similarity index 100%
rename from src/test/run-make/lto-no-link-whole-rlib/Makefile
rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile
diff --git a/src/test/run-make/lto-no-link-whole-rlib/bar.c b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/bar.c
similarity index 100%
rename from src/test/run-make/lto-no-link-whole-rlib/bar.c
rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/bar.c
diff --git a/src/test/run-make/lto-no-link-whole-rlib/foo.c b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/foo.c
similarity index 100%
rename from src/test/run-make/lto-no-link-whole-rlib/foo.c
rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/foo.c
diff --git a/src/test/run-make/lto-no-link-whole-rlib/lib1.rs b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib1.rs
similarity index 100%
rename from src/test/run-make/lto-no-link-whole-rlib/lib1.rs
rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib1.rs
diff --git a/src/test/run-make/lto-no-link-whole-rlib/lib2.rs b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs
similarity index 100%
rename from src/test/run-make/lto-no-link-whole-rlib/lib2.rs
rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs
diff --git a/src/test/run-make/lto-no-link-whole-rlib/main.rs b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/main.rs
similarity index 100%
rename from src/test/run-make/lto-no-link-whole-rlib/main.rs
rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/main.rs
diff --git a/src/test/run-make/lto-readonly-lib/Makefile b/src/test/run-make-fulldeps/lto-readonly-lib/Makefile
similarity index 100%
rename from src/test/run-make/lto-readonly-lib/Makefile
rename to src/test/run-make-fulldeps/lto-readonly-lib/Makefile
diff --git a/src/test/run-make/lto-readonly-lib/lib.rs b/src/test/run-make-fulldeps/lto-readonly-lib/lib.rs
similarity index 100%
rename from src/test/run-make/lto-readonly-lib/lib.rs
rename to src/test/run-make-fulldeps/lto-readonly-lib/lib.rs
diff --git a/src/test/run-make/lto-readonly-lib/main.rs b/src/test/run-make-fulldeps/lto-readonly-lib/main.rs
similarity index 100%
rename from src/test/run-make/lto-readonly-lib/main.rs
rename to src/test/run-make-fulldeps/lto-readonly-lib/main.rs
diff --git a/src/test/run-make/lto-smoke-c/Makefile b/src/test/run-make-fulldeps/lto-smoke-c/Makefile
similarity index 100%
rename from src/test/run-make/lto-smoke-c/Makefile
rename to src/test/run-make-fulldeps/lto-smoke-c/Makefile
diff --git a/src/test/run-make/lto-smoke-c/bar.c b/src/test/run-make-fulldeps/lto-smoke-c/bar.c
similarity index 100%
rename from src/test/run-make/lto-smoke-c/bar.c
rename to src/test/run-make-fulldeps/lto-smoke-c/bar.c
diff --git a/src/test/run-make/lto-smoke-c/foo.rs b/src/test/run-make-fulldeps/lto-smoke-c/foo.rs
similarity index 100%
rename from src/test/run-make/lto-smoke-c/foo.rs
rename to src/test/run-make-fulldeps/lto-smoke-c/foo.rs
diff --git a/src/test/run-make/lto-smoke/Makefile b/src/test/run-make-fulldeps/lto-smoke/Makefile
similarity index 100%
rename from src/test/run-make/lto-smoke/Makefile
rename to src/test/run-make-fulldeps/lto-smoke/Makefile
diff --git a/src/test/run-make/lto-smoke/lib.rs b/src/test/run-make-fulldeps/lto-smoke/lib.rs
similarity index 100%
rename from src/test/run-make/lto-smoke/lib.rs
rename to src/test/run-make-fulldeps/lto-smoke/lib.rs
diff --git a/src/test/run-make/lto-smoke/main.rs b/src/test/run-make-fulldeps/lto-smoke/main.rs
similarity index 100%
rename from src/test/run-make/lto-smoke/main.rs
rename to src/test/run-make-fulldeps/lto-smoke/main.rs
diff --git a/src/test/run-make/manual-crate-name/Makefile b/src/test/run-make-fulldeps/manual-crate-name/Makefile
similarity index 100%
rename from src/test/run-make/manual-crate-name/Makefile
rename to src/test/run-make-fulldeps/manual-crate-name/Makefile
diff --git a/src/test/run-make/manual-crate-name/bar.rs b/src/test/run-make-fulldeps/manual-crate-name/bar.rs
similarity index 100%
rename from src/test/run-make/manual-crate-name/bar.rs
rename to src/test/run-make-fulldeps/manual-crate-name/bar.rs
diff --git a/src/test/run-make/manual-link/Makefile b/src/test/run-make-fulldeps/manual-link/Makefile
similarity index 100%
rename from src/test/run-make/manual-link/Makefile
rename to src/test/run-make-fulldeps/manual-link/Makefile
diff --git a/src/test/run-make/manual-link/bar.c b/src/test/run-make-fulldeps/manual-link/bar.c
similarity index 100%
rename from src/test/run-make/manual-link/bar.c
rename to src/test/run-make-fulldeps/manual-link/bar.c
diff --git a/src/test/run-make/manual-link/foo.c b/src/test/run-make-fulldeps/manual-link/foo.c
similarity index 100%
rename from src/test/run-make/manual-link/foo.c
rename to src/test/run-make-fulldeps/manual-link/foo.c
diff --git a/src/test/run-make/manual-link/foo.rs b/src/test/run-make-fulldeps/manual-link/foo.rs
similarity index 100%
rename from src/test/run-make/manual-link/foo.rs
rename to src/test/run-make-fulldeps/manual-link/foo.rs
diff --git a/src/test/run-make/manual-link/main.rs b/src/test/run-make-fulldeps/manual-link/main.rs
similarity index 100%
rename from src/test/run-make/manual-link/main.rs
rename to src/test/run-make-fulldeps/manual-link/main.rs
diff --git a/src/test/run-make/many-crates-but-no-match/Makefile b/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile
similarity index 100%
rename from src/test/run-make/many-crates-but-no-match/Makefile
rename to src/test/run-make-fulldeps/many-crates-but-no-match/Makefile
diff --git a/src/test/run-make/many-crates-but-no-match/crateA1.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateA1.rs
similarity index 100%
rename from src/test/run-make/many-crates-but-no-match/crateA1.rs
rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateA1.rs
diff --git a/src/test/run-make/many-crates-but-no-match/crateA2.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateA2.rs
similarity index 100%
rename from src/test/run-make/many-crates-but-no-match/crateA2.rs
rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateA2.rs
diff --git a/src/test/run-make/many-crates-but-no-match/crateA3.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateA3.rs
similarity index 100%
rename from src/test/run-make/many-crates-but-no-match/crateA3.rs
rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateA3.rs
diff --git a/src/test/run-make/many-crates-but-no-match/crateB.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateB.rs
similarity index 100%
rename from src/test/run-make/many-crates-but-no-match/crateB.rs
rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateB.rs
diff --git a/src/test/run-make/many-crates-but-no-match/crateC.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateC.rs
similarity index 100%
rename from src/test/run-make/many-crates-but-no-match/crateC.rs
rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateC.rs
diff --git a/src/test/run-make/metadata-flag-frobs-symbols/Makefile b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile
similarity index 100%
rename from src/test/run-make/metadata-flag-frobs-symbols/Makefile
rename to src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile
diff --git a/src/test/run-make/metadata-flag-frobs-symbols/bar.rs b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/bar.rs
similarity index 100%
rename from src/test/run-make/metadata-flag-frobs-symbols/bar.rs
rename to src/test/run-make-fulldeps/metadata-flag-frobs-symbols/bar.rs
diff --git a/src/test/run-make/metadata-flag-frobs-symbols/foo.rs b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/foo.rs
similarity index 100%
rename from src/test/run-make/metadata-flag-frobs-symbols/foo.rs
rename to src/test/run-make-fulldeps/metadata-flag-frobs-symbols/foo.rs
diff --git a/src/test/run-make/min-global-align/Makefile b/src/test/run-make-fulldeps/min-global-align/Makefile
similarity index 100%
rename from src/test/run-make/min-global-align/Makefile
rename to src/test/run-make-fulldeps/min-global-align/Makefile
diff --git a/src/test/run-make/min-global-align/min_global_align.rs b/src/test/run-make-fulldeps/min-global-align/min_global_align.rs
similarity index 100%
rename from src/test/run-make/min-global-align/min_global_align.rs
rename to src/test/run-make-fulldeps/min-global-align/min_global_align.rs
diff --git a/src/test/run-make/mismatching-target-triples/Makefile b/src/test/run-make-fulldeps/mismatching-target-triples/Makefile
similarity index 100%
rename from src/test/run-make/mismatching-target-triples/Makefile
rename to src/test/run-make-fulldeps/mismatching-target-triples/Makefile
diff --git a/src/test/run-make/mismatching-target-triples/bar.rs b/src/test/run-make-fulldeps/mismatching-target-triples/bar.rs
similarity index 100%
rename from src/test/run-make/mismatching-target-triples/bar.rs
rename to src/test/run-make-fulldeps/mismatching-target-triples/bar.rs
diff --git a/src/test/run-make/mismatching-target-triples/foo.rs b/src/test/run-make-fulldeps/mismatching-target-triples/foo.rs
similarity index 100%
rename from src/test/run-make/mismatching-target-triples/foo.rs
rename to src/test/run-make-fulldeps/mismatching-target-triples/foo.rs
diff --git a/src/test/run-make/missing-crate-dependency/Makefile b/src/test/run-make-fulldeps/missing-crate-dependency/Makefile
similarity index 100%
rename from src/test/run-make/missing-crate-dependency/Makefile
rename to src/test/run-make-fulldeps/missing-crate-dependency/Makefile
diff --git a/src/test/run-make/missing-crate-dependency/crateA.rs b/src/test/run-make-fulldeps/missing-crate-dependency/crateA.rs
similarity index 100%
rename from src/test/run-make/missing-crate-dependency/crateA.rs
rename to src/test/run-make-fulldeps/missing-crate-dependency/crateA.rs
diff --git a/src/test/run-make/missing-crate-dependency/crateB.rs b/src/test/run-make-fulldeps/missing-crate-dependency/crateB.rs
similarity index 100%
rename from src/test/run-make/missing-crate-dependency/crateB.rs
rename to src/test/run-make-fulldeps/missing-crate-dependency/crateB.rs
diff --git a/src/test/run-make/missing-crate-dependency/crateC.rs b/src/test/run-make-fulldeps/missing-crate-dependency/crateC.rs
similarity index 100%
rename from src/test/run-make/missing-crate-dependency/crateC.rs
rename to src/test/run-make-fulldeps/missing-crate-dependency/crateC.rs
diff --git a/src/test/run-make/mixing-deps/Makefile b/src/test/run-make-fulldeps/mixing-deps/Makefile
similarity index 100%
rename from src/test/run-make/mixing-deps/Makefile
rename to src/test/run-make-fulldeps/mixing-deps/Makefile
diff --git a/src/test/run-make/mixing-deps/both.rs b/src/test/run-make-fulldeps/mixing-deps/both.rs
similarity index 100%
rename from src/test/run-make/mixing-deps/both.rs
rename to src/test/run-make-fulldeps/mixing-deps/both.rs
diff --git a/src/test/run-make/mixing-deps/dylib.rs b/src/test/run-make-fulldeps/mixing-deps/dylib.rs
similarity index 100%
rename from src/test/run-make/mixing-deps/dylib.rs
rename to src/test/run-make-fulldeps/mixing-deps/dylib.rs
diff --git a/src/test/run-make/mixing-deps/prog.rs b/src/test/run-make-fulldeps/mixing-deps/prog.rs
similarity index 100%
rename from src/test/run-make/mixing-deps/prog.rs
rename to src/test/run-make-fulldeps/mixing-deps/prog.rs
diff --git a/src/test/run-make/mixing-formats/Makefile b/src/test/run-make-fulldeps/mixing-formats/Makefile
similarity index 100%
rename from src/test/run-make/mixing-formats/Makefile
rename to src/test/run-make-fulldeps/mixing-formats/Makefile
diff --git a/src/test/run-make/mixing-formats/bar1.rs b/src/test/run-make-fulldeps/mixing-formats/bar1.rs
similarity index 100%
rename from src/test/run-make/mixing-formats/bar1.rs
rename to src/test/run-make-fulldeps/mixing-formats/bar1.rs
diff --git a/src/test/run-make/mixing-formats/bar2.rs b/src/test/run-make-fulldeps/mixing-formats/bar2.rs
similarity index 100%
rename from src/test/run-make/mixing-formats/bar2.rs
rename to src/test/run-make-fulldeps/mixing-formats/bar2.rs
diff --git a/src/test/run-make/mixing-formats/baz.rs b/src/test/run-make-fulldeps/mixing-formats/baz.rs
similarity index 100%
rename from src/test/run-make/mixing-formats/baz.rs
rename to src/test/run-make-fulldeps/mixing-formats/baz.rs
diff --git a/src/test/run-make/mixing-formats/baz2.rs b/src/test/run-make-fulldeps/mixing-formats/baz2.rs
similarity index 100%
rename from src/test/run-make/mixing-formats/baz2.rs
rename to src/test/run-make-fulldeps/mixing-formats/baz2.rs
diff --git a/src/test/run-make/mixing-formats/foo.rs b/src/test/run-make-fulldeps/mixing-formats/foo.rs
similarity index 100%
rename from src/test/run-make/mixing-formats/foo.rs
rename to src/test/run-make-fulldeps/mixing-formats/foo.rs
diff --git a/src/test/run-make/mixing-libs/Makefile b/src/test/run-make-fulldeps/mixing-libs/Makefile
similarity index 100%
rename from src/test/run-make/mixing-libs/Makefile
rename to src/test/run-make-fulldeps/mixing-libs/Makefile
diff --git a/src/test/run-make/mixing-libs/dylib.rs b/src/test/run-make-fulldeps/mixing-libs/dylib.rs
similarity index 100%
rename from src/test/run-make/mixing-libs/dylib.rs
rename to src/test/run-make-fulldeps/mixing-libs/dylib.rs
diff --git a/src/test/run-make/mixing-libs/prog.rs b/src/test/run-make-fulldeps/mixing-libs/prog.rs
similarity index 100%
rename from src/test/run-make/mixing-libs/prog.rs
rename to src/test/run-make-fulldeps/mixing-libs/prog.rs
diff --git a/src/test/run-make/mixing-libs/rlib.rs b/src/test/run-make-fulldeps/mixing-libs/rlib.rs
similarity index 100%
rename from src/test/run-make/mixing-libs/rlib.rs
rename to src/test/run-make-fulldeps/mixing-libs/rlib.rs
diff --git a/src/test/run-make/msvc-opt-minsize/Makefile b/src/test/run-make-fulldeps/msvc-opt-minsize/Makefile
similarity index 100%
rename from src/test/run-make/msvc-opt-minsize/Makefile
rename to src/test/run-make-fulldeps/msvc-opt-minsize/Makefile
diff --git a/src/test/run-make/msvc-opt-minsize/foo.rs b/src/test/run-make-fulldeps/msvc-opt-minsize/foo.rs
similarity index 100%
rename from src/test/run-make/msvc-opt-minsize/foo.rs
rename to src/test/run-make-fulldeps/msvc-opt-minsize/foo.rs
diff --git a/src/test/run-make/multiple-emits/Makefile b/src/test/run-make-fulldeps/multiple-emits/Makefile
similarity index 100%
rename from src/test/run-make/multiple-emits/Makefile
rename to src/test/run-make-fulldeps/multiple-emits/Makefile
diff --git a/src/test/run-make/multiple-emits/foo.rs b/src/test/run-make-fulldeps/multiple-emits/foo.rs
similarity index 100%
rename from src/test/run-make/multiple-emits/foo.rs
rename to src/test/run-make-fulldeps/multiple-emits/foo.rs
diff --git a/src/test/run-make/no-builtins-lto/Makefile b/src/test/run-make-fulldeps/no-builtins-lto/Makefile
similarity index 100%
rename from src/test/run-make/no-builtins-lto/Makefile
rename to src/test/run-make-fulldeps/no-builtins-lto/Makefile
diff --git a/src/test/run-make/no-builtins-lto/main.rs b/src/test/run-make-fulldeps/no-builtins-lto/main.rs
similarity index 100%
rename from src/test/run-make/no-builtins-lto/main.rs
rename to src/test/run-make-fulldeps/no-builtins-lto/main.rs
diff --git a/src/test/run-make/no-builtins-lto/no_builtins.rs b/src/test/run-make-fulldeps/no-builtins-lto/no_builtins.rs
similarity index 100%
rename from src/test/run-make/no-builtins-lto/no_builtins.rs
rename to src/test/run-make-fulldeps/no-builtins-lto/no_builtins.rs
diff --git a/src/test/run-make/no-duplicate-libs/Makefile b/src/test/run-make-fulldeps/no-duplicate-libs/Makefile
similarity index 100%
rename from src/test/run-make/no-duplicate-libs/Makefile
rename to src/test/run-make-fulldeps/no-duplicate-libs/Makefile
diff --git a/src/test/run-make/no-duplicate-libs/bar.c b/src/test/run-make-fulldeps/no-duplicate-libs/bar.c
similarity index 100%
rename from src/test/run-make/no-duplicate-libs/bar.c
rename to src/test/run-make-fulldeps/no-duplicate-libs/bar.c
diff --git a/src/test/run-make/no-duplicate-libs/foo.c b/src/test/run-make-fulldeps/no-duplicate-libs/foo.c
similarity index 100%
rename from src/test/run-make/no-duplicate-libs/foo.c
rename to src/test/run-make-fulldeps/no-duplicate-libs/foo.c
diff --git a/src/test/run-make/no-duplicate-libs/main.rs b/src/test/run-make-fulldeps/no-duplicate-libs/main.rs
similarity index 100%
rename from src/test/run-make/no-duplicate-libs/main.rs
rename to src/test/run-make-fulldeps/no-duplicate-libs/main.rs
diff --git a/src/test/run-make/no-integrated-as/Makefile b/src/test/run-make-fulldeps/no-integrated-as/Makefile
similarity index 100%
rename from src/test/run-make/no-integrated-as/Makefile
rename to src/test/run-make-fulldeps/no-integrated-as/Makefile
diff --git a/src/test/run-make/no-integrated-as/hello.rs b/src/test/run-make-fulldeps/no-integrated-as/hello.rs
similarity index 100%
rename from src/test/run-make/no-integrated-as/hello.rs
rename to src/test/run-make-fulldeps/no-integrated-as/hello.rs
diff --git a/src/test/run-make/no-intermediate-extras/Makefile b/src/test/run-make-fulldeps/no-intermediate-extras/Makefile
similarity index 100%
rename from src/test/run-make/no-intermediate-extras/Makefile
rename to src/test/run-make-fulldeps/no-intermediate-extras/Makefile
diff --git a/src/test/run-make/no-intermediate-extras/foo.rs b/src/test/run-make-fulldeps/no-intermediate-extras/foo.rs
similarity index 100%
rename from src/test/run-make/no-intermediate-extras/foo.rs
rename to src/test/run-make-fulldeps/no-intermediate-extras/foo.rs
diff --git a/src/test/run-make/obey-crate-type-flag/Makefile b/src/test/run-make-fulldeps/obey-crate-type-flag/Makefile
similarity index 100%
rename from src/test/run-make/obey-crate-type-flag/Makefile
rename to src/test/run-make-fulldeps/obey-crate-type-flag/Makefile
diff --git a/src/test/run-make/obey-crate-type-flag/test.rs b/src/test/run-make-fulldeps/obey-crate-type-flag/test.rs
similarity index 100%
rename from src/test/run-make/obey-crate-type-flag/test.rs
rename to src/test/run-make-fulldeps/obey-crate-type-flag/test.rs
diff --git a/src/test/run-make/output-filename-conflicts-with-directory/Makefile b/src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile
similarity index 100%
rename from src/test/run-make/output-filename-conflicts-with-directory/Makefile
rename to src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile
diff --git a/src/test/run-make/output-filename-conflicts-with-directory/foo.rs b/src/test/run-make-fulldeps/output-filename-conflicts-with-directory/foo.rs
similarity index 100%
rename from src/test/run-make/output-filename-conflicts-with-directory/foo.rs
rename to src/test/run-make-fulldeps/output-filename-conflicts-with-directory/foo.rs
diff --git a/src/test/run-make/output-filename-overwrites-input/Makefile b/src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile
similarity index 100%
rename from src/test/run-make/output-filename-overwrites-input/Makefile
rename to src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile
diff --git a/src/test/run-make/output-filename-overwrites-input/bar.rs b/src/test/run-make-fulldeps/output-filename-overwrites-input/bar.rs
similarity index 100%
rename from src/test/run-make/output-filename-overwrites-input/bar.rs
rename to src/test/run-make-fulldeps/output-filename-overwrites-input/bar.rs
diff --git a/src/test/run-make/output-filename-overwrites-input/foo.rs b/src/test/run-make-fulldeps/output-filename-overwrites-input/foo.rs
similarity index 100%
rename from src/test/run-make/output-filename-overwrites-input/foo.rs
rename to src/test/run-make-fulldeps/output-filename-overwrites-input/foo.rs
diff --git a/src/test/run-make/output-type-permutations/Makefile b/src/test/run-make-fulldeps/output-type-permutations/Makefile
similarity index 100%
rename from src/test/run-make/output-type-permutations/Makefile
rename to src/test/run-make-fulldeps/output-type-permutations/Makefile
diff --git a/src/test/run-make/output-type-permutations/foo.rs b/src/test/run-make-fulldeps/output-type-permutations/foo.rs
similarity index 100%
rename from src/test/run-make/output-type-permutations/foo.rs
rename to src/test/run-make-fulldeps/output-type-permutations/foo.rs
diff --git a/src/test/run-make/output-with-hyphens/Makefile b/src/test/run-make-fulldeps/output-with-hyphens/Makefile
similarity index 100%
rename from src/test/run-make/output-with-hyphens/Makefile
rename to src/test/run-make-fulldeps/output-with-hyphens/Makefile
diff --git a/src/test/run-make/output-with-hyphens/foo-bar.rs b/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs
similarity index 100%
rename from src/test/run-make/output-with-hyphens/foo-bar.rs
rename to src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs
diff --git a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
new file mode 100644
index 0000000000000..e8c695f52bec0
--- /dev/null
+++ b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
@@ -0,0 +1,8 @@
+-include ../tools.mk
+
+all:
+ifeq ($(PROFILER_SUPPORT),1)
+	$(RUSTC) -Copt-level=3 -Clto=fat -Z pgo-gen="$(TMPDIR)/test.profraw" test.rs
+	$(call RUN,test) || exit 1
+	[ -e "$(TMPDIR)/test.profraw" ] || (echo "No .profraw file"; exit 1)
+endif
diff --git a/src/test/compile-fail/feature-gate-termination_trait.rs b/src/test/run-make-fulldeps/pgo-gen-lto/test.rs
similarity index 74%
rename from src/test/compile-fail/feature-gate-termination_trait.rs
rename to src/test/run-make-fulldeps/pgo-gen-lto/test.rs
index 5a56445b64e57..3f07b46791d22 100644
--- a/src/test/compile-fail/feature-gate-termination_trait.rs
+++ b/src/test/run-make-fulldeps/pgo-gen-lto/test.rs
@@ -1,4 +1,4 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,6 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() -> i32 { //~ ERROR main function has wrong type [E0580]
-    0
-}
+fn main() {}
diff --git a/src/test/run-make-fulldeps/pgo-gen/Makefile b/src/test/run-make-fulldeps/pgo-gen/Makefile
new file mode 100644
index 0000000000000..7dc227b5a145a
--- /dev/null
+++ b/src/test/run-make-fulldeps/pgo-gen/Makefile
@@ -0,0 +1,8 @@
+-include ../tools.mk
+
+all:
+ifeq ($(PROFILER_SUPPORT),1)
+	$(RUSTC) -g -Z pgo-gen="$(TMPDIR)/test.profraw" test.rs
+	$(call RUN,test) || exit 1
+	[ -e "$(TMPDIR)/test.profraw" ] || (echo "No .profraw file"; exit 1)
+endif
diff --git a/src/test/run-make-fulldeps/pgo-gen/test.rs b/src/test/run-make-fulldeps/pgo-gen/test.rs
new file mode 100644
index 0000000000000..3f07b46791d22
--- /dev/null
+++ b/src/test/run-make-fulldeps/pgo-gen/test.rs
@@ -0,0 +1,11 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {}
diff --git a/src/test/run-make/prefer-dylib/Makefile b/src/test/run-make-fulldeps/prefer-dylib/Makefile
similarity index 100%
rename from src/test/run-make/prefer-dylib/Makefile
rename to src/test/run-make-fulldeps/prefer-dylib/Makefile
diff --git a/src/test/run-make/prefer-dylib/bar.rs b/src/test/run-make-fulldeps/prefer-dylib/bar.rs
similarity index 100%
rename from src/test/run-make/prefer-dylib/bar.rs
rename to src/test/run-make-fulldeps/prefer-dylib/bar.rs
diff --git a/src/test/run-make/prefer-dylib/foo.rs b/src/test/run-make-fulldeps/prefer-dylib/foo.rs
similarity index 100%
rename from src/test/run-make/prefer-dylib/foo.rs
rename to src/test/run-make-fulldeps/prefer-dylib/foo.rs
diff --git a/src/test/run-make/prefer-rlib/Makefile b/src/test/run-make-fulldeps/prefer-rlib/Makefile
similarity index 100%
rename from src/test/run-make/prefer-rlib/Makefile
rename to src/test/run-make-fulldeps/prefer-rlib/Makefile
diff --git a/src/test/run-make/prefer-rlib/bar.rs b/src/test/run-make-fulldeps/prefer-rlib/bar.rs
similarity index 100%
rename from src/test/run-make/prefer-rlib/bar.rs
rename to src/test/run-make-fulldeps/prefer-rlib/bar.rs
diff --git a/src/test/run-make/prefer-rlib/foo.rs b/src/test/run-make-fulldeps/prefer-rlib/foo.rs
similarity index 100%
rename from src/test/run-make/prefer-rlib/foo.rs
rename to src/test/run-make-fulldeps/prefer-rlib/foo.rs
diff --git a/src/test/run-make/pretty-expanded-hygiene/Makefile b/src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile
similarity index 100%
rename from src/test/run-make/pretty-expanded-hygiene/Makefile
rename to src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile
diff --git a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs b/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs
similarity index 100%
rename from src/test/run-make/pretty-expanded-hygiene/input.pp.rs
rename to src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs
diff --git a/src/test/run-make/pretty-expanded-hygiene/input.rs b/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs
similarity index 100%
rename from src/test/run-make/pretty-expanded-hygiene/input.rs
rename to src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs
diff --git a/src/test/run-make/pretty-expanded/Makefile b/src/test/run-make-fulldeps/pretty-expanded/Makefile
similarity index 100%
rename from src/test/run-make/pretty-expanded/Makefile
rename to src/test/run-make-fulldeps/pretty-expanded/Makefile
diff --git a/src/test/run-make/pretty-expanded/input.rs b/src/test/run-make-fulldeps/pretty-expanded/input.rs
similarity index 100%
rename from src/test/run-make/pretty-expanded/input.rs
rename to src/test/run-make-fulldeps/pretty-expanded/input.rs
diff --git a/src/test/run-make/pretty-print-path-suffix/Makefile b/src/test/run-make-fulldeps/pretty-print-path-suffix/Makefile
similarity index 100%
rename from src/test/run-make/pretty-print-path-suffix/Makefile
rename to src/test/run-make-fulldeps/pretty-print-path-suffix/Makefile
diff --git a/src/test/run-make/pretty-print-path-suffix/foo.pp b/src/test/run-make-fulldeps/pretty-print-path-suffix/foo.pp
similarity index 100%
rename from src/test/run-make/pretty-print-path-suffix/foo.pp
rename to src/test/run-make-fulldeps/pretty-print-path-suffix/foo.pp
diff --git a/src/test/run-make/pretty-print-path-suffix/foo_method.pp b/src/test/run-make-fulldeps/pretty-print-path-suffix/foo_method.pp
similarity index 100%
rename from src/test/run-make/pretty-print-path-suffix/foo_method.pp
rename to src/test/run-make-fulldeps/pretty-print-path-suffix/foo_method.pp
diff --git a/src/test/run-make/pretty-print-path-suffix/input.rs b/src/test/run-make-fulldeps/pretty-print-path-suffix/input.rs
similarity index 100%
rename from src/test/run-make/pretty-print-path-suffix/input.rs
rename to src/test/run-make-fulldeps/pretty-print-path-suffix/input.rs
diff --git a/src/test/run-make/pretty-print-path-suffix/nest_foo.pp b/src/test/run-make-fulldeps/pretty-print-path-suffix/nest_foo.pp
similarity index 100%
rename from src/test/run-make/pretty-print-path-suffix/nest_foo.pp
rename to src/test/run-make-fulldeps/pretty-print-path-suffix/nest_foo.pp
diff --git a/src/test/run-make/pretty-print-to-file/Makefile b/src/test/run-make-fulldeps/pretty-print-to-file/Makefile
similarity index 100%
rename from src/test/run-make/pretty-print-to-file/Makefile
rename to src/test/run-make-fulldeps/pretty-print-to-file/Makefile
diff --git a/src/test/run-make/pretty-print-to-file/input.pp b/src/test/run-make-fulldeps/pretty-print-to-file/input.pp
similarity index 100%
rename from src/test/run-make/pretty-print-to-file/input.pp
rename to src/test/run-make-fulldeps/pretty-print-to-file/input.pp
diff --git a/src/test/run-make/pretty-print-to-file/input.rs b/src/test/run-make-fulldeps/pretty-print-to-file/input.rs
similarity index 100%
rename from src/test/run-make/pretty-print-to-file/input.rs
rename to src/test/run-make-fulldeps/pretty-print-to-file/input.rs
diff --git a/src/test/run-make/print-cfg/Makefile b/src/test/run-make-fulldeps/print-cfg/Makefile
similarity index 100%
rename from src/test/run-make/print-cfg/Makefile
rename to src/test/run-make-fulldeps/print-cfg/Makefile
diff --git a/src/test/run-make/print-target-list/Makefile b/src/test/run-make-fulldeps/print-target-list/Makefile
similarity index 100%
rename from src/test/run-make/print-target-list/Makefile
rename to src/test/run-make-fulldeps/print-target-list/Makefile
diff --git a/src/test/run-make/profile/Makefile b/src/test/run-make-fulldeps/profile/Makefile
similarity index 100%
rename from src/test/run-make/profile/Makefile
rename to src/test/run-make-fulldeps/profile/Makefile
diff --git a/src/test/run-make/profile/test.rs b/src/test/run-make-fulldeps/profile/test.rs
similarity index 100%
rename from src/test/run-make/profile/test.rs
rename to src/test/run-make-fulldeps/profile/test.rs
diff --git a/src/test/run-make/prune-link-args/Makefile b/src/test/run-make-fulldeps/prune-link-args/Makefile
similarity index 100%
rename from src/test/run-make/prune-link-args/Makefile
rename to src/test/run-make-fulldeps/prune-link-args/Makefile
diff --git a/src/test/run-make/prune-link-args/empty.rs b/src/test/run-make-fulldeps/prune-link-args/empty.rs
similarity index 100%
rename from src/test/run-make/prune-link-args/empty.rs
rename to src/test/run-make-fulldeps/prune-link-args/empty.rs
diff --git a/src/test/run-make/relocation-model/Makefile b/src/test/run-make-fulldeps/relocation-model/Makefile
similarity index 100%
rename from src/test/run-make/relocation-model/Makefile
rename to src/test/run-make-fulldeps/relocation-model/Makefile
diff --git a/src/test/run-make/relocation-model/foo.rs b/src/test/run-make-fulldeps/relocation-model/foo.rs
similarity index 100%
rename from src/test/run-make/relocation-model/foo.rs
rename to src/test/run-make-fulldeps/relocation-model/foo.rs
diff --git a/src/test/run-make/relro-levels/Makefile b/src/test/run-make-fulldeps/relro-levels/Makefile
similarity index 100%
rename from src/test/run-make/relro-levels/Makefile
rename to src/test/run-make-fulldeps/relro-levels/Makefile
diff --git a/src/test/run-make/relro-levels/hello.rs b/src/test/run-make-fulldeps/relro-levels/hello.rs
similarity index 100%
rename from src/test/run-make/relro-levels/hello.rs
rename to src/test/run-make-fulldeps/relro-levels/hello.rs
diff --git a/src/test/run-make/reproducible-build/Makefile b/src/test/run-make-fulldeps/reproducible-build/Makefile
similarity index 100%
rename from src/test/run-make/reproducible-build/Makefile
rename to src/test/run-make-fulldeps/reproducible-build/Makefile
diff --git a/src/test/run-make/reproducible-build/linker.rs b/src/test/run-make-fulldeps/reproducible-build/linker.rs
similarity index 100%
rename from src/test/run-make/reproducible-build/linker.rs
rename to src/test/run-make-fulldeps/reproducible-build/linker.rs
diff --git a/src/test/run-make/reproducible-build/reproducible-build-aux.rs b/src/test/run-make-fulldeps/reproducible-build/reproducible-build-aux.rs
similarity index 100%
rename from src/test/run-make/reproducible-build/reproducible-build-aux.rs
rename to src/test/run-make-fulldeps/reproducible-build/reproducible-build-aux.rs
diff --git a/src/test/run-make/reproducible-build/reproducible-build.rs b/src/test/run-make-fulldeps/reproducible-build/reproducible-build.rs
similarity index 100%
rename from src/test/run-make/reproducible-build/reproducible-build.rs
rename to src/test/run-make-fulldeps/reproducible-build/reproducible-build.rs
diff --git a/src/test/run-make/rlib-chain/Makefile b/src/test/run-make-fulldeps/rlib-chain/Makefile
similarity index 100%
rename from src/test/run-make/rlib-chain/Makefile
rename to src/test/run-make-fulldeps/rlib-chain/Makefile
diff --git a/src/test/run-make/rlib-chain/m1.rs b/src/test/run-make-fulldeps/rlib-chain/m1.rs
similarity index 100%
rename from src/test/run-make/rlib-chain/m1.rs
rename to src/test/run-make-fulldeps/rlib-chain/m1.rs
diff --git a/src/test/run-make/rlib-chain/m2.rs b/src/test/run-make-fulldeps/rlib-chain/m2.rs
similarity index 100%
rename from src/test/run-make/rlib-chain/m2.rs
rename to src/test/run-make-fulldeps/rlib-chain/m2.rs
diff --git a/src/test/run-make/rlib-chain/m3.rs b/src/test/run-make-fulldeps/rlib-chain/m3.rs
similarity index 100%
rename from src/test/run-make/rlib-chain/m3.rs
rename to src/test/run-make-fulldeps/rlib-chain/m3.rs
diff --git a/src/test/run-make/rlib-chain/m4.rs b/src/test/run-make-fulldeps/rlib-chain/m4.rs
similarity index 100%
rename from src/test/run-make/rlib-chain/m4.rs
rename to src/test/run-make-fulldeps/rlib-chain/m4.rs
diff --git a/src/test/run-make/rustc-macro-dep-files/Makefile b/src/test/run-make-fulldeps/rustc-macro-dep-files/Makefile
similarity index 100%
rename from src/test/run-make/rustc-macro-dep-files/Makefile
rename to src/test/run-make-fulldeps/rustc-macro-dep-files/Makefile
diff --git a/src/test/run-make/rustc-macro-dep-files/bar.rs b/src/test/run-make-fulldeps/rustc-macro-dep-files/bar.rs
similarity index 100%
rename from src/test/run-make/rustc-macro-dep-files/bar.rs
rename to src/test/run-make-fulldeps/rustc-macro-dep-files/bar.rs
diff --git a/src/test/run-make/rustc-macro-dep-files/foo.rs b/src/test/run-make-fulldeps/rustc-macro-dep-files/foo.rs
similarity index 100%
rename from src/test/run-make/rustc-macro-dep-files/foo.rs
rename to src/test/run-make-fulldeps/rustc-macro-dep-files/foo.rs
diff --git a/src/test/run-make/rustdoc-error-lines/Makefile b/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile
similarity index 100%
rename from src/test/run-make/rustdoc-error-lines/Makefile
rename to src/test/run-make-fulldeps/rustdoc-error-lines/Makefile
diff --git a/src/test/run-make/rustdoc-error-lines/input.rs b/src/test/run-make-fulldeps/rustdoc-error-lines/input.rs
similarity index 100%
rename from src/test/run-make/rustdoc-error-lines/input.rs
rename to src/test/run-make-fulldeps/rustdoc-error-lines/input.rs
diff --git a/src/test/run-make/rustdoc-output-path/Makefile b/src/test/run-make-fulldeps/rustdoc-output-path/Makefile
similarity index 100%
rename from src/test/run-make/rustdoc-output-path/Makefile
rename to src/test/run-make-fulldeps/rustdoc-output-path/Makefile
diff --git a/src/test/run-make/rustdoc-output-path/foo.rs b/src/test/run-make-fulldeps/rustdoc-output-path/foo.rs
similarity index 100%
rename from src/test/run-make/rustdoc-output-path/foo.rs
rename to src/test/run-make-fulldeps/rustdoc-output-path/foo.rs
diff --git a/src/test/run-make/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile
similarity index 100%
rename from src/test/run-make/sanitizer-address/Makefile
rename to src/test/run-make-fulldeps/sanitizer-address/Makefile
diff --git a/src/test/run-make/sanitizer-address/overflow.rs b/src/test/run-make-fulldeps/sanitizer-address/overflow.rs
similarity index 100%
rename from src/test/run-make/sanitizer-address/overflow.rs
rename to src/test/run-make-fulldeps/sanitizer-address/overflow.rs
diff --git a/src/test/run-make/sanitizer-cdylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile
similarity index 100%
rename from src/test/run-make/sanitizer-cdylib-link/Makefile
rename to src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile
diff --git a/src/test/run-make/sanitizer-cdylib-link/library.rs b/src/test/run-make-fulldeps/sanitizer-cdylib-link/library.rs
similarity index 100%
rename from src/test/run-make/sanitizer-cdylib-link/library.rs
rename to src/test/run-make-fulldeps/sanitizer-cdylib-link/library.rs
diff --git a/src/test/run-make/sanitizer-cdylib-link/program.rs b/src/test/run-make-fulldeps/sanitizer-cdylib-link/program.rs
similarity index 100%
rename from src/test/run-make/sanitizer-cdylib-link/program.rs
rename to src/test/run-make-fulldeps/sanitizer-cdylib-link/program.rs
diff --git a/src/test/run-make/sanitizer-dylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile
similarity index 100%
rename from src/test/run-make/sanitizer-dylib-link/Makefile
rename to src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile
diff --git a/src/test/run-make/sanitizer-dylib-link/library.rs b/src/test/run-make-fulldeps/sanitizer-dylib-link/library.rs
similarity index 100%
rename from src/test/run-make/sanitizer-dylib-link/library.rs
rename to src/test/run-make-fulldeps/sanitizer-dylib-link/library.rs
diff --git a/src/test/run-make/sanitizer-dylib-link/program.rs b/src/test/run-make-fulldeps/sanitizer-dylib-link/program.rs
similarity index 100%
rename from src/test/run-make/sanitizer-dylib-link/program.rs
rename to src/test/run-make-fulldeps/sanitizer-dylib-link/program.rs
diff --git a/src/test/run-make/sanitizer-invalid-cratetype/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile
similarity index 100%
rename from src/test/run-make/sanitizer-invalid-cratetype/Makefile
rename to src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile
diff --git a/src/test/run-make/sanitizer-invalid-cratetype/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/hello.rs
similarity index 100%
rename from src/test/run-make/sanitizer-invalid-cratetype/hello.rs
rename to src/test/run-make-fulldeps/sanitizer-invalid-cratetype/hello.rs
diff --git a/src/test/run-make/sanitizer-invalid-target/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile
similarity index 100%
rename from src/test/run-make/sanitizer-invalid-target/Makefile
rename to src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile
diff --git a/src/test/run-make/sanitizer-invalid-target/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs
similarity index 100%
rename from src/test/run-make/sanitizer-invalid-target/hello.rs
rename to src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs
diff --git a/src/test/run-make/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile
similarity index 100%
rename from src/test/run-make/sanitizer-leak/Makefile
rename to src/test/run-make-fulldeps/sanitizer-leak/Makefile
diff --git a/src/test/run-make/sanitizer-leak/leak.rs b/src/test/run-make-fulldeps/sanitizer-leak/leak.rs
similarity index 100%
rename from src/test/run-make/sanitizer-leak/leak.rs
rename to src/test/run-make-fulldeps/sanitizer-leak/leak.rs
diff --git a/src/test/run-make/sanitizer-memory/Makefile b/src/test/run-make-fulldeps/sanitizer-memory/Makefile
similarity index 100%
rename from src/test/run-make/sanitizer-memory/Makefile
rename to src/test/run-make-fulldeps/sanitizer-memory/Makefile
diff --git a/src/test/run-make/sanitizer-memory/uninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs
similarity index 100%
rename from src/test/run-make/sanitizer-memory/uninit.rs
rename to src/test/run-make-fulldeps/sanitizer-memory/uninit.rs
diff --git a/src/test/run-make/sanitizer-staticlib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile
similarity index 100%
rename from src/test/run-make/sanitizer-staticlib-link/Makefile
rename to src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile
diff --git a/src/test/run-make/sanitizer-staticlib-link/library.rs b/src/test/run-make-fulldeps/sanitizer-staticlib-link/library.rs
similarity index 100%
rename from src/test/run-make/sanitizer-staticlib-link/library.rs
rename to src/test/run-make-fulldeps/sanitizer-staticlib-link/library.rs
diff --git a/src/test/run-make/sanitizer-staticlib-link/program.c b/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c
similarity index 100%
rename from src/test/run-make/sanitizer-staticlib-link/program.c
rename to src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c
diff --git a/src/test/run-make/save-analysis-fail/Makefile b/src/test/run-make-fulldeps/save-analysis-fail/Makefile
similarity index 100%
rename from src/test/run-make/save-analysis-fail/Makefile
rename to src/test/run-make-fulldeps/save-analysis-fail/Makefile
diff --git a/src/test/run-make/save-analysis-fail/SameDir.rs b/src/test/run-make-fulldeps/save-analysis-fail/SameDir.rs
similarity index 100%
rename from src/test/run-make/save-analysis-fail/SameDir.rs
rename to src/test/run-make-fulldeps/save-analysis-fail/SameDir.rs
diff --git a/src/test/run-make/save-analysis-fail/SameDir3.rs b/src/test/run-make-fulldeps/save-analysis-fail/SameDir3.rs
similarity index 100%
rename from src/test/run-make/save-analysis-fail/SameDir3.rs
rename to src/test/run-make-fulldeps/save-analysis-fail/SameDir3.rs
diff --git a/src/test/run-make/save-analysis-fail/SubDir/mod.rs b/src/test/run-make-fulldeps/save-analysis-fail/SubDir/mod.rs
similarity index 100%
rename from src/test/run-make/save-analysis-fail/SubDir/mod.rs
rename to src/test/run-make-fulldeps/save-analysis-fail/SubDir/mod.rs
diff --git a/src/test/run-make/save-analysis-fail/foo.rs b/src/test/run-make-fulldeps/save-analysis-fail/foo.rs
similarity index 100%
rename from src/test/run-make/save-analysis-fail/foo.rs
rename to src/test/run-make-fulldeps/save-analysis-fail/foo.rs
diff --git a/src/test/run-make/save-analysis-fail/krate2.rs b/src/test/run-make-fulldeps/save-analysis-fail/krate2.rs
similarity index 100%
rename from src/test/run-make/save-analysis-fail/krate2.rs
rename to src/test/run-make-fulldeps/save-analysis-fail/krate2.rs
diff --git a/src/test/run-make/save-analysis/Makefile b/src/test/run-make-fulldeps/save-analysis/Makefile
similarity index 100%
rename from src/test/run-make/save-analysis/Makefile
rename to src/test/run-make-fulldeps/save-analysis/Makefile
diff --git a/src/test/run-make/save-analysis/SameDir.rs b/src/test/run-make-fulldeps/save-analysis/SameDir.rs
similarity index 100%
rename from src/test/run-make/save-analysis/SameDir.rs
rename to src/test/run-make-fulldeps/save-analysis/SameDir.rs
diff --git a/src/test/run-make/save-analysis/SameDir3.rs b/src/test/run-make-fulldeps/save-analysis/SameDir3.rs
similarity index 100%
rename from src/test/run-make/save-analysis/SameDir3.rs
rename to src/test/run-make-fulldeps/save-analysis/SameDir3.rs
diff --git a/src/test/run-make/save-analysis/SubDir/mod.rs b/src/test/run-make-fulldeps/save-analysis/SubDir/mod.rs
similarity index 100%
rename from src/test/run-make/save-analysis/SubDir/mod.rs
rename to src/test/run-make-fulldeps/save-analysis/SubDir/mod.rs
diff --git a/src/test/run-make/save-analysis/extra-docs.md b/src/test/run-make-fulldeps/save-analysis/extra-docs.md
similarity index 100%
rename from src/test/run-make/save-analysis/extra-docs.md
rename to src/test/run-make-fulldeps/save-analysis/extra-docs.md
diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make-fulldeps/save-analysis/foo.rs
similarity index 100%
rename from src/test/run-make/save-analysis/foo.rs
rename to src/test/run-make-fulldeps/save-analysis/foo.rs
diff --git a/src/test/run-make/save-analysis/krate2.rs b/src/test/run-make-fulldeps/save-analysis/krate2.rs
similarity index 100%
rename from src/test/run-make/save-analysis/krate2.rs
rename to src/test/run-make-fulldeps/save-analysis/krate2.rs
diff --git a/src/test/run-make/sepcomp-cci-copies/Makefile b/src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile
similarity index 100%
rename from src/test/run-make/sepcomp-cci-copies/Makefile
rename to src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile
diff --git a/src/test/run-make/sepcomp-cci-copies/cci_lib.rs b/src/test/run-make-fulldeps/sepcomp-cci-copies/cci_lib.rs
similarity index 100%
rename from src/test/run-make/sepcomp-cci-copies/cci_lib.rs
rename to src/test/run-make-fulldeps/sepcomp-cci-copies/cci_lib.rs
diff --git a/src/test/run-make/sepcomp-cci-copies/foo.rs b/src/test/run-make-fulldeps/sepcomp-cci-copies/foo.rs
similarity index 100%
rename from src/test/run-make/sepcomp-cci-copies/foo.rs
rename to src/test/run-make-fulldeps/sepcomp-cci-copies/foo.rs
diff --git a/src/test/run-make/sepcomp-inlining/Makefile b/src/test/run-make-fulldeps/sepcomp-inlining/Makefile
similarity index 100%
rename from src/test/run-make/sepcomp-inlining/Makefile
rename to src/test/run-make-fulldeps/sepcomp-inlining/Makefile
diff --git a/src/test/run-make/sepcomp-inlining/foo.rs b/src/test/run-make-fulldeps/sepcomp-inlining/foo.rs
similarity index 100%
rename from src/test/run-make/sepcomp-inlining/foo.rs
rename to src/test/run-make-fulldeps/sepcomp-inlining/foo.rs
diff --git a/src/test/run-make/sepcomp-separate/Makefile b/src/test/run-make-fulldeps/sepcomp-separate/Makefile
similarity index 100%
rename from src/test/run-make/sepcomp-separate/Makefile
rename to src/test/run-make-fulldeps/sepcomp-separate/Makefile
diff --git a/src/test/run-make/sepcomp-separate/foo.rs b/src/test/run-make-fulldeps/sepcomp-separate/foo.rs
similarity index 100%
rename from src/test/run-make/sepcomp-separate/foo.rs
rename to src/test/run-make-fulldeps/sepcomp-separate/foo.rs
diff --git a/src/test/run-make/simd-ffi/Makefile b/src/test/run-make-fulldeps/simd-ffi/Makefile
similarity index 100%
rename from src/test/run-make/simd-ffi/Makefile
rename to src/test/run-make-fulldeps/simd-ffi/Makefile
diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make-fulldeps/simd-ffi/simd.rs
similarity index 100%
rename from src/test/run-make/simd-ffi/simd.rs
rename to src/test/run-make-fulldeps/simd-ffi/simd.rs
diff --git a/src/test/run-make/simple-dylib/Makefile b/src/test/run-make-fulldeps/simple-dylib/Makefile
similarity index 100%
rename from src/test/run-make/simple-dylib/Makefile
rename to src/test/run-make-fulldeps/simple-dylib/Makefile
diff --git a/src/test/run-make/simple-dylib/bar.rs b/src/test/run-make-fulldeps/simple-dylib/bar.rs
similarity index 100%
rename from src/test/run-make/simple-dylib/bar.rs
rename to src/test/run-make-fulldeps/simple-dylib/bar.rs
diff --git a/src/test/run-make/simple-dylib/foo.rs b/src/test/run-make-fulldeps/simple-dylib/foo.rs
similarity index 100%
rename from src/test/run-make/simple-dylib/foo.rs
rename to src/test/run-make-fulldeps/simple-dylib/foo.rs
diff --git a/src/test/run-make/simple-rlib/Makefile b/src/test/run-make-fulldeps/simple-rlib/Makefile
similarity index 100%
rename from src/test/run-make/simple-rlib/Makefile
rename to src/test/run-make-fulldeps/simple-rlib/Makefile
diff --git a/src/test/run-make/simple-rlib/bar.rs b/src/test/run-make-fulldeps/simple-rlib/bar.rs
similarity index 100%
rename from src/test/run-make/simple-rlib/bar.rs
rename to src/test/run-make-fulldeps/simple-rlib/bar.rs
diff --git a/src/test/run-make/simple-rlib/foo.rs b/src/test/run-make-fulldeps/simple-rlib/foo.rs
similarity index 100%
rename from src/test/run-make/simple-rlib/foo.rs
rename to src/test/run-make-fulldeps/simple-rlib/foo.rs
diff --git a/src/test/run-make/stable-symbol-names/Makefile b/src/test/run-make-fulldeps/stable-symbol-names/Makefile
similarity index 100%
rename from src/test/run-make/stable-symbol-names/Makefile
rename to src/test/run-make-fulldeps/stable-symbol-names/Makefile
diff --git a/src/test/run-make/stable-symbol-names/stable-symbol-names1.rs b/src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names1.rs
similarity index 100%
rename from src/test/run-make/stable-symbol-names/stable-symbol-names1.rs
rename to src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names1.rs
diff --git a/src/test/run-make/stable-symbol-names/stable-symbol-names2.rs b/src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs
similarity index 100%
rename from src/test/run-make/stable-symbol-names/stable-symbol-names2.rs
rename to src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs
diff --git a/src/test/run-make/static-dylib-by-default/Makefile b/src/test/run-make-fulldeps/static-dylib-by-default/Makefile
similarity index 100%
rename from src/test/run-make/static-dylib-by-default/Makefile
rename to src/test/run-make-fulldeps/static-dylib-by-default/Makefile
diff --git a/src/test/run-make/static-dylib-by-default/bar.rs b/src/test/run-make-fulldeps/static-dylib-by-default/bar.rs
similarity index 100%
rename from src/test/run-make/static-dylib-by-default/bar.rs
rename to src/test/run-make-fulldeps/static-dylib-by-default/bar.rs
diff --git a/src/test/run-make/static-dylib-by-default/foo.rs b/src/test/run-make-fulldeps/static-dylib-by-default/foo.rs
similarity index 100%
rename from src/test/run-make/static-dylib-by-default/foo.rs
rename to src/test/run-make-fulldeps/static-dylib-by-default/foo.rs
diff --git a/src/test/run-make/static-dylib-by-default/main.c b/src/test/run-make-fulldeps/static-dylib-by-default/main.c
similarity index 100%
rename from src/test/run-make/static-dylib-by-default/main.c
rename to src/test/run-make-fulldeps/static-dylib-by-default/main.c
diff --git a/src/test/run-make/static-nobundle/Makefile b/src/test/run-make-fulldeps/static-nobundle/Makefile
similarity index 100%
rename from src/test/run-make/static-nobundle/Makefile
rename to src/test/run-make-fulldeps/static-nobundle/Makefile
diff --git a/src/test/run-make/static-nobundle/aaa.c b/src/test/run-make-fulldeps/static-nobundle/aaa.c
similarity index 100%
rename from src/test/run-make/static-nobundle/aaa.c
rename to src/test/run-make-fulldeps/static-nobundle/aaa.c
diff --git a/src/test/run-make/static-nobundle/bbb.rs b/src/test/run-make-fulldeps/static-nobundle/bbb.rs
similarity index 100%
rename from src/test/run-make/static-nobundle/bbb.rs
rename to src/test/run-make-fulldeps/static-nobundle/bbb.rs
diff --git a/src/test/run-make/static-nobundle/ccc.rs b/src/test/run-make-fulldeps/static-nobundle/ccc.rs
similarity index 100%
rename from src/test/run-make/static-nobundle/ccc.rs
rename to src/test/run-make-fulldeps/static-nobundle/ccc.rs
diff --git a/src/test/run-make/static-nobundle/ddd.rs b/src/test/run-make-fulldeps/static-nobundle/ddd.rs
similarity index 100%
rename from src/test/run-make/static-nobundle/ddd.rs
rename to src/test/run-make-fulldeps/static-nobundle/ddd.rs
diff --git a/src/test/run-make/static-unwinding/Makefile b/src/test/run-make-fulldeps/static-unwinding/Makefile
similarity index 100%
rename from src/test/run-make/static-unwinding/Makefile
rename to src/test/run-make-fulldeps/static-unwinding/Makefile
diff --git a/src/test/run-make/static-unwinding/lib.rs b/src/test/run-make-fulldeps/static-unwinding/lib.rs
similarity index 100%
rename from src/test/run-make/static-unwinding/lib.rs
rename to src/test/run-make-fulldeps/static-unwinding/lib.rs
diff --git a/src/test/run-make/static-unwinding/main.rs b/src/test/run-make-fulldeps/static-unwinding/main.rs
similarity index 100%
rename from src/test/run-make/static-unwinding/main.rs
rename to src/test/run-make-fulldeps/static-unwinding/main.rs
diff --git a/src/test/run-make/staticlib-blank-lib/Makefile b/src/test/run-make-fulldeps/staticlib-blank-lib/Makefile
similarity index 100%
rename from src/test/run-make/staticlib-blank-lib/Makefile
rename to src/test/run-make-fulldeps/staticlib-blank-lib/Makefile
diff --git a/src/test/run-make/staticlib-blank-lib/foo.rs b/src/test/run-make-fulldeps/staticlib-blank-lib/foo.rs
similarity index 100%
rename from src/test/run-make/staticlib-blank-lib/foo.rs
rename to src/test/run-make-fulldeps/staticlib-blank-lib/foo.rs
diff --git a/src/test/run-make/stdin-non-utf8/Makefile b/src/test/run-make-fulldeps/stdin-non-utf8/Makefile
similarity index 100%
rename from src/test/run-make/stdin-non-utf8/Makefile
rename to src/test/run-make-fulldeps/stdin-non-utf8/Makefile
diff --git a/src/test/run-make/stdin-non-utf8/non-utf8 b/src/test/run-make-fulldeps/stdin-non-utf8/non-utf8
similarity index 100%
rename from src/test/run-make/stdin-non-utf8/non-utf8
rename to src/test/run-make-fulldeps/stdin-non-utf8/non-utf8
diff --git a/src/test/run-make/suspicious-library/Makefile b/src/test/run-make-fulldeps/suspicious-library/Makefile
similarity index 100%
rename from src/test/run-make/suspicious-library/Makefile
rename to src/test/run-make-fulldeps/suspicious-library/Makefile
diff --git a/src/test/run-make/suspicious-library/bar.rs b/src/test/run-make-fulldeps/suspicious-library/bar.rs
similarity index 100%
rename from src/test/run-make/suspicious-library/bar.rs
rename to src/test/run-make-fulldeps/suspicious-library/bar.rs
diff --git a/src/test/run-make/suspicious-library/foo.rs b/src/test/run-make-fulldeps/suspicious-library/foo.rs
similarity index 100%
rename from src/test/run-make/suspicious-library/foo.rs
rename to src/test/run-make-fulldeps/suspicious-library/foo.rs
diff --git a/src/test/run-make/symbol-visibility/Makefile b/src/test/run-make-fulldeps/symbol-visibility/Makefile
similarity index 100%
rename from src/test/run-make/symbol-visibility/Makefile
rename to src/test/run-make-fulldeps/symbol-visibility/Makefile
diff --git a/src/test/run-make/symbol-visibility/a_cdylib.rs b/src/test/run-make-fulldeps/symbol-visibility/a_cdylib.rs
similarity index 100%
rename from src/test/run-make/symbol-visibility/a_cdylib.rs
rename to src/test/run-make-fulldeps/symbol-visibility/a_cdylib.rs
diff --git a/src/test/run-make/symbol-visibility/a_rust_dylib.rs b/src/test/run-make-fulldeps/symbol-visibility/a_rust_dylib.rs
similarity index 100%
rename from src/test/run-make/symbol-visibility/a_rust_dylib.rs
rename to src/test/run-make-fulldeps/symbol-visibility/a_rust_dylib.rs
diff --git a/src/test/run-make/symbol-visibility/an_executable.rs b/src/test/run-make-fulldeps/symbol-visibility/an_executable.rs
similarity index 100%
rename from src/test/run-make/symbol-visibility/an_executable.rs
rename to src/test/run-make-fulldeps/symbol-visibility/an_executable.rs
diff --git a/src/test/run-make/symbol-visibility/an_rlib.rs b/src/test/run-make-fulldeps/symbol-visibility/an_rlib.rs
similarity index 100%
rename from src/test/run-make/symbol-visibility/an_rlib.rs
rename to src/test/run-make-fulldeps/symbol-visibility/an_rlib.rs
diff --git a/src/test/run-make/symbols-are-reasonable/Makefile b/src/test/run-make-fulldeps/symbols-are-reasonable/Makefile
similarity index 100%
rename from src/test/run-make/symbols-are-reasonable/Makefile
rename to src/test/run-make-fulldeps/symbols-are-reasonable/Makefile
diff --git a/src/test/run-make/symbols-are-reasonable/lib.rs b/src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs
similarity index 100%
rename from src/test/run-make/symbols-are-reasonable/lib.rs
rename to src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs
diff --git a/src/test/run-make/symbols-include-type-name/Makefile b/src/test/run-make-fulldeps/symbols-include-type-name/Makefile
similarity index 100%
rename from src/test/run-make/symbols-include-type-name/Makefile
rename to src/test/run-make-fulldeps/symbols-include-type-name/Makefile
diff --git a/src/test/run-make/symbols-include-type-name/lib.rs b/src/test/run-make-fulldeps/symbols-include-type-name/lib.rs
similarity index 100%
rename from src/test/run-make/symbols-include-type-name/lib.rs
rename to src/test/run-make-fulldeps/symbols-include-type-name/lib.rs
diff --git a/src/test/run-make/symlinked-extern/Makefile b/src/test/run-make-fulldeps/symlinked-extern/Makefile
similarity index 100%
rename from src/test/run-make/symlinked-extern/Makefile
rename to src/test/run-make-fulldeps/symlinked-extern/Makefile
diff --git a/src/test/run-make/symlinked-extern/bar.rs b/src/test/run-make-fulldeps/symlinked-extern/bar.rs
similarity index 100%
rename from src/test/run-make/symlinked-extern/bar.rs
rename to src/test/run-make-fulldeps/symlinked-extern/bar.rs
diff --git a/src/test/run-make/symlinked-extern/baz.rs b/src/test/run-make-fulldeps/symlinked-extern/baz.rs
similarity index 100%
rename from src/test/run-make/symlinked-extern/baz.rs
rename to src/test/run-make-fulldeps/symlinked-extern/baz.rs
diff --git a/src/test/run-make/symlinked-extern/foo.rs b/src/test/run-make-fulldeps/symlinked-extern/foo.rs
similarity index 100%
rename from src/test/run-make/symlinked-extern/foo.rs
rename to src/test/run-make-fulldeps/symlinked-extern/foo.rs
diff --git a/src/test/run-make/symlinked-libraries/Makefile b/src/test/run-make-fulldeps/symlinked-libraries/Makefile
similarity index 100%
rename from src/test/run-make/symlinked-libraries/Makefile
rename to src/test/run-make-fulldeps/symlinked-libraries/Makefile
diff --git a/src/test/run-make/symlinked-libraries/bar.rs b/src/test/run-make-fulldeps/symlinked-libraries/bar.rs
similarity index 100%
rename from src/test/run-make/symlinked-libraries/bar.rs
rename to src/test/run-make-fulldeps/symlinked-libraries/bar.rs
diff --git a/src/test/run-make/symlinked-libraries/foo.rs b/src/test/run-make-fulldeps/symlinked-libraries/foo.rs
similarity index 100%
rename from src/test/run-make/symlinked-libraries/foo.rs
rename to src/test/run-make-fulldeps/symlinked-libraries/foo.rs
diff --git a/src/test/run-make/symlinked-rlib/Makefile b/src/test/run-make-fulldeps/symlinked-rlib/Makefile
similarity index 100%
rename from src/test/run-make/symlinked-rlib/Makefile
rename to src/test/run-make-fulldeps/symlinked-rlib/Makefile
diff --git a/src/test/run-make/symlinked-rlib/bar.rs b/src/test/run-make-fulldeps/symlinked-rlib/bar.rs
similarity index 100%
rename from src/test/run-make/symlinked-rlib/bar.rs
rename to src/test/run-make-fulldeps/symlinked-rlib/bar.rs
diff --git a/src/test/run-make/symlinked-rlib/foo.rs b/src/test/run-make-fulldeps/symlinked-rlib/foo.rs
similarity index 100%
rename from src/test/run-make/symlinked-rlib/foo.rs
rename to src/test/run-make-fulldeps/symlinked-rlib/foo.rs
diff --git a/src/test/run-make/sysroot-crates-are-unstable/Makefile b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/Makefile
similarity index 100%
rename from src/test/run-make/sysroot-crates-are-unstable/Makefile
rename to src/test/run-make-fulldeps/sysroot-crates-are-unstable/Makefile
diff --git a/src/test/run-make/sysroot-crates-are-unstable/test.py b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py
similarity index 100%
rename from src/test/run-make/sysroot-crates-are-unstable/test.py
rename to src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py
diff --git a/src/test/run-make/target-cpu-native/Makefile b/src/test/run-make-fulldeps/target-cpu-native/Makefile
similarity index 100%
rename from src/test/run-make/target-cpu-native/Makefile
rename to src/test/run-make-fulldeps/target-cpu-native/Makefile
diff --git a/src/test/run-make/target-cpu-native/foo.rs b/src/test/run-make-fulldeps/target-cpu-native/foo.rs
similarity index 100%
rename from src/test/run-make/target-cpu-native/foo.rs
rename to src/test/run-make-fulldeps/target-cpu-native/foo.rs
diff --git a/src/test/run-make/target-specs/Makefile b/src/test/run-make-fulldeps/target-specs/Makefile
similarity index 100%
rename from src/test/run-make/target-specs/Makefile
rename to src/test/run-make-fulldeps/target-specs/Makefile
diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make-fulldeps/target-specs/foo.rs
similarity index 100%
rename from src/test/run-make/target-specs/foo.rs
rename to src/test/run-make-fulldeps/target-specs/foo.rs
diff --git a/src/test/run-make/target-specs/my-awesome-platform.json b/src/test/run-make-fulldeps/target-specs/my-awesome-platform.json
similarity index 100%
rename from src/test/run-make/target-specs/my-awesome-platform.json
rename to src/test/run-make-fulldeps/target-specs/my-awesome-platform.json
diff --git a/src/test/run-make/target-specs/my-incomplete-platform.json b/src/test/run-make-fulldeps/target-specs/my-incomplete-platform.json
similarity index 100%
rename from src/test/run-make/target-specs/my-incomplete-platform.json
rename to src/test/run-make-fulldeps/target-specs/my-incomplete-platform.json
diff --git a/src/test/run-make/target-specs/my-invalid-platform.json b/src/test/run-make-fulldeps/target-specs/my-invalid-platform.json
similarity index 100%
rename from src/test/run-make/target-specs/my-invalid-platform.json
rename to src/test/run-make-fulldeps/target-specs/my-invalid-platform.json
diff --git a/src/test/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json b/src/test/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json
similarity index 100%
rename from src/test/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json
rename to src/test/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json
diff --git a/src/test/run-make/target-without-atomics/Makefile b/src/test/run-make-fulldeps/target-without-atomics/Makefile
similarity index 100%
rename from src/test/run-make/target-without-atomics/Makefile
rename to src/test/run-make-fulldeps/target-without-atomics/Makefile
diff --git a/src/test/run-make/test-harness/Makefile b/src/test/run-make-fulldeps/test-harness/Makefile
similarity index 100%
rename from src/test/run-make/test-harness/Makefile
rename to src/test/run-make-fulldeps/test-harness/Makefile
diff --git a/src/test/run-make/test-harness/test-ignore-cfg.rs b/src/test/run-make-fulldeps/test-harness/test-ignore-cfg.rs
similarity index 100%
rename from src/test/run-make/test-harness/test-ignore-cfg.rs
rename to src/test/run-make-fulldeps/test-harness/test-ignore-cfg.rs
diff --git a/src/test/run-make/tools.mk b/src/test/run-make-fulldeps/tools.mk
similarity index 98%
rename from src/test/run-make/tools.mk
rename to src/test/run-make-fulldeps/tools.mk
index d9103e1992735..af1707de6c02f 100644
--- a/src/test/run-make/tools.mk
+++ b/src/test/run-make-fulldeps/tools.mk
@@ -9,7 +9,7 @@ RUSTC_ORIGINAL := $(RUSTC)
 BARE_RUSTC := $(HOST_RPATH_ENV) '$(RUSTC)'
 BARE_RUSTDOC := $(HOST_RPATH_ENV) '$(RUSTDOC)'
 RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS)
-RUSTDOC := $(BARE_RUSTDOC)
+RUSTDOC := $(BARE_RUSTDOC) -L $(TARGET_RPATH_DIR)
 ifdef RUSTC_LINKER
 RUSTC := $(RUSTC) -Clinker=$(RUSTC_LINKER)
 RUSTDOC := $(RUSTDOC) --linker $(RUSTC_LINKER) -Z unstable-options
diff --git a/src/test/run-make/treat-err-as-bug/Makefile b/src/test/run-make-fulldeps/treat-err-as-bug/Makefile
similarity index 100%
rename from src/test/run-make/treat-err-as-bug/Makefile
rename to src/test/run-make-fulldeps/treat-err-as-bug/Makefile
diff --git a/src/test/run-make/treat-err-as-bug/err.rs b/src/test/run-make-fulldeps/treat-err-as-bug/err.rs
similarity index 100%
rename from src/test/run-make/treat-err-as-bug/err.rs
rename to src/test/run-make-fulldeps/treat-err-as-bug/err.rs
diff --git a/src/test/run-make/type-mismatch-same-crate-name/Makefile b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile
similarity index 100%
rename from src/test/run-make/type-mismatch-same-crate-name/Makefile
rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile
diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateA.rs b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateA.rs
similarity index 100%
rename from src/test/run-make/type-mismatch-same-crate-name/crateA.rs
rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateA.rs
diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateB.rs b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateB.rs
similarity index 100%
rename from src/test/run-make/type-mismatch-same-crate-name/crateB.rs
rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateB.rs
diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateC.rs b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs
similarity index 100%
rename from src/test/run-make/type-mismatch-same-crate-name/crateC.rs
rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs
diff --git a/src/test/run-make/use-extern-for-plugins/Makefile b/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile
similarity index 100%
rename from src/test/run-make/use-extern-for-plugins/Makefile
rename to src/test/run-make-fulldeps/use-extern-for-plugins/Makefile
diff --git a/src/test/run-make/use-extern-for-plugins/bar.rs b/src/test/run-make-fulldeps/use-extern-for-plugins/bar.rs
similarity index 100%
rename from src/test/run-make/use-extern-for-plugins/bar.rs
rename to src/test/run-make-fulldeps/use-extern-for-plugins/bar.rs
diff --git a/src/test/run-make/use-extern-for-plugins/baz.rs b/src/test/run-make-fulldeps/use-extern-for-plugins/baz.rs
similarity index 100%
rename from src/test/run-make/use-extern-for-plugins/baz.rs
rename to src/test/run-make-fulldeps/use-extern-for-plugins/baz.rs
diff --git a/src/test/run-make/use-extern-for-plugins/foo.rs b/src/test/run-make-fulldeps/use-extern-for-plugins/foo.rs
similarity index 100%
rename from src/test/run-make/use-extern-for-plugins/foo.rs
rename to src/test/run-make-fulldeps/use-extern-for-plugins/foo.rs
diff --git a/src/test/run-make/used/Makefile b/src/test/run-make-fulldeps/used/Makefile
similarity index 100%
rename from src/test/run-make/used/Makefile
rename to src/test/run-make-fulldeps/used/Makefile
diff --git a/src/test/run-make/used/used.rs b/src/test/run-make-fulldeps/used/used.rs
similarity index 100%
rename from src/test/run-make/used/used.rs
rename to src/test/run-make-fulldeps/used/used.rs
diff --git a/src/test/run-make/version/Makefile b/src/test/run-make-fulldeps/version/Makefile
similarity index 100%
rename from src/test/run-make/version/Makefile
rename to src/test/run-make-fulldeps/version/Makefile
diff --git a/src/test/run-make/volatile-intrinsics/Makefile b/src/test/run-make-fulldeps/volatile-intrinsics/Makefile
similarity index 100%
rename from src/test/run-make/volatile-intrinsics/Makefile
rename to src/test/run-make-fulldeps/volatile-intrinsics/Makefile
diff --git a/src/test/run-make/volatile-intrinsics/main.rs b/src/test/run-make-fulldeps/volatile-intrinsics/main.rs
similarity index 100%
rename from src/test/run-make/volatile-intrinsics/main.rs
rename to src/test/run-make-fulldeps/volatile-intrinsics/main.rs
diff --git a/src/test/run-make/weird-output-filenames/Makefile b/src/test/run-make-fulldeps/weird-output-filenames/Makefile
similarity index 100%
rename from src/test/run-make/weird-output-filenames/Makefile
rename to src/test/run-make-fulldeps/weird-output-filenames/Makefile
diff --git a/src/test/run-make/weird-output-filenames/foo.rs b/src/test/run-make-fulldeps/weird-output-filenames/foo.rs
similarity index 100%
rename from src/test/run-make/weird-output-filenames/foo.rs
rename to src/test/run-make-fulldeps/weird-output-filenames/foo.rs
diff --git a/src/test/run-make/windows-spawn/Makefile b/src/test/run-make-fulldeps/windows-spawn/Makefile
similarity index 100%
rename from src/test/run-make/windows-spawn/Makefile
rename to src/test/run-make-fulldeps/windows-spawn/Makefile
diff --git a/src/test/run-make/windows-spawn/hello.rs b/src/test/run-make-fulldeps/windows-spawn/hello.rs
similarity index 100%
rename from src/test/run-make/windows-spawn/hello.rs
rename to src/test/run-make-fulldeps/windows-spawn/hello.rs
diff --git a/src/test/run-make/windows-spawn/spawn.rs b/src/test/run-make-fulldeps/windows-spawn/spawn.rs
similarity index 100%
rename from src/test/run-make/windows-spawn/spawn.rs
rename to src/test/run-make-fulldeps/windows-spawn/spawn.rs
diff --git a/src/test/run-make/windows-subsystem/Makefile b/src/test/run-make-fulldeps/windows-subsystem/Makefile
similarity index 100%
rename from src/test/run-make/windows-subsystem/Makefile
rename to src/test/run-make-fulldeps/windows-subsystem/Makefile
diff --git a/src/test/run-make/windows-subsystem/console.rs b/src/test/run-make-fulldeps/windows-subsystem/console.rs
similarity index 100%
rename from src/test/run-make/windows-subsystem/console.rs
rename to src/test/run-make-fulldeps/windows-subsystem/console.rs
diff --git a/src/test/run-make/windows-subsystem/windows.rs b/src/test/run-make-fulldeps/windows-subsystem/windows.rs
similarity index 100%
rename from src/test/run-make/windows-subsystem/windows.rs
rename to src/test/run-make-fulldeps/windows-subsystem/windows.rs
diff --git a/src/test/run-make/wasm-custom-section/Makefile b/src/test/run-make/wasm-custom-section/Makefile
new file mode 100644
index 0000000000000..399951e516314
--- /dev/null
+++ b/src/test/run-make/wasm-custom-section/Makefile
@@ -0,0 +1,10 @@
+-include ../../run-make-fulldeps/tools.mk
+
+ifeq ($(TARGET),wasm32-unknown-unknown)
+all:
+	$(RUSTC) foo.rs --target wasm32-unknown-unknown
+	$(RUSTC) bar.rs -C lto -O --target wasm32-unknown-unknown
+	$(NODE) foo.js $(TMPDIR)/bar.wasm
+else
+all:
+endif
diff --git a/src/test/run-make/wasm-custom-section/bar.rs b/src/test/run-make/wasm-custom-section/bar.rs
new file mode 100644
index 0000000000000..e3db36d6dbd4c
--- /dev/null
+++ b/src/test/run-make/wasm-custom-section/bar.rs
@@ -0,0 +1,24 @@
+// Copyright 2018 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.
+
+#![crate_type = "cdylib"]
+#![feature(wasm_custom_section)]
+#![deny(warnings)]
+
+extern crate foo;
+
+#[wasm_custom_section = "foo"]
+const A: [u8; 2] = [5, 6];
+
+#[wasm_custom_section = "baz"]
+const B: [u8; 2] = [7, 8];
+
+#[no_mangle]
+pub extern fn foo() {}
diff --git a/src/test/run-make/wasm-custom-section/foo.js b/src/test/run-make/wasm-custom-section/foo.js
new file mode 100644
index 0000000000000..e7a4cfc344efb
--- /dev/null
+++ b/src/test/run-make/wasm-custom-section/foo.js
@@ -0,0 +1,46 @@
+// Copyright 2018 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.
+
+const fs = require('fs');
+const process = require('process');
+const assert = require('assert');
+const buffer = fs.readFileSync(process.argv[2]);
+
+let m = new WebAssembly.Module(buffer);
+let sections = WebAssembly.Module.customSections(m, "baz");
+console.log('section baz', sections);
+assert.strictEqual(sections.length, 1);
+let section = new Uint8Array(sections[0]);
+console.log('contents', section);
+assert.strictEqual(section.length, 2);
+assert.strictEqual(section[0], 7);
+assert.strictEqual(section[1], 8);
+
+sections = WebAssembly.Module.customSections(m, "bar");
+console.log('section bar', sections);
+assert.strictEqual(sections.length, 1, "didn't pick up `bar` section from dependency");
+section = new Uint8Array(sections[0]);
+console.log('contents', section);
+assert.strictEqual(section.length, 2);
+assert.strictEqual(section[0], 3);
+assert.strictEqual(section[1], 4);
+
+sections = WebAssembly.Module.customSections(m, "foo");
+console.log('section foo', sections);
+assert.strictEqual(sections.length, 1, "didn't create `foo` section");
+section = new Uint8Array(sections[0]);
+console.log('contents', section);
+assert.strictEqual(section.length, 4, "didn't concatenate `foo` sections");
+assert.strictEqual(section[0], 5);
+assert.strictEqual(section[1], 6);
+assert.strictEqual(section[2], 1);
+assert.strictEqual(section[3], 2);
+
+process.exit(0);
diff --git a/src/test/run-make/wasm-custom-section/foo.rs b/src/test/run-make/wasm-custom-section/foo.rs
new file mode 100644
index 0000000000000..44d1efd7c2d62
--- /dev/null
+++ b/src/test/run-make/wasm-custom-section/foo.rs
@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+#![crate_type = "rlib"]
+#![feature(wasm_custom_section)]
+#![deny(warnings)]
+
+#[wasm_custom_section = "foo"]
+const A: [u8; 2] = [1, 2];
+
+#[wasm_custom_section = "bar"]
+const B: [u8; 2] = [3, 4];
diff --git a/src/test/run-make/wasm-import-module/Makefile b/src/test/run-make/wasm-import-module/Makefile
new file mode 100644
index 0000000000000..399951e516314
--- /dev/null
+++ b/src/test/run-make/wasm-import-module/Makefile
@@ -0,0 +1,10 @@
+-include ../../run-make-fulldeps/tools.mk
+
+ifeq ($(TARGET),wasm32-unknown-unknown)
+all:
+	$(RUSTC) foo.rs --target wasm32-unknown-unknown
+	$(RUSTC) bar.rs -C lto -O --target wasm32-unknown-unknown
+	$(NODE) foo.js $(TMPDIR)/bar.wasm
+else
+all:
+endif
diff --git a/src/test/run-make/wasm-import-module/bar.rs b/src/test/run-make/wasm-import-module/bar.rs
new file mode 100644
index 0000000000000..9e659223c651c
--- /dev/null
+++ b/src/test/run-make/wasm-import-module/bar.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+#![crate_type = "cdylib"]
+#![feature(wasm_import_module)]
+#![deny(warnings)]
+
+extern crate foo;
+
+#[wasm_import_module = "./me"]
+extern {
+    #[link_name = "me_in_dep"]
+    fn dep();
+}
+
+#[no_mangle]
+pub extern fn foo() {
+    unsafe {
+        foo::dep();
+        dep();
+    }
+}
diff --git a/src/test/run-make/wasm-import-module/foo.js b/src/test/run-make/wasm-import-module/foo.js
new file mode 100644
index 0000000000000..369962e55b1eb
--- /dev/null
+++ b/src/test/run-make/wasm-import-module/foo.js
@@ -0,0 +1,28 @@
+// Copyright 2018 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.
+
+const fs = require('fs');
+const process = require('process');
+const assert = require('assert');
+const buffer = fs.readFileSync(process.argv[2]);
+
+let m = new WebAssembly.Module(buffer);
+let imports = WebAssembly.Module.imports(m);
+console.log('imports', imports);
+assert.strictEqual(imports.length, 2);
+
+assert.strictEqual(imports[0].kind, 'function');
+assert.strictEqual(imports[1].kind, 'function');
+
+let modules = [imports[0].module, imports[1].module];
+modules.sort();
+
+assert.strictEqual(modules[0], './dep');
+assert.strictEqual(modules[1], './me');
diff --git a/src/test/run-make/wasm-import-module/foo.rs b/src/test/run-make/wasm-import-module/foo.rs
new file mode 100644
index 0000000000000..bcd2ca70befaa
--- /dev/null
+++ b/src/test/run-make/wasm-import-module/foo.rs
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+#![crate_type = "rlib"]
+#![feature(wasm_import_module)]
+#![deny(warnings)]
+
+#[wasm_import_module = "./dep"]
+extern {
+    pub fn dep();
+}
diff --git a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs b/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs
index 26419a51513f2..dc6f33bad9979 100644
--- a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs
@@ -12,7 +12,6 @@
 
 #![crate_type="dylib"]
 #![feature(plugin_registrar, rustc_private)]
-#![feature(slice_patterns)]
 
 extern crate syntax;
 extern crate syntax_pos;
@@ -49,7 +48,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
     }
 
     let text = match args[0] {
-        TokenTree::Token(_, token::Ident(s)) => s.to_string(),
+        TokenTree::Token(_, token::Ident(s, _)) => s.to_string(),
         _ => {
             cx.span_err(sp, "argument should be a single identifier");
             return DummyResult::any(sp);
diff --git a/src/test/run-pass-fulldeps/issue-35829.rs b/src/test/run-pass-fulldeps/issue-35829.rs
index c420243325038..798c214bc4715 100644
--- a/src/test/run-pass-fulldeps/issue-35829.rs
+++ b/src/test/run-pass-fulldeps/issue-35829.rs
@@ -20,8 +20,7 @@ use syntax::ext::expand::ExpansionConfig;
 use syntax::parse::ParseSess;
 use syntax::codemap::{FilePathMapping, dummy_spanned};
 use syntax::print::pprust::expr_to_string;
-use syntax::ast::{Expr, ExprKind, LitKind, StrStyle, RangeLimits};
-use syntax::symbol::Symbol;
+use syntax::ast::{ExprKind, LitKind, RangeLimits};
 use syntax::ptr::P;
 
 use rustc_data_structures::sync::Lrc;
diff --git a/src/test/run-pass/clone-closure.rs b/src/test/run-pass/clone-closure.rs
index 7f554c77fc4f8..0fe3711d8d32e 100644
--- a/src/test/run-pass/clone-closure.rs
+++ b/src/test/run-pass/clone-closure.rs
@@ -10,8 +10,6 @@
 
 // Check that closures implement `Clone`.
 
-#![feature(clone_closures)]
-
 #[derive(Clone)]
 struct S(i32);
 
diff --git a/src/test/run-pass/conservative_impl_trait.rs b/src/test/run-pass/conservative_impl_trait.rs
index 30090018e2947..14e1ca612c087 100644
--- a/src/test/run-pass/conservative_impl_trait.rs
+++ b/src/test/run-pass/conservative_impl_trait.rs
@@ -10,8 +10,6 @@
 
 // #39665
 
-#![feature(conservative_impl_trait)]
-
 fn batches(n: &u32) -> impl Iterator<Item=&u32> {
     std::iter::once(n)
 }
diff --git a/src/test/run-pass/copy-closure.rs b/src/test/run-pass/copy-closure.rs
index 309c83ebd99ac..a211d6fc3a385 100644
--- a/src/test/run-pass/copy-closure.rs
+++ b/src/test/run-pass/copy-closure.rs
@@ -10,9 +10,6 @@
 
 // Check that closures implement `Copy`.
 
-#![feature(copy_closures)]
-#![feature(clone_closures)]
-
 fn call<T, F: FnOnce() -> T>(f: F) -> T { f() }
 
 fn main() {
diff --git a/src/test/run-pass/ctfe/signed_enum_discr.rs b/src/test/run-pass/ctfe/signed_enum_discr.rs
new file mode 100644
index 0000000000000..7049d28a87085
--- /dev/null
+++ b/src/test/run-pass/ctfe/signed_enum_discr.rs
@@ -0,0 +1,27 @@
+// Copyright 2018 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.
+
+// https://github.com/rust-lang/rust/issues/49181
+
+#[derive(Eq, PartialEq)]
+#[repr(i8)]
+pub enum A {
+    B = -1,
+    C = 1,
+}
+
+pub const D: A = A::B;
+
+fn main() {
+    match A::C {
+        D => {},
+        _ => {}
+    }
+}
diff --git a/src/test/run-pass/ctfe/tuple-struct-constructors.rs b/src/test/run-pass/ctfe/tuple-struct-constructors.rs
index ecc5d37663679..ee1ce192fe03c 100644
--- a/src/test/run-pass/ctfe/tuple-struct-constructors.rs
+++ b/src/test/run-pass/ctfe/tuple-struct-constructors.rs
@@ -10,11 +10,10 @@
 
 // https://github.com/rust-lang/rust/issues/41898
 
-#![feature(nonzero, const_fn)]
-extern crate core;
-use core::nonzero::NonZero;
+#![feature(nonzero)]
+use std::num::NonZeroU64;
 
 fn main() {
-    const FOO: NonZero<u64> = unsafe { NonZero::new_unchecked(2) };
+    const FOO: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(2) };
     if let FOO = FOO {}
 }
diff --git a/src/test/run-pass/deep.rs b/src/test/run-pass/deep.rs
index 9ae4f2c1e7085..d59fe8d813d24 100644
--- a/src/test/run-pass/deep.rs
+++ b/src/test/run-pass/deep.rs
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-
-
+// ignore-emscripten apparently blows the stack
 
 fn f(x: isize) -> isize {
     if x == 1 { return 1; } else { let y: isize = 1 + f(x - 1); return y; }
diff --git a/src/test/run-pass/destructure-array-1.rs b/src/test/run-pass/destructure-array-1.rs
index 0d24f0bd0d7b3..43271162c1812 100644
--- a/src/test/run-pass/destructure-array-1.rs
+++ b/src/test/run-pass/destructure-array-1.rs
@@ -11,9 +11,6 @@
 // Ensure that we can do a destructuring bind of a fixed-size array,
 // even when the element type has a destructor.
 
-
-#![feature(slice_patterns)]
-
 struct D { x: u8 }
 
 impl Drop for D { fn drop(&mut self) { } }
diff --git a/src/test/run-pass/dyn-trait.rs b/src/test/run-pass/dyn-trait.rs
index fdec6a26ac945..399823ec92d0c 100644
--- a/src/test/run-pass/dyn-trait.rs
+++ b/src/test/run-pass/dyn-trait.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-pretty `dyn ::foo` parses differently in the current epoch
+// ignore-pretty `dyn ::foo` parses differently in the current edition
 
 #![feature(dyn_trait)]
 
diff --git a/src/test/run-pass/dynamic-drop.rs b/src/test/run-pass/dynamic-drop.rs
index 4d0bd3f3412f1..765fb06e5f3a4 100644
--- a/src/test/run-pass/dynamic-drop.rs
+++ b/src/test/run-pass/dynamic-drop.rs
@@ -13,7 +13,8 @@
 
 // ignore-wasm32-bare compiled with panic=abort by default
 
-#![feature(generators, generator_trait, untagged_unions, slice_patterns, advanced_slice_patterns)]
+#![feature(generators, generator_trait, untagged_unions)]
+#![feature(slice_patterns)]
 
 use std::cell::{Cell, RefCell};
 use std::ops::Generator;
@@ -178,7 +179,7 @@ fn generator(a: &Allocator, run_count: usize) {
          );
     };
     for _ in 0..run_count {
-        gen.resume();
+        unsafe { gen.resume(); }
     }
 }
 
diff --git a/src/test/run-pass/epoch-gate-feature.rs b/src/test/run-pass/epoch-gate-feature.rs
index 37d092c06e02b..f3d8f216e1132 100644
--- a/src/test/run-pass/epoch-gate-feature.rs
+++ b/src/test/run-pass/epoch-gate-feature.rs
@@ -11,7 +11,7 @@
 // Checks if the correct registers are being used to pass arguments
 // when the sysv64 ABI is specified.
 
-// compile-flags: -Zepoch=2018
+// compile-flags: -Zedition=2018
 
 pub trait Foo {}
 
diff --git a/src/test/run-pass/float-int-invalid-const-cast.rs b/src/test/run-pass/float-int-invalid-const-cast.rs
index 80ab12482cbb7..f84432abbfa0b 100644
--- a/src/test/run-pass/float-int-invalid-const-cast.rs
+++ b/src/test/run-pass/float-int-invalid-const-cast.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(i128_type)]
+// ignore-emscripten no i128 support
+
 #![deny(const_err)]
 
 use std::{f32, f64};
diff --git a/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs b/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs
index a6a2a2d081e1f..91e43537cc21d 100644
--- a/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs
+++ b/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait, generators, generator_trait)]
+#![feature(generators, generator_trait)]
 
 use std::ops::Generator;
 
diff --git a/src/test/run-pass/generator/auxiliary/xcrate.rs b/src/test/run-pass/generator/auxiliary/xcrate.rs
index f6878e64fbf93..fcfe0b754b68c 100644
--- a/src/test/run-pass/generator/auxiliary/xcrate.rs
+++ b/src/test/run-pass/generator/auxiliary/xcrate.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(generators, generator_trait, conservative_impl_trait)]
+#![feature(generators, generator_trait)]
 
 use std::ops::Generator;
 
diff --git a/src/test/run-pass/generator/conditional-drop.rs b/src/test/run-pass/generator/conditional-drop.rs
index 8329684e1a39b..3d39c46186be3 100644
--- a/src/test/run-pass/generator/conditional-drop.rs
+++ b/src/test/run-pass/generator/conditional-drop.rs
@@ -42,9 +42,9 @@ fn t1() {
     };
 
     let n = A.load(Ordering::SeqCst);
-    a.resume();
+    unsafe { a.resume() };
     assert_eq!(A.load(Ordering::SeqCst), n + 1);
-    a.resume();
+    unsafe { a.resume() };
     assert_eq!(A.load(Ordering::SeqCst), n + 1);
 }
 
@@ -58,8 +58,8 @@ fn t2() {
     };
 
     let n = A.load(Ordering::SeqCst);
-    a.resume();
+    unsafe { a.resume() };
     assert_eq!(A.load(Ordering::SeqCst), n);
-    a.resume();
+    unsafe { a.resume() };
     assert_eq!(A.load(Ordering::SeqCst), n + 1);
 }
diff --git a/src/test/run-pass/generator/control-flow.rs b/src/test/run-pass/generator/control-flow.rs
index 60a00b4e46756..09971410e556d 100644
--- a/src/test/run-pass/generator/control-flow.rs
+++ b/src/test/run-pass/generator/control-flow.rs
@@ -16,7 +16,7 @@ fn finish<T>(mut amt: usize, mut t: T) -> T::Return
     where T: Generator<Yield = ()>
 {
     loop {
-        match t.resume() {
+        match unsafe { t.resume() } {
             GeneratorState::Yielded(()) => amt = amt.checked_sub(1).unwrap(),
             GeneratorState::Complete(ret) => {
                 assert_eq!(amt, 0);
diff --git a/src/test/run-pass/generator/drop-env.rs b/src/test/run-pass/generator/drop-env.rs
index ac42a25899dbb..ef4dc24472e61 100644
--- a/src/test/run-pass/generator/drop-env.rs
+++ b/src/test/run-pass/generator/drop-env.rs
@@ -37,7 +37,7 @@ fn t1() {
     };
 
     let n = A.load(Ordering::SeqCst);
-    drop(foo.resume());
+    drop(unsafe { foo.resume() });
     assert_eq!(A.load(Ordering::SeqCst), n);
     drop(foo);
     assert_eq!(A.load(Ordering::SeqCst), n + 1);
@@ -50,7 +50,7 @@ fn t2() {
     };
 
     let n = A.load(Ordering::SeqCst);
-    drop(foo.resume());
+    drop(unsafe { foo.resume() });
     assert_eq!(A.load(Ordering::SeqCst), n + 1);
     drop(foo);
     assert_eq!(A.load(Ordering::SeqCst), n + 1);
diff --git a/src/test/run-pass/generator/issue-44197.rs b/src/test/run-pass/generator/issue-44197.rs
index 7cb80ea8b21b7..272b7eb7bfdd0 100644
--- a/src/test/run-pass/generator/issue-44197.rs
+++ b/src/test/run-pass/generator/issue-44197.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait, generators, generator_trait)]
+#![feature(generators, generator_trait)]
 
 use std::ops::{ Generator, GeneratorState };
 
@@ -35,6 +35,8 @@ fn bar2(baz: String) -> impl Generator<Yield = String, Return = ()> {
 }
 
 fn main() {
-    assert_eq!(bar(String::new()).resume(), GeneratorState::Yielded(String::new()));
-    assert_eq!(bar2(String::new()).resume(), GeneratorState::Complete(()));
+    unsafe {
+        assert_eq!(bar(String::new()).resume(), GeneratorState::Yielded(String::new()));
+        assert_eq!(bar2(String::new()).resume(), GeneratorState::Complete(()));
+    }
 }
diff --git a/src/test/run-pass/generator/iterator-count.rs b/src/test/run-pass/generator/iterator-count.rs
index 9afe95f9e865c..3564ddaa8068e 100644
--- a/src/test/run-pass/generator/iterator-count.rs
+++ b/src/test/run-pass/generator/iterator-count.rs
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(generators, generator_trait, conservative_impl_trait)]
+#![feature(generators, generator_trait)]
 
 use std::ops::{GeneratorState, Generator};
 
 struct W<T>(T);
 
+// This impl isn't safe in general, but the generator used in this test is movable
+// so it won't cause problems.
 impl<T: Generator<Return = ()>> Iterator for W<T> {
     type Item = T::Yield;
 
     fn next(&mut self) -> Option<Self::Item> {
-        match self.0.resume() {
+        match unsafe { self.0.resume() } {
             GeneratorState::Complete(..) => None,
             GeneratorState::Yielded(v) => Some(v),
         }
diff --git a/src/test/run-pass/generator/live-upvar-across-yield.rs b/src/test/run-pass/generator/live-upvar-across-yield.rs
index e34b0b3100c32..28e7da232ce09 100644
--- a/src/test/run-pass/generator/live-upvar-across-yield.rs
+++ b/src/test/run-pass/generator/live-upvar-across-yield.rs
@@ -17,5 +17,5 @@ fn main() {
     let mut a = || {
         b(yield);
     };
-    a.resume();
+    unsafe { a.resume() };
 }
diff --git a/src/test/run-pass/generator/nested_generators.rs b/src/test/run-pass/generator/nested_generators.rs
index f70d4144a3c9e..29808da85a7a9 100644
--- a/src/test/run-pass/generator/nested_generators.rs
+++ b/src/test/run-pass/generator/nested_generators.rs
@@ -20,7 +20,7 @@ fn main() {
             yield 2;
         };
 
-        match sub_generator.resume() {
+        match unsafe { sub_generator.resume() } {
             GeneratorState::Yielded(x) => {
                 yield x;
             }
diff --git a/src/test/run-pass/generator/panic-drops.rs b/src/test/run-pass/generator/panic-drops.rs
index 36e401a54bcdd..3d7b60ab6b901 100644
--- a/src/test/run-pass/generator/panic-drops.rs
+++ b/src/test/run-pass/generator/panic-drops.rs
@@ -42,7 +42,7 @@ fn main() {
 
     assert_eq!(A.load(Ordering::SeqCst), 0);
     let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        foo.resume()
+        unsafe { foo.resume() }
     }));
     assert!(res.is_err());
     assert_eq!(A.load(Ordering::SeqCst), 1);
@@ -57,7 +57,7 @@ fn main() {
 
     assert_eq!(A.load(Ordering::SeqCst), 1);
     let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        foo.resume()
+        unsafe { foo.resume() }
     }));
     assert!(res.is_err());
     assert_eq!(A.load(Ordering::SeqCst), 1);
diff --git a/src/test/run-pass/generator/panic-safe.rs b/src/test/run-pass/generator/panic-safe.rs
index 0d5bae7876bd3..ace5cdde51d85 100644
--- a/src/test/run-pass/generator/panic-safe.rs
+++ b/src/test/run-pass/generator/panic-safe.rs
@@ -24,13 +24,13 @@ fn main() {
     };
 
     let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        foo.resume()
+        unsafe { foo.resume() }
     }));
     assert!(res.is_err());
 
     for _ in 0..10 {
         let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-            foo.resume()
+            unsafe { foo.resume() }
         }));
         assert!(res.is_err());
     }
diff --git a/src/test/run-pass/generator/resume-after-return.rs b/src/test/run-pass/generator/resume-after-return.rs
index 56511dcd53a6a..06e7615d26191 100644
--- a/src/test/run-pass/generator/resume-after-return.rs
+++ b/src/test/run-pass/generator/resume-after-return.rs
@@ -23,12 +23,12 @@ fn main() {
         yield;
     };
 
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Complete(()) => {}
         s => panic!("bad state: {:?}", s),
     }
 
-    match panic::catch_unwind(move || foo.resume()) {
+    match panic::catch_unwind(move || unsafe { foo.resume() }) {
         Ok(_) => panic!("generator successfully resumed"),
         Err(_) => {}
     }
diff --git a/src/test/run-pass/generator/smoke.rs b/src/test/run-pass/generator/smoke.rs
index 8693964665d34..7395c8484c169 100644
--- a/src/test/run-pass/generator/smoke.rs
+++ b/src/test/run-pass/generator/smoke.rs
@@ -24,7 +24,7 @@ fn simple() {
         }
     };
 
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Complete(()) => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -40,7 +40,7 @@ fn return_capture() {
         a
     };
 
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Complete(ref s) if *s == "foo" => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -52,11 +52,11 @@ fn simple_yield() {
         yield;
     };
 
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Yielded(()) => {}
         s => panic!("bad state: {:?}", s),
     }
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Complete(()) => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -69,11 +69,11 @@ fn yield_capture() {
         yield b;
     };
 
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Yielded(ref s) if *s == "foo" => {}
         s => panic!("bad state: {:?}", s),
     }
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Complete(()) => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -86,11 +86,11 @@ fn simple_yield_value() {
         return String::from("foo")
     };
 
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Yielded(ref s) if *s == "bar" => {}
         s => panic!("bad state: {:?}", s),
     }
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Complete(ref s) if *s == "foo" => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -104,11 +104,11 @@ fn return_after_yield() {
         return a
     };
 
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Yielded(()) => {}
         s => panic!("bad state: {:?}", s),
     }
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Complete(ref s) if *s == "foo" => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -156,11 +156,11 @@ fn send_and_sync() {
 fn send_over_threads() {
     let mut foo = || { yield };
     thread::spawn(move || {
-        match foo.resume() {
+        match unsafe { foo.resume() } {
             GeneratorState::Yielded(()) => {}
             s => panic!("bad state: {:?}", s),
         }
-        match foo.resume() {
+        match unsafe { foo.resume() } {
             GeneratorState::Complete(()) => {}
             s => panic!("bad state: {:?}", s),
         }
@@ -169,11 +169,11 @@ fn send_over_threads() {
     let a = String::from("a");
     let mut foo = || { yield a };
     thread::spawn(move || {
-        match foo.resume() {
+        match unsafe { foo.resume() } {
             GeneratorState::Yielded(ref s) if *s == "a" => {}
             s => panic!("bad state: {:?}", s),
         }
-        match foo.resume() {
+        match unsafe { foo.resume() } {
             GeneratorState::Complete(()) => {}
             s => panic!("bad state: {:?}", s),
         }
diff --git a/src/test/run-pass/generator/static-generators.rs b/src/test/run-pass/generator/static-generators.rs
index 9504414d8b6f5..ebc070eee09c1 100644
--- a/src/test/run-pass/generator/static-generators.rs
+++ b/src/test/run-pass/generator/static-generators.rs
@@ -13,14 +13,14 @@
 use std::ops::{Generator, GeneratorState};
 
 fn main() {
-    let mut generator = unsafe {
-        static || {
-            let a = true;
-            let b = &a;
-            yield;
-            assert_eq!(b as *const _, &a as *const _);
-        }
+    let mut generator = static || {
+        let a = true;
+        let b = &a;
+        yield;
+        assert_eq!(b as *const _, &a as *const _);
     };
-    assert_eq!(generator.resume(), GeneratorState::Yielded(()));
-    assert_eq!(generator.resume(), GeneratorState::Complete(()));
+    unsafe {
+        assert_eq!(generator.resume(), GeneratorState::Yielded(()));
+        assert_eq!(generator.resume(), GeneratorState::Complete(()));
+    }
 }
diff --git a/src/test/run-pass/generator/xcrate-reachable.rs b/src/test/run-pass/generator/xcrate-reachable.rs
index dff5e08b9c20e..2fc39ba186916 100644
--- a/src/test/run-pass/generator/xcrate-reachable.rs
+++ b/src/test/run-pass/generator/xcrate-reachable.rs
@@ -10,12 +10,12 @@
 
 // aux-build:xcrate-reachable.rs
 
-#![feature(conservative_impl_trait, generator_trait)]
+#![feature(generator_trait)]
 
 extern crate xcrate_reachable as foo;
 
 use std::ops::Generator;
 
 fn main() {
-    foo::foo().resume();
+    unsafe { foo::foo().resume(); }
 }
diff --git a/src/test/run-pass/generator/xcrate.rs b/src/test/run-pass/generator/xcrate.rs
index dc7a6fdef9c7e..04791d5135677 100644
--- a/src/test/run-pass/generator/xcrate.rs
+++ b/src/test/run-pass/generator/xcrate.rs
@@ -19,18 +19,18 @@ use std::ops::{GeneratorState, Generator};
 fn main() {
     let mut foo = xcrate::foo();
 
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Complete(()) => {}
         s => panic!("bad state: {:?}", s),
     }
 
     let mut foo = xcrate::bar(3);
 
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Yielded(3) => {}
         s => panic!("bad state: {:?}", s),
     }
-    match foo.resume() {
+    match unsafe { foo.resume() } {
         GeneratorState::Complete(()) => {}
         s => panic!("bad state: {:?}", s),
     }
diff --git a/src/test/run-pass/generator/yield-subtype.rs b/src/test/run-pass/generator/yield-subtype.rs
index 7e8a0d1e2b925..c41341690441f 100644
--- a/src/test/run-pass/generator/yield-subtype.rs
+++ b/src/test/run-pass/generator/yield-subtype.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // revisions:lexical nll
+//[nll]compile-flags: -Z disable-nll-user-type-assert
 #![cfg_attr(nll, feature(nll))]
 
 #![feature(generators)]
diff --git a/src/test/run-pass/i128-ffi.rs b/src/test/run-pass/i128-ffi.rs
index d989210dd71f2..edf278cbf64a5 100644
--- a/src/test/run-pass/i128-ffi.rs
+++ b/src/test/run-pass/i128-ffi.rs
@@ -15,8 +15,6 @@
 // ignore-windows
 // ignore-32bit
 
-#![feature(i128_type)]
-
 #[link(name = "rust_test_helpers", kind = "static")]
 extern "C" {
     fn identity(f: u128) -> u128;
diff --git a/src/test/run-pass/i128.rs b/src/test/run-pass/i128.rs
index c3e43c92590ed..baf3b3399849a 100644
--- a/src/test/run-pass/i128.rs
+++ b/src/test/run-pass/i128.rs
@@ -12,7 +12,7 @@
 
 // compile-flags: -Z borrowck=compare
 
-#![feature(i128_type, test)]
+#![feature(test)]
 
 extern crate test;
 use test::black_box as b;
diff --git a/src/test/run-pass/ignore-all-the-things.rs b/src/test/run-pass/ignore-all-the-things.rs
index 711f2dd6c6676..c14f3dc72916d 100644
--- a/src/test/run-pass/ignore-all-the-things.rs
+++ b/src/test/run-pass/ignore-all-the-things.rs
@@ -10,7 +10,6 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(advanced_slice_patterns)]
 #![feature(slice_patterns)]
 
 struct Foo(isize, isize, isize, isize);
@@ -20,11 +19,11 @@ pub fn main() {
     let Foo(..) = Foo(5, 5, 5, 5);
     let Foo(..) = Foo(5, 5, 5, 5);
     let Bar{..} = Bar{a: 5, b: 5, c: 5, d: 5};
-    //let (..) = (5, 5, 5, 5);
-    //let Foo(a, b, ..) = Foo(5, 5, 5, 5);
-    //let Foo(.., d) = Foo(5, 5, 5, 5);
-    //let (a, b, ..) = (5, 5, 5, 5);
-    //let (.., c, d) = (5, 5, 5, 5);
+    let (..) = (5, 5, 5, 5);
+    let Foo(a, b, ..) = Foo(5, 5, 5, 5);
+    let Foo(.., d) = Foo(5, 5, 5, 5);
+    let (a, b, ..) = (5, 5, 5, 5);
+    let (.., c, d) = (5, 5, 5, 5);
     let Bar{b: b, ..} = Bar{a: 5, b: 5, c: 5, d: 5};
     match [5, 5, 5, 5] {
         [..] => { }
diff --git a/src/test/run-pass/impl-trait/auto-trait-leak.rs b/src/test/run-pass/impl-trait/auto-trait-leak.rs
index 011d910c5a50f..62fbae7b40c03 100644
--- a/src/test/run-pass/impl-trait/auto-trait-leak.rs
+++ b/src/test/run-pass/impl-trait/auto-trait-leak.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 // Fast path, main can see the concrete type returned.
 fn before() -> impl FnMut(i32) {
     let mut p = Box::new(0);
diff --git a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs b/src/test/run-pass/impl-trait/auxiliary/xcrate.rs
index e4f525a982610..c27a2dd89d524 100644
--- a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs
+++ b/src/test/run-pass/impl-trait/auxiliary/xcrate.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 // NOTE commented out due to issue #45994
 //pub fn fourway_add(a: i32) -> impl Fn(i32) -> impl Fn(i32) -> impl Fn(i32) -> i32 {
 //    move |b| move |c| move |d| a + b + c + d
diff --git a/src/test/run-pass/impl-trait/equality.rs b/src/test/run-pass/impl-trait/equality.rs
index ceed454e5ad7e..034d3d7c80f36 100644
--- a/src/test/run-pass/impl-trait/equality.rs
+++ b/src/test/run-pass/impl-trait/equality.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait, specialization)]
+#![feature(specialization)]
 
 trait Foo: std::fmt::Debug + Eq {}
 
diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs
index aca100591ddec..b1db203071788 100644
--- a/src/test/run-pass/impl-trait/example-calendar.rs
+++ b/src/test/run-pass/impl-trait/example-calendar.rs
@@ -11,9 +11,7 @@
 // revisions: normal nll
 //[nll] compile-flags: -Znll -Zborrowck=mir
 
-#![feature(conservative_impl_trait,
-           universal_impl_trait,
-           fn_traits,
+#![feature(fn_traits,
            step_trait,
            unboxed_closures,
            copy_closures,
diff --git a/src/test/run-pass/impl-trait/example-st.rs b/src/test/run-pass/impl-trait/example-st.rs
index e9326ed286aff..a06bde7f532d3 100644
--- a/src/test/run-pass/impl-trait/example-st.rs
+++ b/src/test/run-pass/impl-trait/example-st.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 struct State;
 type Error = ();
 
diff --git a/src/test/run-pass/impl-trait/issue-42479.rs b/src/test/run-pass/impl-trait/issue-42479.rs
index 629948a5dc4a8..df7a6c1309220 100644
--- a/src/test/run-pass/impl-trait/issue-42479.rs
+++ b/src/test/run-pass/impl-trait/issue-42479.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 use std::iter::once;
 
 struct Foo {
diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs
index fcad23926fc0c..1b50ceefbe1ae 100644
--- a/src/test/run-pass/impl-trait/lifetimes.rs
+++ b/src/test/run-pass/impl-trait/lifetimes.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait, underscore_lifetimes, universal_impl_trait)]
+#![feature(underscore_lifetimes)]
 #![allow(warnings)]
 
 use std::fmt::Debug;
diff --git a/src/test/run-pass/impl-trait/universal_hrtb_anon.rs b/src/test/run-pass/impl-trait/universal_hrtb_anon.rs
index 48874ef41de55..9fc74757da0bf 100644
--- a/src/test/run-pass/impl-trait/universal_hrtb_anon.rs
+++ b/src/test/run-pass/impl-trait/universal_hrtb_anon.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
-
 fn hrtb(f: impl Fn(&u32) -> u32) -> u32 {
     f(&22) + f(&44)
 }
diff --git a/src/test/run-pass/impl-trait/universal_hrtb_named.rs b/src/test/run-pass/impl-trait/universal_hrtb_named.rs
index 95147a542005e..3aefc79ebf782 100644
--- a/src/test/run-pass/impl-trait/universal_hrtb_named.rs
+++ b/src/test/run-pass/impl-trait/universal_hrtb_named.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
-
 fn hrtb(f: impl for<'a> Fn(&'a u32) -> &'a u32) -> u32 {
     f(&22) + f(&44)
 }
diff --git a/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs b/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs
index d0f18575297b2..57452a2e475c3 100644
--- a/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs
+++ b/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
 use std::fmt::Display;
 
 fn check_display_eq(iter: &Vec<impl Display>) {
diff --git a/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs b/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs
index ccf24b77a6b77..fea946f12584e 100644
--- a/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs
+++ b/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
 use std::fmt::Display;
 
 fn check_display_eq(iter: impl IntoIterator<Item = impl Display>) {
diff --git a/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs b/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs
index af0201b5f871e..d3611e02e025b 100644
--- a/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs
+++ b/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
-
 use std::fmt::Debug;
 
 trait InTraitDefnParameters {
diff --git a/src/test/run-pass/impl-trait/universal_multiple_bounds.rs b/src/test/run-pass/impl-trait/universal_multiple_bounds.rs
index bb332c0c96cb5..594207feb09a4 100644
--- a/src/test/run-pass/impl-trait/universal_multiple_bounds.rs
+++ b/src/test/run-pass/impl-trait/universal_multiple_bounds.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
-
 use std::fmt::Display;
 
 fn foo(f: impl Display + Clone) -> String {
diff --git a/src/test/run-pass/in-band-lifetimes.rs b/src/test/run-pass/in-band-lifetimes.rs
index 95cc3c3759e60..6edd0d686eff8 100644
--- a/src/test/run-pass/in-band-lifetimes.rs
+++ b/src/test/run-pass/in-band-lifetimes.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![allow(warnings)]
-#![feature(in_band_lifetimes, universal_impl_trait, conservative_impl_trait)]
+#![feature(in_band_lifetimes)]
 
 fn foo(x: &'x u8) -> &'x u8 { x }
 fn foo2(x: &'a u8, y: &u8) -> &'a u8 { x }
diff --git a/src/test/run-pass/intrinsics-integer.rs b/src/test/run-pass/intrinsics-integer.rs
index bfa3a1e128a9a..7a8ff1befc7f0 100644
--- a/src/test/run-pass/intrinsics-integer.rs
+++ b/src/test/run-pass/intrinsics-integer.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(intrinsics, i128_type)]
+// ignore-emscripten no i128 support
+
+#![feature(intrinsics)]
 
 mod rusti {
     extern "rust-intrinsic" {
diff --git a/src/test/run-pass/intrinsics-math.rs b/src/test/run-pass/intrinsics-math.rs
index a2c55634749cb..5132405a9d583 100644
--- a/src/test/run-pass/intrinsics-math.rs
+++ b/src/test/run-pass/intrinsics-math.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-emscripten fma not implemented in emscripten
+
 macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
         let (a, b) = (&$a, &$b);
diff --git a/src/test/run-pass/issue-10683.rs b/src/test/run-pass/issue-10683.rs
index eb2177202a22b..d3ba477fa573e 100644
--- a/src/test/run-pass/issue-10683.rs
+++ b/src/test/run-pass/issue-10683.rs
@@ -10,8 +10,6 @@
 
 // pretty-expanded FIXME #23616
 
-use std::ascii::AsciiExt;
-
 static NAME: &'static str = "hello world";
 
 fn main() {
diff --git a/src/test/run-pass/issue-13027.rs b/src/test/run-pass/issue-13027.rs
index 1498748471179..d28ea94ec1a0d 100644
--- a/src/test/run-pass/issue-13027.rs
+++ b/src/test/run-pass/issue-13027.rs
@@ -12,8 +12,6 @@
 // Tests that match expression handles overlapped literal and range
 // properly in the presence of guard function.
 
-#![feature(slice_patterns)]
-
 fn val() -> usize { 1 }
 
 static CONST: usize = 1;
diff --git a/src/test/run-pass/issue-15080.rs b/src/test/run-pass/issue-15080.rs
index 14e0037884698..59267f79e2643 100644
--- a/src/test/run-pass/issue-15080.rs
+++ b/src/test/run-pass/issue-15080.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 #![feature(slice_patterns)]
 
 fn main() {
diff --git a/src/test/run-pass/issue-15104.rs b/src/test/run-pass/issue-15104.rs
index 508360cb70110..2878f2795c590 100644
--- a/src/test/run-pass/issue-15104.rs
+++ b/src/test/run-pass/issue-15104.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 #![feature(slice_patterns)]
 
 fn main() {
diff --git a/src/test/run-pass/issue-16648.rs b/src/test/run-pass/issue-16648.rs
index e1b94179764bf..bf272308fa9df 100644
--- a/src/test/run-pass/issue-16648.rs
+++ b/src/test/run-pass/issue-16648.rs
@@ -8,9 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![feature(slice_patterns)]
-
 fn main() {
     let x: (isize, &[isize]) = (2, &[1, 2]);
     assert_eq!(match x {
diff --git a/src/test/run-pass/issue-17877.rs b/src/test/run-pass/issue-17877.rs
index 6c87e8d35fbf0..d3fe0903a1d64 100644
--- a/src/test/run-pass/issue-17877.rs
+++ b/src/test/run-pass/issue-17877.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 #![feature(slice_patterns)]
 
 fn main() {
diff --git a/src/test/run-pass/issue-27889.rs b/src/test/run-pass/issue-27889.rs
index 3f7d0400c884e..29a5f6dd24bd0 100644
--- a/src/test/run-pass/issue-27889.rs
+++ b/src/test/run-pass/issue-27889.rs
@@ -10,7 +10,6 @@
 
 // Test that a field can have the same name in different variants
 // of an enum
-// FIXME #27889
 
 pub enum Foo {
     X { foo: u32 },
diff --git a/src/test/run-pass/issue-28561.rs b/src/test/run-pass/issue-28561.rs
index 8c73830f4d778..e21e487fedd1c 100644
--- a/src/test/run-pass/issue-28561.rs
+++ b/src/test/run-pass/issue-28561.rs
@@ -45,7 +45,7 @@ struct Array<T> {
     f32: [T; 32],
 }
 
-// FIXME(#7622): merge with `Array` once `[T; N]: Clone` where `T: Clone`
+// FIXME(#44580): merge with `Array` once `[T; N]: Clone` where `T: Clone`
 #[derive(Clone, Copy)]
 struct CopyArray<T: Copy> {
     f00: [T; 00],
diff --git a/src/test/run-pass/issue-32947.rs b/src/test/run-pass/issue-32947.rs
index d0fef36efb9cd..d059a46b4df12 100644
--- a/src/test/run-pass/issue-32947.rs
+++ b/src/test/run-pass/issue-32947.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-emscripten FIXME(#45351)
+
 #![feature(repr_simd, test)]
 
 extern crate test;
diff --git a/src/test/run-pass/issue-36792.rs b/src/test/run-pass/issue-36792.rs
index faf983f6ecb1c..f2755ec3f8466 100644
--- a/src/test/run-pass/issue-36792.rs
+++ b/src/test/run-pass/issue-36792.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
 fn foo() -> impl Copy {
     foo
 }
diff --git a/src/test/run-pass/issue-37598.rs b/src/test/run-pass/issue-37598.rs
index d32d2fc295440..e97c8d9f4176c 100644
--- a/src/test/run-pass/issue-37598.rs
+++ b/src/test/run-pass/issue-37598.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(advanced_slice_patterns, slice_patterns)]
+#![feature(slice_patterns)]
 
 fn check(list: &[u8]) {
     match list {
diff --git a/src/test/run-pass/issue-38002.rs b/src/test/run-pass/issue-38002.rs
index 489d35e9147ad..dd6ccec973fc0 100644
--- a/src/test/run-pass/issue-38002.rs
+++ b/src/test/run-pass/issue-38002.rs
@@ -10,8 +10,6 @@
 
 // Check that constant ADTs are translated OK, part k of N.
 
-#![feature(slice_patterns)]
-
 enum Bar {
     C
 }
diff --git a/src/test/run-pass/issue-38074.rs b/src/test/run-pass/issue-38074.rs
index 5c9a63b861663..2368ba8a110be 100644
--- a/src/test/run-pass/issue-38074.rs
+++ b/src/test/run-pass/issue-38074.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-emscripten FIXME(#45351)
+
 #![feature(platform_intrinsics, repr_simd)]
 
 extern "platform-intrinsic" {
diff --git a/src/test/run-pass/issue-38763.rs b/src/test/run-pass/issue-38763.rs
index 01cc8265a399f..e038062ff9ae7 100644
--- a/src/test/run-pass/issue-38763.rs
+++ b/src/test/run-pass/issue-38763.rs
@@ -10,8 +10,6 @@
 
 // ignore-emscripten
 
-#![feature(i128_type)]
-
 #[repr(C)]
 pub struct Foo(i128);
 
diff --git a/src/test/run-pass/issue-38987.rs b/src/test/run-pass/issue-38987.rs
index a513476d4a33a..31a3b7233d8cd 100644
--- a/src/test/run-pass/issue-38987.rs
+++ b/src/test/run-pass/issue-38987.rs
@@ -7,7 +7,6 @@
 // <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(i128_type)]
 
 fn main() {
     let _ = -0x8000_0000_0000_0000_0000_0000_0000_0000i128;
diff --git a/src/test/run-pass/issue-39720.rs b/src/test/run-pass/issue-39720.rs
index f90696e3cdf16..9873a8c2bf44f 100644
--- a/src/test/run-pass/issue-39720.rs
+++ b/src/test/run-pass/issue-39720.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-emscripten FIXME(#45351)
+
 #![feature(repr_simd, platform_intrinsics)]
 
 #[repr(C)]
diff --git a/src/test/run-pass/issue-46855.rs b/src/test/run-pass/issue-46855.rs
index d864d55c93972..28aa6c731ec81 100644
--- a/src/test/run-pass/issue-46855.rs
+++ b/src/test/run-pass/issue-46855.rs
@@ -10,8 +10,6 @@
 
 // compile-flags: -Zmir-opt-level=1
 
-#![feature(slice_patterns)]
-
 use std::mem;
 
 #[derive(Copy, Clone)]
diff --git a/src/test/run-pass/issue-46959.rs b/src/test/run-pass/issue-46959.rs
index 0826f5e492389..7f050c055b0ce 100644
--- a/src/test/run-pass/issue-46959.rs
+++ b/src/test/run-pass/issue-46959.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
-#![feature(conservative_impl_trait)]
 #![deny(non_camel_case_types)]
 
 #[allow(dead_code)]
diff --git a/src/test/run-pass/issue-7784.rs b/src/test/run-pass/issue-7784.rs
index badc013cd621f..8d21594aa12ca 100644
--- a/src/test/run-pass/issue-7784.rs
+++ b/src/test/run-pass/issue-7784.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![feature(advanced_slice_patterns)]
 #![feature(slice_patterns)]
 
 use std::ops::Add;
diff --git a/src/test/run-pass/match-vec-alternatives.rs b/src/test/run-pass/match-vec-alternatives.rs
index fa609593c24b6..7d03d9c2abe20 100644
--- a/src/test/run-pass/match-vec-alternatives.rs
+++ b/src/test/run-pass/match-vec-alternatives.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![feature(advanced_slice_patterns)]
 #![feature(slice_patterns)]
 
 fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str {
diff --git a/src/test/run-pass/mir_heavy_promoted.rs b/src/test/run-pass/mir_heavy_promoted.rs
index 9e033421574b9..b50852175776c 100644
--- a/src/test/run-pass/mir_heavy_promoted.rs
+++ b/src/test/run-pass/mir_heavy_promoted.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-emscripten apparently only works in optimized mode
+
 const TEST_DATA: [u8; 32 * 1024 * 1024] = [42; 32 * 1024 * 1024];
 
 // Check that the promoted copy of TEST_DATA doesn't
diff --git a/src/test/run-pass/next-power-of-two-overflow-debug.rs b/src/test/run-pass/next-power-of-two-overflow-debug.rs
index 2782f8c2a598c..2135b3f8764c0 100644
--- a/src/test/run-pass/next-power-of-two-overflow-debug.rs
+++ b/src/test/run-pass/next-power-of-two-overflow-debug.rs
@@ -10,8 +10,7 @@
 
 // compile-flags: -C debug_assertions=yes
 // ignore-wasm32-bare compiled with panic=abort by default
-
-#![feature(i128_type)]
+// ignore-emscripten dies with an LLVM error
 
 use std::panic;
 
diff --git a/src/test/run-pass/next-power-of-two-overflow-ndebug.rs b/src/test/run-pass/next-power-of-two-overflow-ndebug.rs
index f8bcb961c6833..b05c1863d902d 100644
--- a/src/test/run-pass/next-power-of-two-overflow-ndebug.rs
+++ b/src/test/run-pass/next-power-of-two-overflow-ndebug.rs
@@ -9,8 +9,7 @@
 // except according to those terms.
 
 // compile-flags: -C debug_assertions=no
-
-#![feature(i128_type)]
+// ignore-emscripten dies with an LLVM error
 
 fn main() {
     for i in 129..256 {
diff --git a/src/test/run-pass/nll/rc-loop.rs b/src/test/run-pass/nll/rc-loop.rs
index 2b746fac4d426..2114dbebe93fb 100644
--- a/src/test/run-pass/nll/rc-loop.rs
+++ b/src/test/run-pass/nll/rc-loop.rs
@@ -14,7 +14,6 @@
 // `x`.  The lexical checker makes this very painful. The NLL checker
 // does not.
 
-#![feature(match_default_bindings)]
 #![feature(nll)]
 
 use std::rc::Rc;
diff --git a/src/test/run-pass/packed-struct-borrow-element.rs b/src/test/run-pass/packed-struct-borrow-element.rs
index 3041c73afba88..e725b25efee52 100644
--- a/src/test/run-pass/packed-struct-borrow-element.rs
+++ b/src/test/run-pass/packed-struct-borrow-element.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-emscripten weird assertion?
 
 #[repr(packed)]
 struct Foo {
diff --git a/src/test/run-pass/process-spawn-nonexistent.rs b/src/test/run-pass/process-spawn-nonexistent.rs
new file mode 100644
index 0000000000000..9219cd625f30f
--- /dev/null
+++ b/src/test/run-pass/process-spawn-nonexistent.rs
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+// ignore-cloudabi no processes
+// ignore-emscripten no processes
+
+use std::io::ErrorKind;
+use std::process::Command;
+
+fn main() {
+    assert_eq!(Command::new("nonexistent")
+                   .spawn()
+                   .unwrap_err()
+                   .kind(),
+               ErrorKind::NotFound);
+}
diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs
index 5e534da012875..046d27a9f0fe5 100644
--- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs
+++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs
@@ -8,6 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(termination_trait)]
-
 fn main() {}
diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs
index 80fa4d17b6116..4aa7d8c3a77d2 100644
--- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs
+++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(termination_trait)]
 #![feature(process_exitcode_placeholder)]
 
 use std::process::ExitCode;
diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs
index 269ac451cf4d8..33686ed0b8fa2 100644
--- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs
+++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(termination_trait)]
-
 use std::io::Error;
 
 fn main() -> Result<(), Box<Error>> {
diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs
index 751db0fb50082..1c87e31e763e9 100644
--- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs
+++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(termination_trait)]
-
 use std::io::Error;
 
 fn main() -> Result<(), Error> {
diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs
index 494500d522abe..11997eb691728 100644
--- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs
+++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs
@@ -10,7 +10,7 @@
 
 // compile-flags: --test
 
-#![feature(termination_trait)]
+#![feature(termination_trait_test)]
 #![feature(test)]
 
 extern crate test;
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/box.rs b/src/test/run-pass/rfc-2005-default-binding-mode/box.rs
index 85453f32208cb..95bce1935e525 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/box.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/box.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![feature(box_syntax, box_patterns)]
-#![feature(match_default_bindings)]
 
 struct Foo{}
 
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/constref.rs b/src/test/run-pass/rfc-2005-default-binding-mode/constref.rs
index 1b8fdbaa4d75c..af40ef2b1c5d1 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/constref.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/constref.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 const CONST_REF: &[u8; 3] = b"foo";
 
 trait Foo {
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/enum.rs b/src/test/run-pass/rfc-2005-default-binding-mode/enum.rs
index a7b3db021b021..4755fc37ef347 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/enum.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/enum.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 enum Wrapper {
     Wrap(i32),
 }
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/for.rs b/src/test/run-pass/rfc-2005-default-binding-mode/for.rs
index 4feab94a7edf5..c2467d3f00910 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/for.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/for.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 pub fn main() {
     let mut tups = vec![(0u8, 1u8)];
 
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/general.rs b/src/test/run-pass/rfc-2005-default-binding-mode/general.rs
index 779a38bdb1672..df28046d7d70b 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/general.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/general.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 fn some_or_wildcard(r: &Option<i32>, b: &i32) {
     let _: &i32 = match r {
         Some(a) => a,
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/lit.rs b/src/test/run-pass/rfc-2005-default-binding-mode/lit.rs
index 0b2a8e52fbf77..004ea42b65b88 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/lit.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/lit.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 fn with_u8() {
     let s = 5u8;
     let r = match &s {
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/range.rs b/src/test/run-pass/rfc-2005-default-binding-mode/range.rs
index aafaa4cca82ca..2292d97eaf4e5 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/range.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/range.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 pub fn main() {
     let i = 5;
     match &&&&i {
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/ref-region.rs b/src/test/run-pass/rfc-2005-default-binding-mode/ref-region.rs
index de7df011b56fd..bc96853fd948a 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/ref-region.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/ref-region.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 fn foo<'a, 'b>(x: &'a &'b Option<u32>) -> &'a u32 {
     let x: &'a &'a Option<u32> = x;
     match x {
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs b/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs
index f980ef0ccddda..1d86a2ecf869a 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 // Test that we "reset" the mode as we pass through a `&` pattern.
 //
 // cc #46688
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs b/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs
index 1717d0d54c026..0d1d0893c593e 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![feature(slice_patterns)]
-#![feature(match_default_bindings)]
 
 fn slice_pat() {
     let sl: &[u8] = b"foo";
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/struct.rs b/src/test/run-pass/rfc-2005-default-binding-mode/struct.rs
index 11a675c0c72af..017439b3b140f 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/struct.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/struct.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 #[derive(Debug, PartialEq)]
 struct Foo {
     x: u8,
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/tuple-struct.rs b/src/test/run-pass/rfc-2005-default-binding-mode/tuple-struct.rs
index 7867d6529050d..3b55405abdd7e 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/tuple-struct.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/tuple-struct.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 enum Foo {
     Bar(Option<i8>, (), (), Vec<i32>),
     Baz,
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/tuple.rs b/src/test/run-pass/rfc-2005-default-binding-mode/tuple.rs
index cf27265b2ed56..966b8e1a81279 100644
--- a/src/test/run-pass/rfc-2005-default-binding-mode/tuple.rs
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/tuple.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 pub fn main() {
     let foo = (Some(1), (), (), vec![2, 3]);
 
diff --git a/src/test/compile-fail/i128-feature-libs.rs b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs
similarity index 55%
rename from src/test/compile-fail/i128-feature-libs.rs
rename to src/test/run-pass/rfc-2151-raw-identifiers/attr.rs
index b29ac50fd377f..6cea75cf1d11e 100644
--- a/src/test/compile-fail/i128-feature-libs.rs
+++ b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs
@@ -1,4 +1,4 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,10 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn testl() {
-    ::std::u128::MAX; //~ ERROR use of unstable library feature 'i128'
+#![feature(raw_identifiers)]
+
+use std::mem;
+
+#[r#repr(r#C, r#packed)]
+struct Test {
+    a: bool, b: u64
 }
 
-fn testl2() {
-    ::std::i128::MAX; //~ ERROR use of unstable library feature 'i128'
+#[r#derive(r#Debug)]
+struct Test2(u32);
+
+pub fn main() {
+    assert_eq!(mem::size_of::<Test>(), 9);
+    assert_eq!("Test2(123)", format!("{:?}", Test2(123)));
 }
diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs
new file mode 100644
index 0000000000000..5d495c4e9e557
--- /dev/null
+++ b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs
@@ -0,0 +1,31 @@
+// Copyright 2018 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(raw_identifiers)]
+
+fn r#fn(r#match: u32) -> u32 {
+    r#match
+}
+
+pub fn main() {
+    let r#struct = 1;
+    assert_eq!(1, r#struct);
+
+    let foo = 2;
+    assert_eq!(2, r#foo);
+
+    let r#bar = 3;
+    assert_eq!(3, bar);
+
+    assert_eq!(4, r#fn(4));
+
+    let r#true = false;
+    assert_eq!(r#true, false);
+}
diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/items.rs b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs
new file mode 100644
index 0000000000000..256bd263d38d4
--- /dev/null
+++ b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs
@@ -0,0 +1,43 @@
+// Copyright 2018 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(raw_identifiers)]
+
+#[derive(Debug, PartialEq, Eq)]
+struct IntWrapper(u32);
+
+#[derive(Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Copy, Clone, Default)]
+struct HasKeywordField {
+    r#struct: u32,
+}
+
+struct Generic<r#T>(T);
+
+trait Trait {
+    fn r#trait(&self) -> u32;
+}
+impl Trait for Generic<u32> {
+    fn r#trait(&self) -> u32 {
+        self.0
+    }
+}
+
+pub fn main() {
+    assert_eq!(IntWrapper(1), r#IntWrapper(1));
+
+    match IntWrapper(2) {
+        r#IntWrapper(r#struct) => assert_eq!(2, r#struct),
+    }
+
+    assert_eq!("HasKeywordField { struct: 3 }", format!("{:?}", HasKeywordField { r#struct: 3 }));
+
+    assert_eq!(4, Generic(4).0);
+    assert_eq!(5, Generic(5).r#trait());
+}
diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs
new file mode 100644
index 0000000000000..4bd16ded52fbd
--- /dev/null
+++ b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs
@@ -0,0 +1,48 @@
+// Copyright 2018 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(decl_macro)]
+#![feature(raw_identifiers)]
+
+r#macro_rules! r#struct {
+    ($r#struct:expr) => { $r#struct }
+}
+
+macro_rules! old_macro {
+    ($a:expr) => {$a}
+}
+
+macro r#decl_macro($r#fn:expr) {
+    $r#fn
+}
+
+macro passthrough($id:ident) {
+    $id
+}
+
+macro_rules! test_pat_match {
+    (a) => { 6 };
+    (r#a) => { 7 };
+}
+
+pub fn main() {
+    r#println!("{struct}", r#struct = 1);
+    assert_eq!(2, r#struct!(2));
+    assert_eq!(3, r#old_macro!(3));
+    assert_eq!(4, decl_macro!(4));
+
+    let r#match = 5;
+    assert_eq!(5, passthrough!(r#match));
+
+    assert_eq!("r#struct", stringify!(r#struct));
+
+    assert_eq!(6, test_pat_match!(a));
+    assert_eq!(7, test_pat_match!(r#a));
+}
diff --git a/src/test/run-pass/saturating-float-casts.rs b/src/test/run-pass/saturating-float-casts.rs
index c8fa49c62a0b6..ad3b4b172594e 100644
--- a/src/test/run-pass/saturating-float-casts.rs
+++ b/src/test/run-pass/saturating-float-casts.rs
@@ -11,7 +11,7 @@
 // Tests saturating float->int casts. See u128-as-f32.rs for the opposite direction.
 // compile-flags: -Z saturating-float-casts
 
-#![feature(test, i128, i128_type, stmt_expr_attributes)]
+#![feature(test, stmt_expr_attributes)]
 #![deny(overflowing_literals)]
 extern crate test;
 
diff --git a/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs b/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs
index 1894cd0084bcb..ac6d0c697ecc0 100644
--- a/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs
+++ b/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-emscripten FIXME(#45351) hits an LLVM assert
+
 #![feature(repr_simd, platform_intrinsics)]
 
 #[repr(simd)]
diff --git a/src/test/run-pass/simd-intrinsic-generic-comparison.rs b/src/test/run-pass/simd-intrinsic-generic-comparison.rs
index 5802fb30bd680..d27378ba89308 100644
--- a/src/test/run-pass/simd-intrinsic-generic-comparison.rs
+++ b/src/test/run-pass/simd-intrinsic-generic-comparison.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-emscripten FIXME(#45351) hits an LLVM assert
+
 #![feature(repr_simd, platform_intrinsics, concat_idents)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/run-pass/simd-intrinsic-generic-elements.rs b/src/test/run-pass/simd-intrinsic-generic-elements.rs
index f0444c2717056..72fcef27a665b 100644
--- a/src/test/run-pass/simd-intrinsic-generic-elements.rs
+++ b/src/test/run-pass/simd-intrinsic-generic-elements.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-emscripten FIXME(#45351) hits an LLVM assert
+
 #![feature(repr_simd, platform_intrinsics)]
 
 #[repr(simd)]
diff --git a/src/test/run-pass/simd-intrinsic-generic-select.rs b/src/test/run-pass/simd-intrinsic-generic-select.rs
new file mode 100644
index 0000000000000..8e94d797e8944
--- /dev/null
+++ b/src/test/run-pass/simd-intrinsic-generic-select.rs
@@ -0,0 +1,146 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-emscripten
+
+// Test that the simd_select intrinsics produces correct results.
+
+#![feature(repr_simd, platform_intrinsics)]
+#[allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct i32x4(pub i32, pub i32, pub i32, pub i32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct u32x4(pub u32, pub u32, pub u32, pub u32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct f32x4(pub f32, pub f32, pub f32, pub f32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
+struct b8x4(pub i8, pub i8, pub i8, pub i8);
+
+extern "platform-intrinsic" {
+    fn simd_select<T, U>(x: T, a: U, b: U) -> U;
+}
+
+fn main() {
+    let m0 = b8x4(!0, !0, !0, !0);
+    let m1 = b8x4(0, 0, 0, 0);
+    let m2 = b8x4(!0, !0, 0, 0);
+    let m3 = b8x4(0, 0, !0, !0);
+    let m4 = b8x4(!0, 0, !0, 0);
+
+    unsafe {
+        let a = i32x4(1, -2, 3, 4);
+        let b = i32x4(5, 6, -7, 8);
+
+        let r: i32x4 = simd_select(m0, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: i32x4 = simd_select(m1, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: i32x4 = simd_select(m2, a, b);
+        let e = i32x4(1, -2, -7, 8);
+        assert_eq!(r, e);
+
+        let r: i32x4 = simd_select(m3, a, b);
+        let e = i32x4(5, 6, 3, 4);
+        assert_eq!(r, e);
+
+        let r: i32x4 = simd_select(m4, a, b);
+        let e = i32x4(1, 6, 3, 8);
+        assert_eq!(r, e);
+    }
+
+    unsafe {
+        let a = u32x4(1, 2, 3, 4);
+        let b = u32x4(5, 6, 7, 8);
+
+        let r: u32x4 = simd_select(m0, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select(m1, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select(m2, a, b);
+        let e = u32x4(1, 2, 7, 8);
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select(m3, a, b);
+        let e = u32x4(5, 6, 3, 4);
+        assert_eq!(r, e);
+
+        let r: u32x4 = simd_select(m4, a, b);
+        let e = u32x4(1, 6, 3, 8);
+        assert_eq!(r, e);
+    }
+
+    unsafe {
+        let a = f32x4(1., 2., 3., 4.);
+        let b = f32x4(5., 6., 7., 8.);
+
+        let r: f32x4 = simd_select(m0, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: f32x4 = simd_select(m1, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: f32x4 = simd_select(m2, a, b);
+        let e = f32x4(1., 2., 7., 8.);
+        assert_eq!(r, e);
+
+        let r: f32x4 = simd_select(m3, a, b);
+        let e = f32x4(5., 6., 3., 4.);
+        assert_eq!(r, e);
+
+        let r: f32x4 = simd_select(m4, a, b);
+        let e = f32x4(1., 6., 3., 8.);
+        assert_eq!(r, e);
+    }
+
+    unsafe {
+        let t = !0 as i8;
+        let f = 0 as i8;
+        let a = b8x4(t, f, t, f);
+        let b = b8x4(f, f, f, t);
+
+        let r: b8x4 = simd_select(m0, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: b8x4 = simd_select(m1, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: b8x4 = simd_select(m2, a, b);
+        let e = b8x4(t, f, f, t);
+        assert_eq!(r, e);
+
+        let r: b8x4 = simd_select(m3, a, b);
+        let e = b8x4(f, f, t, f);
+        assert_eq!(r, e);
+
+        let r: b8x4 = simd_select(m4, a, b);
+        let e = b8x4(t, f, t, t);
+        assert_eq!(r, e);
+    }
+}
diff --git a/src/test/run-pass/trailing-comma.rs b/src/test/run-pass/trailing-comma.rs
index b9eda0846537f..02bae5aa45515 100644
--- a/src/test/run-pass/trailing-comma.rs
+++ b/src/test/run-pass/trailing-comma.rs
@@ -10,7 +10,6 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(advanced_slice_patterns,)]
 #![feature(slice_patterns)]
 
 fn f<T,>(_: T,) {}
diff --git a/src/test/run-pass/u128-as-f32.rs b/src/test/run-pass/u128-as-f32.rs
index 117e520155fd1..2848fb2d51a6b 100644
--- a/src/test/run-pass/u128-as-f32.rs
+++ b/src/test/run-pass/u128-as-f32.rs
@@ -10,7 +10,7 @@
 
 // ignore-emscripten u128 not supported
 
-#![feature(test, i128, i128_type)]
+#![feature(test)]
 #![deny(overflowing_literals)]
 extern crate test;
 
diff --git a/src/test/run-pass/u128.rs b/src/test/run-pass/u128.rs
index ebd43a8603386..d649b3b74d39a 100644
--- a/src/test/run-pass/u128.rs
+++ b/src/test/run-pass/u128.rs
@@ -12,7 +12,7 @@
 
 // compile-flags: -Z borrowck=compare
 
-#![feature(i128_type, test)]
+#![feature(test)]
 
 extern crate test;
 use test::black_box as b;
diff --git a/src/test/run-pass/vec-matching-autoslice.rs b/src/test/run-pass/vec-matching-autoslice.rs
index 9df777e7af0dc..7268536a51fad 100644
--- a/src/test/run-pass/vec-matching-autoslice.rs
+++ b/src/test/run-pass/vec-matching-autoslice.rs
@@ -8,9 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![feature(slice_patterns)]
-
 pub fn main() {
     let x = [1, 2, 3];
     match x {
diff --git a/src/test/run-pass/vec-matching-fixed.rs b/src/test/run-pass/vec-matching-fixed.rs
index 1ed6ddc411076..060d152488a97 100644
--- a/src/test/run-pass/vec-matching-fixed.rs
+++ b/src/test/run-pass/vec-matching-fixed.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![feature(advanced_slice_patterns)]
 #![feature(slice_patterns)]
 
 fn a() {
diff --git a/src/test/run-pass/vec-matching-fold.rs b/src/test/run-pass/vec-matching-fold.rs
index ac80a4211ada6..1a30f875580c2 100644
--- a/src/test/run-pass/vec-matching-fold.rs
+++ b/src/test/run-pass/vec-matching-fold.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![feature(advanced_slice_patterns)]
 #![feature(slice_patterns)]
 
 use std::fmt::Debug;
diff --git a/src/test/run-pass/vec-matching.rs b/src/test/run-pass/vec-matching.rs
index bd0731a555cb6..ace418f216068 100644
--- a/src/test/run-pass/vec-matching.rs
+++ b/src/test/run-pass/vec-matching.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![feature(advanced_slice_patterns)]
 #![feature(slice_patterns)]
 
 fn a() {
diff --git a/src/test/run-pass/vec-tail-matching.rs b/src/test/run-pass/vec-tail-matching.rs
index d123eb36a7d4d..4f31405ead500 100644
--- a/src/test/run-pass/vec-tail-matching.rs
+++ b/src/test/run-pass/vec-tail-matching.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-
 #![feature(slice_patterns)]
 
 struct Foo {
diff --git a/src/test/rustdoc/check-styled-link.rs b/src/test/rustdoc/check-styled-link.rs
new file mode 100644
index 0000000000000..1633711e83d9a
--- /dev/null
+++ b/src/test/rustdoc/check-styled-link.rs
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+#![crate_name = "foo"]
+
+pub struct Foo;
+
+// @has foo/struct.Bar.html '//a[@href="../foo/struct.Foo.html"]' 'Foo'
+
+/// Code-styled reference to [`Foo`].
+pub struct Bar;
diff --git a/src/test/rustdoc/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs
index 8499e5c741ee0..ea8a13b034beb 100644
--- a/src/test/rustdoc/doc-cfg.rs
+++ b/src/test/rustdoc/doc-cfg.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![feature(doc_cfg)]
+#![feature(target_feature, cfg_target_feature)]
 
 // @has doc_cfg/struct.Portable.html
 // @!has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' ''
@@ -45,3 +46,26 @@ pub mod unix_only {
         fn unix_and_arm_only_function() {}
     }
 }
+
+// tagging a function with `#[target_feature]` creates a doc(cfg(target_feature)) node for that
+// item as well
+
+// the portability header is different on the module view versus the full view
+// @has doc_cfg/index.html
+// @matches - '//*[@class=" module-item"]//*[@class="stab portability"]' '\Aavx\Z'
+
+// @has doc_cfg/fn.uses_target_feature.html
+// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \
+//        'This is supported with target feature avx only.'
+#[target_feature(enable = "avx")]
+pub unsafe fn uses_target_feature() {
+    content::should::be::irrelevant();
+}
+
+// @has doc_cfg/fn.uses_cfg_target_feature.html
+// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \
+//        'This is supported with target feature avx only.'
+#[doc(cfg(target_feature = "avx"))]
+pub fn uses_cfg_target_feature() {
+    uses_target_feature();
+}
diff --git a/src/test/rustdoc/issue-43869.rs b/src/test/rustdoc/issue-43869.rs
index 554c71500cc8b..a5ed3d892ce92 100644
--- a/src/test/rustdoc/issue-43869.rs
+++ b/src/test/rustdoc/issue-43869.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 pub fn g() -> impl Iterator<Item=u8> {
     Some(1u8).into_iter()
 }
diff --git a/src/test/rustdoc/issue-46976.rs b/src/test/rustdoc/issue-46976.rs
index 0df80fe3bd77a..ce09f62a552d7 100644
--- a/src/test/rustdoc/issue-46976.rs
+++ b/src/test/rustdoc/issue-46976.rs
@@ -8,5 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
 pub fn ice(f: impl Fn()) {}
diff --git a/src/test/rustdoc/link-assoc-const.rs b/src/test/rustdoc/link-assoc-const.rs
new file mode 100644
index 0000000000000..aa7ef07d5c0c3
--- /dev/null
+++ b/src/test/rustdoc/link-assoc-const.rs
@@ -0,0 +1,26 @@
+// Copyright 2018 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.
+
+#![crate_name = "foo"]
+
+// @has foo/index.html '//a[@href="../foo/foo/constant.FIRSTCONST.html"]' 'foo::FIRSTCONST'
+// @has foo/index.html '//a[@href="../foo/struct.Bar.html#associatedconstant.CONST"]' 'Bar::CONST'
+
+//! We have here [`foo::FIRSTCONST`] and [`Bar::CONST`].
+
+pub mod foo {
+    pub const FIRSTCONST: u32 = 42;
+}
+
+pub struct Bar;
+
+impl Bar {
+    pub const CONST: u32 = 42;
+}
diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs
index 0b37f2ed31790..9f860f42266fc 100644
--- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs
+++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs
@@ -20,7 +20,7 @@ where
 
 // @has no_redundancy/struct.Outer.html
 // @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<T> Send for \
-// Outer<T> where T: Copy + Send"
+// Outer<T> where T: Send + Copy"
 pub struct Outer<T> {
     inner_field: Inner<T>,
 }
diff --git a/src/test/rustdoc/universal-impl-trait.rs b/src/test/rustdoc/universal-impl-trait.rs
new file mode 100644
index 0000000000000..4cf99562c5299
--- /dev/null
+++ b/src/test/rustdoc/universal-impl-trait.rs
@@ -0,0 +1,46 @@
+// Copyright 2018 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(universal_impl_trait)]
+#![crate_name = "foo"]
+
+// @has foo/fn.foo.html
+// @has - //pre 'foo('
+// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"'
+// @matches - '_z: .+impl.+trait\.Copy\.html.+, impl.+trait\.Clone\.html'
+pub fn foo(_x: impl Clone, _y: i32, _z: (impl Copy, impl Clone)) {
+}
+
+pub trait Trait {
+    // @has foo/trait.Trait.html
+    // @has - 'method</a>('
+    // @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
+    fn method(&self, _x: impl std::fmt::Debug) {
+    }
+}
+
+pub struct S<T>(T);
+
+impl<T> S<T> {
+    // @has foo/struct.S.html
+    // @has - 'bar</a>('
+    // @matches - '_bar: impl <a class="trait" href="[^"]+/trait\.Copy\.html"'
+    pub fn bar(_bar: impl Copy) {
+    }
+
+    // @has - 'baz</a>('
+    // @matches - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html'
+    pub fn baz(_baz: S<impl Clone>) {
+    }
+}
+
+// @has - 'method</a>('
+// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
+impl<T> Trait for S<T> {}
diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr b/src/test/ui-fulldeps/custom-derive/issue-36935.stderr
index b082999a8978d..0278256994120 100644
--- a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr
+++ b/src/test/ui-fulldeps/custom-derive/issue-36935.stderr
@@ -6,3 +6,5 @@ LL | #[derive(Foo, Bar)] //~ ERROR proc-macro derive panicked
    |
    = help: message: lolnope
 
+error: aborting due to previous error
+
diff --git a/src/test/ui-fulldeps/proc-macro/load-panic.stderr b/src/test/ui-fulldeps/proc-macro/load-panic.stderr
index edfd134469cda..30ad53f9041f0 100644
--- a/src/test/ui-fulldeps/proc-macro/load-panic.stderr
+++ b/src/test/ui-fulldeps/proc-macro/load-panic.stderr
@@ -6,3 +6,5 @@ LL | #[derive(A)]
    |
    = help: message: nope!
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/feature-gate-advanced-slice-features.rs b/src/test/ui/auxiliary/inference_unstable_iterator.rs
similarity index 50%
rename from src/test/ui/feature-gate-advanced-slice-features.rs
rename to src/test/ui/auxiliary/inference_unstable_iterator.rs
index dc9b4e634ab72..b73346e6332ca 100644
--- a/src/test/ui/feature-gate-advanced-slice-features.rs
+++ b/src/test/ui/auxiliary/inference_unstable_iterator.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// gate-test-advanced_slice_patterns
+#![feature(staged_api)]
 
-#![feature(slice_patterns)]
+#![stable(feature = "ipu_iterator", since = "1.0.0")]
 
-fn main() {
-    let x = [ 1, 2, 3, 4, 5 ];
-    match x {
-        [ xs.., 4, 5 ] => {}    //~ ERROR multiple-element slice matches
-        [ 1, xs.., 5 ] => {}    //~ ERROR multiple-element slice matches
-        [ 1, 2, xs.. ] => {}    // OK without feature gate
+#[stable(feature = "ipu_iterator", since = "1.0.0")]
+pub trait IpuIterator {
+    #[unstable(feature = "ipu_flatten", issue = "99999")]
+    fn ipu_flatten(&self) -> u32 {
+        0
     }
 }
+
+#[stable(feature = "ipu_iterator", since = "1.0.0")]
+impl IpuIterator for char {}
diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs b/src/test/ui/auxiliary/inference_unstable_itertools.rs
similarity index 71%
rename from src/test/ui/rfc-2005-default-binding-mode/suggestion.rs
rename to src/test/ui/auxiliary/inference_unstable_itertools.rs
index b9b974ff3c521..2ad264ee3d82f 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs
+++ b/src/test/ui/auxiliary/inference_unstable_itertools.rs
@@ -1,4 +1,4 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
-    if let Some(y) = &Some(22) { //~ ERROR non-reference pattern
-      println!("{}", y);
+pub trait IpuItertools {
+    fn ipu_flatten(&self) -> u32 {
+        1
     }
 }
+
+impl IpuItertools for char {}
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
index 07b268f1a4b01..111968e9c9313 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(advanced_slice_patterns)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(slice_patterns)]
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
index e11702df80a97..6673549e23903 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
@@ -1,5 +1,5 @@
 error[E0506]: cannot assign to `vec[..]` because it is borrowed
-  --> $DIR/borrowck-vec-pattern-nesting.rs:21:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:20:13
    |
 LL |         [box ref _a, _, _] => {
    |              ------ borrow of `vec[..]` occurs here
@@ -8,7 +8,7 @@ LL |             vec[0] = box 4; //~ ERROR cannot assign
    |             ^^^^^^^^^^^^^^ assignment to borrowed `vec[..]` occurs here
 
 error[E0506]: cannot assign to `vec[..]` because it is borrowed
-  --> $DIR/borrowck-vec-pattern-nesting.rs:33:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:32:13
    |
 LL |         &mut [ref _b..] => {
    |               ------ borrow of `vec[..]` occurs here
@@ -17,7 +17,7 @@ LL |             vec[0] = box 4; //~ ERROR cannot assign
    |             ^^^^^^^^^^^^^^ assignment to borrowed `vec[..]` occurs here
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:43:14
+  --> $DIR/borrowck-vec-pattern-nesting.rs:42:14
    |
 LL |           &mut [_a, //~ ERROR cannot move out
    |                ^-- hint: to prevent move, use `ref _a` or `ref mut _a`
@@ -30,7 +30,7 @@ LL | |         ] => {
    | |_________^ cannot move out of here
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:56:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:55:13
    |
 LL |     let a = vec[0]; //~ ERROR cannot move out
    |             ^^^^^^
@@ -39,7 +39,7 @@ LL |     let a = vec[0]; //~ ERROR cannot move out
    |             help: consider using a reference instead: `&vec[0]`
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:64:14
+  --> $DIR/borrowck-vec-pattern-nesting.rs:63:14
    |
 LL |           &mut [ //~ ERROR cannot move out
    |  ______________^
@@ -50,7 +50,7 @@ LL | |          _b] => {}
    |            hint: to prevent move, use `ref _b` or `ref mut _b`
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:69:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:68:13
    |
 LL |     let a = vec[0]; //~ ERROR cannot move out
    |             ^^^^^^
@@ -59,7 +59,7 @@ LL |     let a = vec[0]; //~ ERROR cannot move out
    |             help: consider using a reference instead: `&vec[0]`
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:77:14
+  --> $DIR/borrowck-vec-pattern-nesting.rs:76:14
    |
 LL |         &mut [_a, _b, _c] => {}  //~ ERROR cannot move out
    |              ^--^^--^^--^
@@ -70,7 +70,7 @@ LL |         &mut [_a, _b, _c] => {}  //~ ERROR cannot move out
    |              cannot move out of here
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:81:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:80:13
    |
 LL |     let a = vec[0]; //~ ERROR cannot move out
    |             ^^^^^^
diff --git a/src/test/ui/casts-differing-anon.rs b/src/test/ui/casts-differing-anon.rs
index 74c8ff370f98b..05a03d3b17961 100644
--- a/src/test/ui/casts-differing-anon.rs
+++ b/src/test/ui/casts-differing-anon.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 use std::fmt;
 
 fn foo() -> Box<impl fmt::Debug+?Sized> {
diff --git a/src/test/ui/casts-differing-anon.stderr b/src/test/ui/casts-differing-anon.stderr
index acbff4f73c390..dac24af671cf1 100644
--- a/src/test/ui/casts-differing-anon.stderr
+++ b/src/test/ui/casts-differing-anon.stderr
@@ -1,5 +1,5 @@
 error[E0606]: casting `*mut impl std::fmt::Debug+?Sized` as `*mut impl std::fmt::Debug+?Sized` is invalid
-  --> $DIR/casts-differing-anon.rs:33:13
+  --> $DIR/casts-differing-anon.rs:31:13
    |
 LL |     b_raw = f_raw as *mut _; //~ ERROR is invalid
    |             ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/chalkify/lower_impl.rs b/src/test/ui/chalkify/lower_impl.rs
new file mode 100644
index 0000000000000..2083ada6d2de5
--- /dev/null
+++ b/src/test/ui/chalkify/lower_impl.rs
@@ -0,0 +1,20 @@
+// Copyright 2018 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)]
+
+trait Foo { }
+
+#[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :-
+impl<T: 'static> Foo for T where T: Iterator<Item = i32> { }
+
+fn main() {
+    println!("hello");
+}
diff --git a/src/test/ui/chalkify/lower_impl.stderr b/src/test/ui/chalkify/lower_impl.stderr
new file mode 100644
index 0000000000000..b5d791d640ada
--- /dev/null
+++ b/src/test/ui/chalkify/lower_impl.stderr
@@ -0,0 +1,8 @@
+error: Implemented(T: Foo) :- ProjectionEq(<T as std::iter::Iterator>::Item == i32), TypeOutlives(T : 'static), Implemented(T: std::iter::Iterator), Implemented(T: std::marker::Sized).
+  --> $DIR/lower_impl.rs:15:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/chalkify/lower_trait.rs b/src/test/ui/chalkify/lower_trait.rs
new file mode 100644
index 0000000000000..010cb77edc3f1
--- /dev/null
+++ b/src/test/ui/chalkify/lower_trait.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 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)]
+
+#[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<S, T, U>) :-
+trait Foo<S, T, U> {
+    fn s(S) -> S;
+    fn t(T) -> T;
+    fn u(U) -> U;
+}
+
+fn main() {
+    println!("hello");
+}
diff --git a/src/test/ui/chalkify/lower_trait.stderr b/src/test/ui/chalkify/lower_trait.stderr
new file mode 100644
index 0000000000000..6da1e2fd8edd8
--- /dev/null
+++ b/src/test/ui/chalkify/lower_trait.stderr
@@ -0,0 +1,8 @@
+error: Implemented(Self: Foo<S, T, U>) :- FromEnv(Self: Foo<S, T, U>).
+  --> $DIR/lower_trait.rs:13:1
+   |
+LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<S, T, U>) :-
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr
index 614531c982128..e247e86fbcb22 100644
--- a/src/test/ui/codemap_tests/two_files.stderr
+++ b/src/test/ui/codemap_tests/two_files.stderr
@@ -4,5 +4,6 @@ error[E0404]: expected trait, found type alias `Bar`
 LL | impl Bar for Baz { } //~ ERROR expected trait, found type alias
    |      ^^^ type aliases cannot be used for traits
 
-error: cannot continue compilation due to previous error
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0404`.
diff --git a/src/test/ui/cross-file-errors/main.stderr b/src/test/ui/cross-file-errors/main.stderr
index a9db5214e6a2e..a64595fbb4020 100644
--- a/src/test/ui/cross-file-errors/main.stderr
+++ b/src/test/ui/cross-file-errors/main.stderr
@@ -1,4 +1,4 @@
-error: expected expression, found `_`
+error: expected expression, found reserved identifier `_`
   --> $DIR/underscore.rs:18:9
    |
 LL |         _
@@ -9,3 +9,5 @@ LL |         _
 LL |     underscore!();
    |     -------------- in this macro invocation
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr
index 45dce3d8740d1..169a12ef92e98 100644
--- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr
+++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr
@@ -46,7 +46,7 @@ error[E0223]: ambiguous associated type
 LL | type A = [u8; 4]::AssocTy;
    |          ^^^^^^^^^^^^^^^^ ambiguous associated type
    |
-   = note: specify the type using the syntax `<[u8; <unevaluated[]>] as Trait>::AssocTy`
+   = note: specify the type using the syntax `<[u8; _] as Trait>::AssocTy`
 
 error[E0223]: ambiguous associated type
   --> $DIR/bad-assoc-ty.rs:15:10
diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.rs b/src/test/ui/did_you_mean/recursion_limit_deref.rs
index 3e261ec636c08..f5e75f40fca08 100644
--- a/src/test/ui/did_you_mean/recursion_limit_deref.rs
+++ b/src/test/ui/did_you_mean/recursion_limit_deref.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//~^^^^^^^^^^ ERROR reached the recursion limit
-
 // Test that the recursion limit can be changed and that the compiler
 // suggests a fix. In this case, we have a long chain of Deref impls
 // which will cause an overflow during the autoderef loop.
diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
index 2c8039615572c..20a94f7aac196 100644
--- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
@@ -1,17 +1,13 @@
 error[E0055]: reached the recursion limit while auto-dereferencing I
-  --> $DIR/recursion_limit_deref.rs:62:22
+  --> $DIR/recursion_limit_deref.rs:60:22
    |
 LL |     let x: &Bottom = &t; //~ ERROR mismatched types
    |                      ^^ deref recursion limit reached
    |
    = help: consider adding a `#![recursion_limit="20"]` attribute to your crate
 
-error[E0055]: reached the recursion limit while auto-dereferencing I
-   |
-   = help: consider adding a `#![recursion_limit="20"]` attribute to your crate
-
 error[E0308]: mismatched types
-  --> $DIR/recursion_limit_deref.rs:62:22
+  --> $DIR/recursion_limit_deref.rs:60:22
    |
 LL |     let x: &Bottom = &t; //~ ERROR mismatched types
    |                      ^^ expected struct `Bottom`, found struct `Top`
@@ -19,7 +15,7 @@ LL |     let x: &Bottom = &t; //~ ERROR mismatched types
    = note: expected type `&Bottom`
               found type `&Top`
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 Some errors occurred: E0055, E0308.
 For more information about an error, try `rustc --explain E0055`.
diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.stderr b/src/test/ui/did_you_mean/recursion_limit_macro.stderr
index f6bce55528c7d..265a688df9910 100644
--- a/src/test/ui/did_you_mean/recursion_limit_macro.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit_macro.stderr
@@ -9,3 +9,5 @@ LL |     recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9);
    |
    = help: consider adding a `#![recursion_limit="20"]` attribute to your crate
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/e0119/conflict-with-std.rs b/src/test/ui/e0119/conflict-with-std.rs
index ed9033ad53d56..a9f747d09ec2d 100644
--- a/src/test/ui/e0119/conflict-with-std.rs
+++ b/src/test/ui/e0119/conflict-with-std.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(try_from)]
-
 use std::marker::PhantomData;
 use std::convert::{TryFrom, AsRef};
 
diff --git a/src/test/ui/e0119/conflict-with-std.stderr b/src/test/ui/e0119/conflict-with-std.stderr
index e8b2c84c0df0b..417ff1de3f817 100644
--- a/src/test/ui/e0119/conflict-with-std.stderr
+++ b/src/test/ui/e0119/conflict-with-std.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `std::convert::AsRef<Q>` for type `std::boxed::Box<Q>`:
-  --> $DIR/conflict-with-std.rs:17:1
+  --> $DIR/conflict-with-std.rs:15:1
    |
 LL | impl AsRef<Q> for Box<Q> { //~ ERROR conflicting implementations
    | ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | impl AsRef<Q> for Box<Q> { //~ ERROR conflicting implementations
              where T: ?Sized;
 
 error[E0119]: conflicting implementations of trait `std::convert::From<S>` for type `S`:
-  --> $DIR/conflict-with-std.rs:24:1
+  --> $DIR/conflict-with-std.rs:22:1
    |
 LL | impl From<S> for S { //~ ERROR conflicting implementations
    | ^^^^^^^^^^^^^^^^^^
@@ -18,7 +18,7 @@ LL | impl From<S> for S { //~ ERROR conflicting implementations
            - impl<T> std::convert::From<T> for T;
 
 error[E0119]: conflicting implementations of trait `std::convert::TryFrom<X>` for type `X`:
-  --> $DIR/conflict-with-std.rs:31:1
+  --> $DIR/conflict-with-std.rs:29:1
    |
 LL | impl TryFrom<X> for X { //~ ERROR conflicting implementations
    | ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/error-codes/E0026-teach.stderr b/src/test/ui/error-codes/E0026-teach.stderr
index 63d072fe03d0a..67ea32fba86d6 100644
--- a/src/test/ui/error-codes/E0026-teach.stderr
+++ b/src/test/ui/error-codes/E0026-teach.stderr
@@ -2,7 +2,7 @@ error[E0026]: struct `Thing` does not have a field named `z`
   --> $DIR/E0026-teach.rs:21:23
    |
 LL |         Thing { x, y, z } => {}
-   |                       ^ struct `Thing` does not have field `z`
+   |                       ^ struct `Thing` does not have this field
    |
    = note: This error indicates that a struct pattern attempted to extract a non-existent field from a struct. Struct fields are identified by the name used before the colon : so struct patterns should resemble the declaration of the struct type being matched.
            
diff --git a/src/test/ui/error-codes/E0026.stderr b/src/test/ui/error-codes/E0026.stderr
index af8519511276c..9dabbc8a775fb 100644
--- a/src/test/ui/error-codes/E0026.stderr
+++ b/src/test/ui/error-codes/E0026.stderr
@@ -2,7 +2,7 @@ error[E0026]: struct `Thing` does not have a field named `z`
   --> $DIR/E0026.rs:19:23
    |
 LL |         Thing { x, y, z } => {}
-   |                       ^ struct `Thing` does not have field `z`
+   |                       ^ struct `Thing` does not have this field
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0029-teach.rs b/src/test/ui/error-codes/E0029-teach.rs
index ca85f58133ccd..1bc2c2d58b194 100644
--- a/src/test/ui/error-codes/E0029-teach.rs
+++ b/src/test/ui/error-codes/E0029-teach.rs
@@ -16,7 +16,6 @@ fn main() {
     match s {
         "hello" ... "world" => {}
         //~^ ERROR only char and numeric types are allowed in range patterns
-        //~| ERROR non-reference pattern used to match a reference
         _ => {}
     }
 }
diff --git a/src/test/ui/error-codes/E0029-teach.stderr b/src/test/ui/error-codes/E0029-teach.stderr
index 25d95108f9632..4bb71f68a98b9 100644
--- a/src/test/ui/error-codes/E0029-teach.stderr
+++ b/src/test/ui/error-codes/E0029-teach.stderr
@@ -1,11 +1,3 @@
-error[E0658]: non-reference pattern used to match a reference (see issue #42640)
-  --> $DIR/E0029-teach.rs:17:9
-   |
-LL |         "hello" ... "world" => {}
-   |         ^^^^^^^^^^^^^^^^^^^ help: consider using a reference: `&"hello" ... "world"`
-   |
-   = help: add #![feature(match_default_bindings)] to the crate attributes to enable
-
 error[E0029]: only char and numeric types are allowed in range patterns
   --> $DIR/E0029-teach.rs:17:9
    |
@@ -16,7 +8,6 @@ LL |         "hello" ... "world" => {}
    = note: end type: &'static str
    = note: In a match expression, only numbers and characters can be matched against a range. This is because the compiler checks that the range is non-empty at compile-time, and is unable to evaluate arbitrary comparison functions. If you want to capture values of an orderable type between two end-points, you can use a guard.
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors occurred: E0029, E0658.
-For more information about an error, try `rustc --explain E0029`.
+For more information about this error, try `rustc --explain E0029`.
diff --git a/src/test/ui/error-codes/E0029.rs b/src/test/ui/error-codes/E0029.rs
index 80d215bd327c9..29b6fe4411358 100644
--- a/src/test/ui/error-codes/E0029.rs
+++ b/src/test/ui/error-codes/E0029.rs
@@ -14,7 +14,6 @@ fn main() {
     match s {
         "hello" ... "world" => {}
         //~^ ERROR only char and numeric types are allowed in range patterns
-        //~| ERROR non-reference pattern used to match a reference
         _ => {}
     }
 }
diff --git a/src/test/ui/error-codes/E0029.stderr b/src/test/ui/error-codes/E0029.stderr
index 53c228c6e38c9..bcdfa38711107 100644
--- a/src/test/ui/error-codes/E0029.stderr
+++ b/src/test/ui/error-codes/E0029.stderr
@@ -1,11 +1,3 @@
-error[E0658]: non-reference pattern used to match a reference (see issue #42640)
-  --> $DIR/E0029.rs:15:9
-   |
-LL |         "hello" ... "world" => {}
-   |         ^^^^^^^^^^^^^^^^^^^ help: consider using a reference: `&"hello" ... "world"`
-   |
-   = help: add #![feature(match_default_bindings)] to the crate attributes to enable
-
 error[E0029]: only char and numeric types are allowed in range patterns
   --> $DIR/E0029.rs:15:9
    |
@@ -15,7 +7,6 @@ LL |         "hello" ... "world" => {}
    = note: start type: &'static str
    = note: end type: &'static str
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors occurred: E0029, E0658.
-For more information about an error, try `rustc --explain E0029`.
+For more information about this error, try `rustc --explain E0029`.
diff --git a/src/test/ui/error-codes/E0404.stderr b/src/test/ui/error-codes/E0404.stderr
index 9f705da586167..afb748bedbe0f 100644
--- a/src/test/ui/error-codes/E0404.stderr
+++ b/src/test/ui/error-codes/E0404.stderr
@@ -10,5 +10,6 @@ error[E0404]: expected trait, found struct `Foo`
 LL | fn baz<T: Foo>(_: T) {} //~ ERROR E0404
    |           ^^^ not a trait
 
-error: cannot continue compilation due to previous error
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0404`.
diff --git a/src/test/ui/error-codes/E0405.stderr b/src/test/ui/error-codes/E0405.stderr
index b5901dd9c848b..27190af1c6c11 100644
--- a/src/test/ui/error-codes/E0405.stderr
+++ b/src/test/ui/error-codes/E0405.stderr
@@ -4,5 +4,6 @@ error[E0405]: cannot find trait `SomeTrait` in this scope
 LL | impl SomeTrait for Foo {} //~ ERROR E0405
    |      ^^^^^^^^^ not found in this scope
 
-error: cannot continue compilation due to previous error
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0405`.
diff --git a/src/test/ui/error-codes/E0449.stderr b/src/test/ui/error-codes/E0449.stderr
index 480d8c40022d5..df3b09ba7c9f3 100644
--- a/src/test/ui/error-codes/E0449.stderr
+++ b/src/test/ui/error-codes/E0449.stderr
@@ -2,7 +2,7 @@ error[E0449]: unnecessary visibility qualifier
   --> $DIR/E0449.rs:17:1
    |
 LL | pub impl Bar {} //~ ERROR E0449
-   | ^^^ `pub` not needed here
+   | ^^^ `pub` not permitted here because it's implied
    |
    = note: place qualifiers on individual impl items instead
 
@@ -10,13 +10,13 @@ error[E0449]: unnecessary visibility qualifier
   --> $DIR/E0449.rs:19:1
    |
 LL | pub impl Foo for Bar { //~ ERROR E0449
-   | ^^^ `pub` not needed here
+   | ^^^ `pub` not permitted here because it's implied
 
 error[E0449]: unnecessary visibility qualifier
   --> $DIR/E0449.rs:20:5
    |
 LL |     pub fn foo() {} //~ ERROR E0449
-   |     ^^^ `pub` not needed here
+   |     ^^^ `pub` not permitted here because it's implied
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/error-codes/E0527.rs b/src/test/ui/error-codes/E0527.rs
index 67d222e867e63..a90ccec9cf5e9 100644
--- a/src/test/ui/error-codes/E0527.rs
+++ b/src/test/ui/error-codes/E0527.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns)]
-
 fn main() {
     let r = &[1, 2, 3, 4];
     match r {
diff --git a/src/test/ui/error-codes/E0527.stderr b/src/test/ui/error-codes/E0527.stderr
index 2060f1e69e0ca..1e764c185877b 100644
--- a/src/test/ui/error-codes/E0527.stderr
+++ b/src/test/ui/error-codes/E0527.stderr
@@ -1,5 +1,5 @@
 error[E0527]: pattern requires 2 elements but array has 4
-  --> $DIR/E0527.rs:16:10
+  --> $DIR/E0527.rs:14:10
    |
 LL |         &[a, b] => {
    |          ^^^^^^ expected 4 elements
diff --git a/src/test/ui/error-codes/E0529.rs b/src/test/ui/error-codes/E0529.rs
index 5262ad7b716f5..2459054da89af 100644
--- a/src/test/ui/error-codes/E0529.rs
+++ b/src/test/ui/error-codes/E0529.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slice_patterns)]
-
 fn main() {
     let r: f32 = 1.0;
     match r {
diff --git a/src/test/ui/error-codes/E0529.stderr b/src/test/ui/error-codes/E0529.stderr
index fcada00079066..b2e7ae23fb0eb 100644
--- a/src/test/ui/error-codes/E0529.stderr
+++ b/src/test/ui/error-codes/E0529.stderr
@@ -1,5 +1,5 @@
 error[E0529]: expected an array or slice, found `f32`
-  --> $DIR/E0529.rs:16:9
+  --> $DIR/E0529.rs:14:9
    |
 LL |         [a, b] => {
    |         ^^^^^^ pattern cannot match with input type `f32`
diff --git a/src/test/ui/error-codes/E0657.rs b/src/test/ui/error-codes/E0657.rs
index 31b3acd86ef55..c23aa40ee3790 100644
--- a/src/test/ui/error-codes/E0657.rs
+++ b/src/test/ui/error-codes/E0657.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 #![allow(warnings)]
-#![feature(conservative_impl_trait)]
 
 trait Id<T> {}
 trait Lt<'a> {}
diff --git a/src/test/ui/error-codes/E0657.stderr b/src/test/ui/error-codes/E0657.stderr
index f052914202395..737ae3a163ac2 100644
--- a/src/test/ui/error-codes/E0657.stderr
+++ b/src/test/ui/error-codes/E0657.stderr
@@ -1,11 +1,11 @@
 error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
-  --> $DIR/E0657.rs:20:31
+  --> $DIR/E0657.rs:19:31
    |
 LL |     -> Box<for<'a> Id<impl Lt<'a>>>
    |                               ^^
 
 error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
-  --> $DIR/E0657.rs:29:35
+  --> $DIR/E0657.rs:28:35
    |
 LL |         -> Box<for<'a> Id<impl Lt<'a>>>
    |                                   ^^
diff --git a/src/test/ui/error-codes/E0658.rs b/src/test/ui/error-codes/E0658.rs
index d30068eb1fe2e..dcfa25e528ac3 100644
--- a/src/test/ui/error-codes/E0658.rs
+++ b/src/test/ui/error-codes/E0658.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
-    let _ = ::std::u128::MAX; //~ ERROR E0658
+#[repr(u128)]
+enum Foo { //~ ERROR E0658
+    Bar(u64),
 }
+
+fn main() {}
diff --git a/src/test/ui/error-codes/E0658.stderr b/src/test/ui/error-codes/E0658.stderr
index 5be05600ee51b..b338b384a117e 100644
--- a/src/test/ui/error-codes/E0658.stderr
+++ b/src/test/ui/error-codes/E0658.stderr
@@ -1,10 +1,12 @@
-error[E0658]: use of unstable library feature 'i128' (see issue #35118)
-  --> $DIR/E0658.rs:12:13
+error[E0658]: repr with 128-bit type is unstable (see issue #35118)
+  --> $DIR/E0658.rs:12:1
    |
-LL |     let _ = ::std::u128::MAX; //~ ERROR E0658
-   |             ^^^^^^^^^^^^^^^^
+LL | / enum Foo { //~ ERROR E0658
+LL | |     Bar(u64),
+LL | | }
+   | |_^
    |
-   = help: add #![feature(i128)] to the crate attributes to enable
+   = help: add #![feature(repr128)] to the crate attributes to enable
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gate-advanced-slice-features.stderr b/src/test/ui/feature-gate-advanced-slice-features.stderr
deleted file mode 100644
index 9d9e755497618..0000000000000
--- a/src/test/ui/feature-gate-advanced-slice-features.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0658]: multiple-element slice matches anywhere but at the end of a slice (e.g. `[0, ..xs, 0]`) are experimental (see issue #23121)
-  --> $DIR/feature-gate-advanced-slice-features.rs:18:9
-   |
-LL |         [ xs.., 4, 5 ] => {}    //~ ERROR multiple-element slice matches
-   |         ^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(advanced_slice_patterns)] to the crate attributes to enable
-
-error[E0658]: multiple-element slice matches anywhere but at the end of a slice (e.g. `[0, ..xs, 0]`) are experimental (see issue #23121)
-  --> $DIR/feature-gate-advanced-slice-features.rs:19:9
-   |
-LL |         [ 1, xs.., 5 ] => {}    //~ ERROR multiple-element slice matches
-   |         ^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(advanced_slice_patterns)] to the crate attributes to enable
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-clone-closures.stderr b/src/test/ui/feature-gate-clone-closures.stderr
deleted file mode 100644
index 7038a76380d6b..0000000000000
--- a/src/test/ui/feature-gate-clone-closures.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0599]: no method named `clone` found for type `[closure@$DIR/feature-gate-clone-closures.rs:16:17: 18:6 a:_]` in the current scope
-  --> $DIR/feature-gate-clone-closures.rs:20:23
-   |
-LL |     let hello = hello.clone(); //~ ERROR no method named `clone` found for type
-   |                       ^^^^^
-   |
-   = note: hello is a function, perhaps you wish to call it
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/feature-gate-conservative_impl_trait.stderr b/src/test/ui/feature-gate-conservative_impl_trait.stderr
deleted file mode 100644
index 5400226450bfc..0000000000000
--- a/src/test/ui/feature-gate-conservative_impl_trait.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: `impl Trait` in return position is experimental (see issue #34511)
-  --> $DIR/feature-gate-conservative_impl_trait.rs:11:13
-   |
-LL | fn foo() -> impl Fn() { || {} }
-   |             ^^^^^^^^^
-   |
-   = help: add #![feature(conservative_impl_trait)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-copy-closures.stderr b/src/test/ui/feature-gate-copy-closures.stderr
deleted file mode 100644
index e72680b69eaea..0000000000000
--- a/src/test/ui/feature-gate-copy-closures.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0382]: use of moved value: `hello`
-  --> $DIR/feature-gate-copy-closures.rs:18:9
-   |
-LL |     let b = hello;
-   |         - value moved here
-LL |     let c = hello; //~ ERROR use of moved value: `hello` [E0382]
-   |         ^ value used here after move
-   |
-   = note: move occurs because `hello` has type `[closure@$DIR/feature-gate-copy-closures.rs:13:17: 15:6 a:&i32]`, which does not implement the `Copy` trait
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr
index a9952ff4fac13..a2c1dedff385a 100644
--- a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr
+++ b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr
@@ -4,3 +4,5 @@ error: compilation successful
 LL | fn main() {} //~ ERROR compilation successful
    | ^^^^^^^^^^^^
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/feature-gate-fn_must_use.stderr b/src/test/ui/feature-gate-fn_must_use.stderr
index 4772cf28f6c12..431c57abd2653 100644
--- a/src/test/ui/feature-gate-fn_must_use.stderr
+++ b/src/test/ui/feature-gate-fn_must_use.stderr
@@ -20,3 +20,5 @@ error: compilation successful
 LL | fn main() {} //~ ERROR compilation successful
    | ^^^^^^^^^^^^
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/feature-gate-i128_type.stderr b/src/test/ui/feature-gate-i128_type.stderr
deleted file mode 100644
index eb3b29f4f5594..0000000000000
--- a/src/test/ui/feature-gate-i128_type.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0658]: 128-bit integers are not stable (see issue #35118)
-  --> $DIR/feature-gate-i128_type.rs:12:5
-   |
-LL |     0i128; //~ ERROR 128-bit integers are not stable
-   |     ^^^^^
-   |
-   = help: add #![feature(i128_type)] to the crate attributes to enable
-
-error[E0658]: 128-bit integers are not stable (see issue #35118)
-  --> $DIR/feature-gate-i128_type.rs:16:5
-   |
-LL |     0u128; //~ ERROR 128-bit integers are not stable
-   |     ^^^^^
-   |
-   = help: add #![feature(i128_type)] to the crate attributes to enable
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-i128_type2.rs b/src/test/ui/feature-gate-i128_type2.rs
deleted file mode 100644
index 8a7d316ed8384..0000000000000
--- a/src/test/ui/feature-gate-i128_type2.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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.
-
-// gate-test-i128_type
-
-fn test1() -> i128 { //~ ERROR 128-bit type is unstable
-    0
-}
-
-fn test1_2() -> u128 { //~ ERROR 128-bit type is unstable
-    0
-}
-
-fn test3() {
-    let x: i128 = 0; //~ ERROR 128-bit type is unstable
-}
-
-fn test3_2() {
-    let x: u128 = 0; //~ ERROR 128-bit type is unstable
-}
-
-#[repr(u128)]
-enum A { //~ ERROR 128-bit type is unstable
-    A(u64)
-}
-
-fn main() {}
diff --git a/src/test/ui/feature-gate-i128_type2.stderr b/src/test/ui/feature-gate-i128_type2.stderr
deleted file mode 100644
index 23d4d6c98d90a..0000000000000
--- a/src/test/ui/feature-gate-i128_type2.stderr
+++ /dev/null
@@ -1,45 +0,0 @@
-error[E0658]: 128-bit type is unstable (see issue #35118)
-  --> $DIR/feature-gate-i128_type2.rs:13:15
-   |
-LL | fn test1() -> i128 { //~ ERROR 128-bit type is unstable
-   |               ^^^^
-   |
-   = help: add #![feature(i128_type)] to the crate attributes to enable
-
-error[E0658]: 128-bit type is unstable (see issue #35118)
-  --> $DIR/feature-gate-i128_type2.rs:17:17
-   |
-LL | fn test1_2() -> u128 { //~ ERROR 128-bit type is unstable
-   |                 ^^^^
-   |
-   = help: add #![feature(i128_type)] to the crate attributes to enable
-
-error[E0658]: 128-bit type is unstable (see issue #35118)
-  --> $DIR/feature-gate-i128_type2.rs:22:12
-   |
-LL |     let x: i128 = 0; //~ ERROR 128-bit type is unstable
-   |            ^^^^
-   |
-   = help: add #![feature(i128_type)] to the crate attributes to enable
-
-error[E0658]: 128-bit type is unstable (see issue #35118)
-  --> $DIR/feature-gate-i128_type2.rs:26:12
-   |
-LL |     let x: u128 = 0; //~ ERROR 128-bit type is unstable
-   |            ^^^^
-   |
-   = help: add #![feature(i128_type)] to the crate attributes to enable
-
-error[E0658]: repr with 128-bit type is unstable (see issue #35118)
-  --> $DIR/feature-gate-i128_type2.rs:30:1
-   |
-LL | / enum A { //~ ERROR 128-bit type is unstable
-LL | |     A(u64)
-LL | | }
-   | |_^
-   |
-   = help: add #![feature(repr128)] to the crate attributes to enable
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-clone-closures.rs b/src/test/ui/feature-gate-in_band_lifetimes-impl.rs
similarity index 66%
rename from src/test/ui/feature-gate-clone-closures.rs
rename to src/test/ui/feature-gate-in_band_lifetimes-impl.rs
index a15153ea7bf0a..a02b3e800097e 100644
--- a/src/test/ui/feature-gate-clone-closures.rs
+++ b/src/test/ui/feature-gate-in_band_lifetimes-impl.rs
@@ -8,14 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Clone)]
-struct S(i32);
+#![allow(warnings)]
+#![feature(underscore_lifetimes)]
 
-fn main() {
-    let a = S(5);
-    let hello = move || {
-        println!("Hello {}", a.0);
-    };
+trait MyTrait<'a> { }
 
-    let hello = hello.clone(); //~ ERROR no method named `clone` found for type
-}
+impl<'a> MyTrait<'a> for &u32 { }
+//~^ ERROR missing lifetime specifier
+
+impl<'a> MyTrait<'_> for &'a f32 { }
+//~^ ERROR missing lifetime specifier
+
+fn main() {}
diff --git a/src/test/ui/feature-gate-in_band_lifetimes-impl.stderr b/src/test/ui/feature-gate-in_band_lifetimes-impl.stderr
new file mode 100644
index 0000000000000..e32a06c3ce456
--- /dev/null
+++ b/src/test/ui/feature-gate-in_band_lifetimes-impl.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/feature-gate-in_band_lifetimes-impl.rs:16:26
+   |
+LL | impl<'a> MyTrait<'a> for &u32 { }
+   |                          ^ expected lifetime parameter
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/feature-gate-in_band_lifetimes-impl.rs:19:18
+   |
+LL | impl<'a> MyTrait<'_> for &'a f32 { }
+   |                  ^^ expected lifetime parameter
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/feature-gate-match_default_bindings.stderr b/src/test/ui/feature-gate-match_default_bindings.stderr
deleted file mode 100644
index 8fa553561de20..0000000000000
--- a/src/test/ui/feature-gate-match_default_bindings.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: non-reference pattern used to match a reference (see issue #42640)
-  --> $DIR/feature-gate-match_default_bindings.rs:13:9
-   |
-LL |         Some(n) => {},
-   |         ^^^^^^^ help: consider using a reference: `&Some(n)`
-   |
-   = help: add #![feature(match_default_bindings)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/generator/unsafe-immovable.rs b/src/test/ui/feature-gate-raw-identifiers.rs
similarity index 68%
rename from src/test/ui/generator/unsafe-immovable.rs
rename to src/test/ui/feature-gate-raw-identifiers.rs
index 45acbf50931bc..38024feb432d9 100644
--- a/src/test/ui/generator/unsafe-immovable.rs
+++ b/src/test/ui/feature-gate-raw-identifiers.rs
@@ -1,4 +1,4 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,10 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(generators)]
-
 fn main() {
-    static || { //~ ERROR: construction of immovable generator requires unsafe
-        yield;
-    };
+    let r#foo = 3; //~ ERROR raw identifiers are experimental and subject to change
+    println!("{}", foo);
 }
diff --git a/src/test/ui/feature-gate-raw-identifiers.stderr b/src/test/ui/feature-gate-raw-identifiers.stderr
new file mode 100644
index 0000000000000..02eff7247c47b
--- /dev/null
+++ b/src/test/ui/feature-gate-raw-identifiers.stderr
@@ -0,0 +1,11 @@
+error[E0658]: raw identifiers are experimental and subject to change (see issue #48589)
+  --> $DIR/feature-gate-raw-identifiers.rs:12:9
+   |
+LL |     let r#foo = 3; //~ ERROR raw identifiers are experimental and subject to change
+   |         ^^^^^
+   |
+   = help: add #![feature(raw_identifiers)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-slice-patterns.rs b/src/test/ui/feature-gate-slice-patterns.rs
index 625cb2d351553..fd058f6517211 100644
--- a/src/test/ui/feature-gate-slice-patterns.rs
+++ b/src/test/ui/feature-gate-slice-patterns.rs
@@ -8,11 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test that slice pattern syntax is gated by `slice_patterns` feature gate
+// Test that slice pattern syntax with `..` is gated by `slice_patterns` feature gate
 
 fn main() {
     let x = [1, 2, 3, 4, 5];
     match x {
-        [1, 2, xs..] => {} //~ ERROR slice pattern syntax is experimental
+        [1, 2, ..] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+        [1, .., 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+        [.., 4, 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+    }
+
+    let x = [ 1, 2, 3, 4, 5 ];
+    match x {
+        [ xs.., 4, 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+        [ 1, xs.., 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+        [ 1, 2, xs.. ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
     }
 }
diff --git a/src/test/ui/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gate-slice-patterns.stderr
index 7c216fad933e3..d560dcd54eefb 100644
--- a/src/test/ui/feature-gate-slice-patterns.stderr
+++ b/src/test/ui/feature-gate-slice-patterns.stderr
@@ -1,11 +1,51 @@
-error[E0658]: slice pattern syntax is experimental (see issue #23121)
-  --> $DIR/feature-gate-slice-patterns.rs:16:9
+error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121)
+  --> $DIR/feature-gate-slice-patterns.rs:16:16
    |
-LL |         [1, 2, xs..] => {} //~ ERROR slice pattern syntax is experimental
-   |         ^^^^^^^^^^^^
+LL |         [1, 2, ..] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+   |                ^^
    |
    = help: add #![feature(slice_patterns)] to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121)
+  --> $DIR/feature-gate-slice-patterns.rs:17:13
+   |
+LL |         [1, .., 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+   |             ^^
+   |
+   = help: add #![feature(slice_patterns)] to the crate attributes to enable
+
+error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121)
+  --> $DIR/feature-gate-slice-patterns.rs:18:10
+   |
+LL |         [.., 4, 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+   |          ^^
+   |
+   = help: add #![feature(slice_patterns)] to the crate attributes to enable
+
+error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121)
+  --> $DIR/feature-gate-slice-patterns.rs:23:11
+   |
+LL |         [ xs.., 4, 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+   |           ^^
+   |
+   = help: add #![feature(slice_patterns)] to the crate attributes to enable
+
+error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121)
+  --> $DIR/feature-gate-slice-patterns.rs:24:14
+   |
+LL |         [ 1, xs.., 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+   |              ^^
+   |
+   = help: add #![feature(slice_patterns)] to the crate attributes to enable
+
+error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121)
+  --> $DIR/feature-gate-slice-patterns.rs:25:17
+   |
+LL |         [ 1, 2, xs.. ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+   |                 ^^
+   |
+   = help: add #![feature(slice_patterns)] to the crate attributes to enable
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-universal.stderr b/src/test/ui/feature-gate-universal.stderr
deleted file mode 100644
index dc1a6b29c72c6..0000000000000
--- a/src/test/ui/feature-gate-universal.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: `impl Trait` in argument position is experimental (see issue #34511)
-  --> $DIR/feature-gate-universal.rs:13:11
-   |
-LL | fn foo(x: impl std::fmt::Debug) { print!("{:?}", x); }
-   |           ^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(universal_impl_trait)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-wasm_custom_section.rs b/src/test/ui/feature-gate-wasm_custom_section.rs
new file mode 100644
index 0000000000000..c695ef4ff068f
--- /dev/null
+++ b/src/test/ui/feature-gate-wasm_custom_section.rs
@@ -0,0 +1,14 @@
+// Copyright 2018 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.
+
+#[wasm_custom_section = "foo"] //~ ERROR: attribute is currently unstable
+const A: [u8; 2] = [1, 2];
+
+fn main() {}
diff --git a/src/test/ui/feature-gate-wasm_custom_section.stderr b/src/test/ui/feature-gate-wasm_custom_section.stderr
new file mode 100644
index 0000000000000..1b4415539f449
--- /dev/null
+++ b/src/test/ui/feature-gate-wasm_custom_section.stderr
@@ -0,0 +1,11 @@
+error[E0658]: attribute is currently unstable
+  --> $DIR/feature-gate-wasm_custom_section.rs:11:1
+   |
+LL | #[wasm_custom_section = "foo"] //~ ERROR: attribute is currently unstable
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(wasm_custom_section)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-conservative_impl_trait.rs b/src/test/ui/feature-gate-wasm_import_module.rs
similarity index 72%
rename from src/test/ui/feature-gate-conservative_impl_trait.rs
rename to src/test/ui/feature-gate-wasm_import_module.rs
index 7a3ae639bfc89..c5898a9c12697 100644
--- a/src/test/ui/feature-gate-conservative_impl_trait.rs
+++ b/src/test/ui/feature-gate-wasm_import_module.rs
@@ -1,4 +1,4 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo() -> impl Fn() { || {} }
-//~^ ERROR `impl Trait` in return position is experimental
+#[wasm_import_module = "test"] //~ ERROR: experimental
+extern {
+}
 
 fn main() {}
diff --git a/src/test/ui/feature-gate-wasm_import_module.stderr b/src/test/ui/feature-gate-wasm_import_module.stderr
new file mode 100644
index 0000000000000..bae5fa9d5956c
--- /dev/null
+++ b/src/test/ui/feature-gate-wasm_import_module.stderr
@@ -0,0 +1,11 @@
+error[E0658]: experimental attribute
+  --> $DIR/feature-gate-wasm_import_module.rs:11:1
+   |
+LL | #[wasm_import_module = "test"] //~ ERROR: experimental
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(wasm_import_module)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
index 9c4fb79f6f1aa..0beed62798710 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
@@ -1316,3 +1316,5 @@ LL | |     println!("Hello World");
 LL | | }
    | |_^
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr
index 83f6e016370bb..802c5d9384d75 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr
@@ -6,3 +6,5 @@ LL | |     println!("Hello World");
 LL | | }
    | |_^
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr
index cd83915fe82d3..dd78baf927509 100644
--- a/src/test/ui/generator/auto-trait-regions.stderr
+++ b/src/test/ui/generator/auto-trait-regions.stderr
@@ -1,15 +1,15 @@
-error[E0277]: the trait bound `No: Foo` is not satisfied in `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`
+error[E0277]: the trait bound `No: Foo` is not satisfied in `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`
   --> $DIR/auto-trait-regions.rs:40:5
    |
 LL |     assert_foo(gen); //~ ERROR the trait bound `No: Foo` is not satisfied
-   |     ^^^^^^^^^^ within `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`, the trait `Foo` is not implemented for `No`
+   |     ^^^^^^^^^^ within `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`, the trait `Foo` is not implemented for `No`
    |
    = help: the following implementations were found:
              <No as Foo>
    = note: required because it appears within the type `OnlyFooIfStaticRef`
    = note: required because it appears within the type `&OnlyFooIfStaticRef`
    = note: required because it appears within the type `for<'r> {&'r OnlyFooIfStaticRef, ()}`
-   = note: required because it appears within the type `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`
+   = note: required because it appears within the type `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`
 note: required by `assert_foo`
   --> $DIR/auto-trait-regions.rs:30:1
    |
diff --git a/src/test/ui/generator/borrowing.rs b/src/test/ui/generator/borrowing.rs
index de10bdef4aee0..e56927d818231 100644
--- a/src/test/ui/generator/borrowing.rs
+++ b/src/test/ui/generator/borrowing.rs
@@ -15,7 +15,7 @@ use std::ops::Generator;
 fn main() {
     let _b = {
         let a = 3;
-        (|| yield &a).resume()
+        unsafe { (|| yield &a).resume() }
         //~^ ERROR: `a` does not live long enough
     };
 
diff --git a/src/test/ui/generator/borrowing.stderr b/src/test/ui/generator/borrowing.stderr
index 2a5de3790ada9..45d950b5aef64 100644
--- a/src/test/ui/generator/borrowing.stderr
+++ b/src/test/ui/generator/borrowing.stderr
@@ -1,10 +1,10 @@
 error[E0597]: `a` does not live long enough
-  --> $DIR/borrowing.rs:18:20
+  --> $DIR/borrowing.rs:18:29
    |
-LL |         (|| yield &a).resume()
-   |          --        ^ borrowed value does not live long enough
-   |          |
-   |          capture occurs here
+LL |         unsafe { (|| yield &a).resume() }
+   |                   --        ^ borrowed value does not live long enough
+   |                   |
+   |                   capture occurs here
 LL |         //~^ ERROR: `a` does not live long enough
 LL |     };
    |     - borrowed value only lives until here
diff --git a/src/test/ui/generator/dropck.rs b/src/test/ui/generator/dropck.rs
index 0b143d7f5143e..b2240fb225f58 100644
--- a/src/test/ui/generator/dropck.rs
+++ b/src/test/ui/generator/dropck.rs
@@ -23,6 +23,6 @@ fn main() {
         let _d = ref_.take(); //~ ERROR `ref_` does not live long enough
         yield;
     };
-    gen.resume();
+    unsafe { gen.resume(); }
     // drops the RefCell and then the Ref, leading to use-after-free
 }
diff --git a/src/test/ui/generator/sized-yield.rs b/src/test/ui/generator/sized-yield.rs
index f38ebf8b94636..a1c8ca77e41e8 100644
--- a/src/test/ui/generator/sized-yield.rs
+++ b/src/test/ui/generator/sized-yield.rs
@@ -17,5 +17,5 @@ fn main() {
    let mut gen = move || { //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
        yield s[..];
    };
-   gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+   unsafe { gen.resume(); } //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
 }
diff --git a/src/test/ui/generator/sized-yield.stderr b/src/test/ui/generator/sized-yield.stderr
index fc99c7e3bd747..957fac172c258 100644
--- a/src/test/ui/generator/sized-yield.stderr
+++ b/src/test/ui/generator/sized-yield.stderr
@@ -11,10 +11,10 @@ LL | |    };
    = note: the yield type of a generator must have a statically known size
 
 error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
-  --> $DIR/sized-yield.rs:20:8
+  --> $DIR/sized-yield.rs:20:17
    |
-LL |    gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
-   |        ^^^^^^ `str` does not have a constant size known at compile-time
+LL |    unsafe { gen.resume(); } //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+   |                 ^^^^^^ `str` does not have a constant size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
 
diff --git a/src/test/ui/generator/unsafe-immovable.stderr b/src/test/ui/generator/unsafe-immovable.stderr
deleted file mode 100644
index b2add55613d54..0000000000000
--- a/src/test/ui/generator/unsafe-immovable.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0133]: construction of immovable generator requires unsafe function or block
-  --> $DIR/unsafe-immovable.rs:14:5
-   |
-LL | /     static || { //~ ERROR: construction of immovable generator requires unsafe
-LL | |         yield;
-LL | |     };
-   | |_____^ construction of immovable generator
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/generator/yield-while-iterating.rs b/src/test/ui/generator/yield-while-iterating.rs
index bc53448cb08e6..b8a67a0e7b65d 100644
--- a/src/test/ui/generator/yield-while-iterating.rs
+++ b/src/test/ui/generator/yield-while-iterating.rs
@@ -43,7 +43,7 @@ fn yield_during_iter_borrowed_slice_2() {
     println!("{:?}", x);
 }
 
-fn yield_during_iter_borrowed_slice_3() {
+unsafe fn yield_during_iter_borrowed_slice_3() {
     // OK to take a mutable ref to `x` and yield
     // up pointers from it:
     let mut x = vec![22_i32];
@@ -55,7 +55,7 @@ fn yield_during_iter_borrowed_slice_3() {
     b.resume();
 }
 
-fn yield_during_iter_borrowed_slice_4() {
+unsafe fn yield_during_iter_borrowed_slice_4() {
     // ...but not OK to do that while reading
     // from `x` too
     let mut x = vec![22_i32];
@@ -68,7 +68,7 @@ fn yield_during_iter_borrowed_slice_4() {
     b.resume();
 }
 
-fn yield_during_range_iter() {
+unsafe fn yield_during_range_iter() {
     // Should be OK.
     let mut b = || {
         let v = vec![1,2,3];
diff --git a/src/test/ui/generator/yield-while-local-borrowed.rs b/src/test/ui/generator/yield-while-local-borrowed.rs
index 11bd4ed05caca..3dc2650a2ecbf 100644
--- a/src/test/ui/generator/yield-while-local-borrowed.rs
+++ b/src/test/ui/generator/yield-while-local-borrowed.rs
@@ -15,7 +15,7 @@
 use std::ops::{GeneratorState, Generator};
 use std::cell::Cell;
 
-fn borrow_local_inline() {
+unsafe fn borrow_local_inline() {
     // Not OK to yield with a borrow of a temporary.
     //
     // (This error occurs because the region shows up in the type of
@@ -30,7 +30,7 @@ fn borrow_local_inline() {
     b.resume();
 }
 
-fn borrow_local_inline_done() {
+unsafe fn borrow_local_inline_done() {
     // No error here -- `a` is not in scope at the point of `yield`.
     let mut b = move || {
         {
@@ -41,7 +41,7 @@ fn borrow_local_inline_done() {
     b.resume();
 }
 
-fn borrow_local() {
+unsafe fn borrow_local() {
     // Not OK to yield with a borrow of a temporary.
     //
     // (This error occurs because the region shows up in the type of
diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.rs b/src/test/ui/generator/yield-while-ref-reborrowed.rs
index b9c963ae74077..573dd4377bb2c 100644
--- a/src/test/ui/generator/yield-while-ref-reborrowed.rs
+++ b/src/test/ui/generator/yield-while-ref-reborrowed.rs
@@ -13,7 +13,7 @@
 use std::ops::{GeneratorState, Generator};
 use std::cell::Cell;
 
-fn reborrow_shared_ref(x: &i32) {
+unsafe fn reborrow_shared_ref(x: &i32) {
     // This is OK -- we have a borrow live over the yield, but it's of
     // data that outlives the generator.
     let mut b = move || {
@@ -24,7 +24,7 @@ fn reborrow_shared_ref(x: &i32) {
     b.resume();
 }
 
-fn reborrow_mutable_ref(x: &mut i32) {
+unsafe fn reborrow_mutable_ref(x: &mut i32) {
     // This is OK -- we have a borrow live over the yield, but it's of
     // data that outlives the generator.
     let mut b = move || {
@@ -35,7 +35,7 @@ fn reborrow_mutable_ref(x: &mut i32) {
     b.resume();
 }
 
-fn reborrow_mutable_ref_2(x: &mut i32) {
+unsafe fn reborrow_mutable_ref_2(x: &mut i32) {
     // ...but not OK to go on using `x`.
     let mut b = || {
         let a = &mut *x;
diff --git a/src/test/ui/param-bounds-ignored.rs b/src/test/ui/higher-lifetime-bounds.rs
similarity index 77%
rename from src/test/ui/param-bounds-ignored.rs
rename to src/test/ui/higher-lifetime-bounds.rs
index 94bcdec945035..70b3b34fbd8fc 100644
--- a/src/test/ui/param-bounds-ignored.rs
+++ b/src/test/ui/higher-lifetime-bounds.rs
@@ -10,31 +10,7 @@
 
 #![allow(dead_code, non_camel_case_types)]
 
-use std::rc::Rc;
-
-type SVec<T: Send+Send> = Vec<T>;
-//~^ WARN bounds on generic parameters are ignored in type aliases
-type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>;
-//~^ WARN bounds on generic parameters are ignored in type aliases
-type WVec<'b, T: 'b+'b> = Vec<T>;
-//~^ WARN bounds on generic parameters are ignored in type aliases
-type W2Vec<'b, T> where T: 'b, T: 'b = Vec<T>;
-//~^ WARN where clauses are ignored in type aliases
-
-fn foo<'a>(y: &'a i32) {
-    // If the bounds above would matter, the code below would be rejected.
-    let mut x : SVec<_> = Vec::new();
-    x.push(Rc::new(42));
-
-    let mut x : VVec<'static, 'a> = Vec::new();
-    x.push(y);
-
-    let mut x : WVec<'static, & 'a i32> = Vec::new();
-    x.push(y);
-
-    let mut x : W2Vec<'static, & 'a i32> = Vec::new();
-    x.push(y);
-}
+// Test that bounds on higher-kinded lifetime binders are rejected.
 
 fn bar1<'a, 'b>(
     x: &'a i32,
diff --git a/src/test/ui/param-bounds-ignored.stderr b/src/test/ui/higher-lifetime-bounds.stderr
similarity index 61%
rename from src/test/ui/param-bounds-ignored.stderr
rename to src/test/ui/higher-lifetime-bounds.stderr
index 657fec54f9608..82c0074743604 100644
--- a/src/test/ui/param-bounds-ignored.stderr
+++ b/src/test/ui/higher-lifetime-bounds.stderr
@@ -1,94 +1,68 @@
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:42:22
+  --> $DIR/higher-lifetime-bounds.rs:18:22
    |
 LL |     f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32)
    |                      ^^^ ^^^
 
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:50:34
+  --> $DIR/higher-lifetime-bounds.rs:26:34
    |
 LL | fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>(
    |                                  ^^^
 
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:65:28
+  --> $DIR/higher-lifetime-bounds.rs:41:28
    |
 LL |     where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32
    |                            ^^^
 
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:77:25
+  --> $DIR/higher-lifetime-bounds.rs:53:25
    |
 LL |     where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32
    |                         ^^^
 
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:85:28
+  --> $DIR/higher-lifetime-bounds.rs:61:28
    |
 LL | struct S1<F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>(F);
    |                            ^^^
 
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:87:40
+  --> $DIR/higher-lifetime-bounds.rs:63:40
    |
 LL | struct S2<F>(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32;
    |                                        ^^^
 
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:89:37
+  --> $DIR/higher-lifetime-bounds.rs:65:37
    |
 LL | struct S3<F>(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32;
    |                                     ^^^
 
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:92:29
+  --> $DIR/higher-lifetime-bounds.rs:68:29
    |
 LL | struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32);
    |                             ^^^
 
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:95:29
+  --> $DIR/higher-lifetime-bounds.rs:71:29
    |
 LL | type T1 = Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>;
    |                             ^^^
 
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:99:34
+  --> $DIR/higher-lifetime-bounds.rs:75:34
    |
 LL |     let _ : Option<for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32> = None;
    |                                  ^^^
 
 error: lifetime bounds cannot be used in this context
-  --> $DIR/param-bounds-ignored.rs:101:38
+  --> $DIR/higher-lifetime-bounds.rs:77:38
    |
 LL |     let _ : Option<Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None;
    |                                      ^^^
 
-warning: bounds on generic parameters are ignored in type aliases
-  --> $DIR/param-bounds-ignored.rs:15:14
-   |
-LL | type SVec<T: Send+Send> = Vec<T>;
-   |              ^^^^ ^^^^
-   |
-   = note: #[warn(ignored_generic_bounds)] on by default
-
-warning: bounds on generic parameters are ignored in type aliases
-  --> $DIR/param-bounds-ignored.rs:17:19
-   |
-LL | type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>;
-   |                   ^^ ^^
-
-warning: bounds on generic parameters are ignored in type aliases
-  --> $DIR/param-bounds-ignored.rs:19:18
-   |
-LL | type WVec<'b, T: 'b+'b> = Vec<T>;
-   |                  ^^ ^^
-
-warning: where clauses are ignored in type aliases
-  --> $DIR/param-bounds-ignored.rs:21:25
-   |
-LL | type W2Vec<'b, T> where T: 'b, T: 'b = Vec<T>;
-   |                         ^^^^^  ^^^^^
-
 error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs
index 5a6aac43ec770..99a7dd5e7852b 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.rs
+++ b/src/test/ui/impl-trait/auto-trait-leak.rs
@@ -10,8 +10,6 @@
 
 // ignore-tidy-linelength
 
-#![feature(conservative_impl_trait)]
-
 use std::cell::Cell;
 use std::rc::Rc;
 
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index 71ca8675db4ef..ca639f1076d3c 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -1,56 +1,56 @@
 error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
-  --> $DIR/auto-trait-leak.rs:27:5
+  --> $DIR/auto-trait-leak.rs:25:5
    |
 LL |     send(before());
    |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
    |
    = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
-   = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:21:5: 21:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
+   = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:19:5: 19:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
    = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
 note: required by `send`
-  --> $DIR/auto-trait-leak.rs:24:1
+  --> $DIR/auto-trait-leak.rs:22:1
    |
 LL | fn send<T: Send>(_: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
-  --> $DIR/auto-trait-leak.rs:30:5
+  --> $DIR/auto-trait-leak.rs:28:5
    |
 LL |     send(after());
    |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
    |
    = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
-   = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:38:5: 38:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
+   = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:36:5: 36:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
    = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
 note: required by `send`
-  --> $DIR/auto-trait-leak.rs:24:1
+  --> $DIR/auto-trait-leak.rs:22:1
    |
 LL | fn send<T: Send>(_: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0391]: cyclic dependency detected
-  --> $DIR/auto-trait-leak.rs:44:1
+  --> $DIR/auto-trait-leak.rs:42:1
    |
 LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic reference
    |
 note: the cycle begins when processing `cycle1`...
-  --> $DIR/auto-trait-leak.rs:44:1
+  --> $DIR/auto-trait-leak.rs:42:1
    |
 LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which then requires processing `cycle2::{{impl-Trait}}`...
-  --> $DIR/auto-trait-leak.rs:52:16
+  --> $DIR/auto-trait-leak.rs:50:16
    |
 LL | fn cycle2() -> impl Clone {
    |                ^^^^^^^^^^
 note: ...which then requires processing `cycle2`...
-  --> $DIR/auto-trait-leak.rs:52:1
+  --> $DIR/auto-trait-leak.rs:50:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which then requires processing `cycle1::{{impl-Trait}}`...
-  --> $DIR/auto-trait-leak.rs:44:16
+  --> $DIR/auto-trait-leak.rs:42:16
    |
 LL | fn cycle1() -> impl Clone {
    |                ^^^^^^^^^^
diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs
index 9d9d4cef3119a..b65e477f21f90 100644
--- a/src/test/ui/impl-trait/equality.rs
+++ b/src/test/ui/impl-trait/equality.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait, specialization)]
+#![feature(specialization)]
 
 trait Foo: Copy + ToString {}
 
diff --git a/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs b/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs
new file mode 100644
index 0000000000000..78ae922c75126
--- /dev/null
+++ b/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs
@@ -0,0 +1,30 @@
+// 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.
+
+// In contrast to `region-escape-via-bound-invariant`, in this case we
+// *can* return a value of type `&'x u32`, even though `'x` does not
+// appear in the bounds. This is because `&` is contravariant, and so
+// we are *actually* returning a `&'y u32`.
+//
+// See https://github.com/rust-lang/rust/issues/46541 for more details.
+
+// run-pass
+
+#![allow(dead_code)]
+#![feature(in_band_lifetimes)]
+#![feature(nll)]
+
+fn foo(x: &'x u32) -> impl Fn() -> &'y u32
+where 'x: 'y
+{
+    move || x
+}
+
+fn main() { }
diff --git a/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs b/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs
new file mode 100644
index 0000000000000..972461c2ffd96
--- /dev/null
+++ b/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs
@@ -0,0 +1,34 @@
+// 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.
+
+// In contrast to `region-escape-via-bound-invariant`, in this case we
+// *can* return a value of type `&'x u32`, even though `'x` does not
+// appear in the bounds. This is because `&` is contravariant, and so
+// we are *actually* returning a `&'y u32`.
+//
+// See https://github.com/rust-lang/rust/issues/46541 for more details.
+
+// run-pass
+
+#![allow(dead_code)]
+#![feature(in_band_lifetimes)]
+#![feature(nll)]
+
+trait Trait<'a> { }
+
+impl Trait<'b> for &'a u32 { }
+
+fn foo(x: &'x u32) -> impl Trait<'y>
+where 'x: 'y
+{
+    x
+}
+
+fn main() { }
diff --git a/src/test/ui/impl-trait/region-escape-via-bound.rs b/src/test/ui/impl-trait/region-escape-via-bound.rs
new file mode 100644
index 0000000000000..e73f15606dc5a
--- /dev/null
+++ b/src/test/ui/impl-trait/region-escape-via-bound.rs
@@ -0,0 +1,33 @@
+// 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.
+
+// Test that we do not allow the region `'x` to escape in the impl
+// trait **even though** `'y` escapes, which outlives `'x`.
+//
+// See https://github.com/rust-lang/rust/issues/46541 for more details.
+
+#![allow(dead_code)]
+#![feature(in_band_lifetimes)]
+#![feature(nll)]
+
+use std::cell::Cell;
+
+trait Trait<'a> { }
+
+impl Trait<'b> for Cell<&'a u32> { }
+
+fn foo(x: Cell<&'x u32>) -> impl Trait<'y>
+    //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0909]
+where 'x: 'y
+{
+    x
+}
+
+fn main() { }
diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr
new file mode 100644
index 0000000000000..4281a4c10adfa
--- /dev/null
+++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr
@@ -0,0 +1,20 @@
+error[E0909]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/region-escape-via-bound.rs:26:29
+   |
+LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y>
+   |                             ^^^^^^^^^^^^^^
+   |
+note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 26:1
+  --> $DIR/region-escape-via-bound.rs:26:1
+   |
+LL | / fn foo(x: Cell<&'x u32>) -> impl Trait<'y>
+LL | |     //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0909]
+LL | | where 'x: 'y
+LL | | {
+LL | |     x
+LL | | }
+   | |_^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0909`.
diff --git a/src/test/ui/impl-trait/universal-mismatched-type.rs b/src/test/ui/impl-trait/universal-mismatched-type.rs
index 00fc22ff0d853..6a62eb36c303c 100644
--- a/src/test/ui/impl-trait/universal-mismatched-type.rs
+++ b/src/test/ui/impl-trait/universal-mismatched-type.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
-
 use std::fmt::Debug;
 
 fn foo(x: impl Debug) -> String {
diff --git a/src/test/ui/impl-trait/universal-mismatched-type.stderr b/src/test/ui/impl-trait/universal-mismatched-type.stderr
index 64f1aff13bdba..031db511ff30d 100644
--- a/src/test/ui/impl-trait/universal-mismatched-type.stderr
+++ b/src/test/ui/impl-trait/universal-mismatched-type.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/universal-mismatched-type.rs:16:5
+  --> $DIR/universal-mismatched-type.rs:14:5
    |
 LL | fn foo(x: impl Debug) -> String {
    |                          ------ expected `std::string::String` because of return type
diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.rs b/src/test/ui/impl-trait/universal-two-impl-traits.rs
index 9a4847b56062a..5ecef1fee65d1 100644
--- a/src/test/ui/impl-trait/universal-two-impl-traits.rs
+++ b/src/test/ui/impl-trait/universal-two-impl-traits.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
-
 use std::fmt::Debug;
 
 fn foo(x: impl Debug, y: impl Debug) -> String {
diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.stderr b/src/test/ui/impl-trait/universal-two-impl-traits.stderr
index 61f52ff25fb18..ed406895fc699 100644
--- a/src/test/ui/impl-trait/universal-two-impl-traits.stderr
+++ b/src/test/ui/impl-trait/universal-two-impl-traits.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/universal-two-impl-traits.rs:17:9
+  --> $DIR/universal-two-impl-traits.rs:15:9
    |
 LL |     a = y; //~ ERROR mismatched
    |         ^ expected type parameter, found a different type parameter
diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.rs b/src/test/ui/impl-trait/universal_wrong_bounds.rs
index 36d9f615c5f57..a5e948223fb1c 100644
--- a/src/test/ui/impl-trait/universal_wrong_bounds.rs
+++ b/src/test/ui/impl-trait/universal_wrong_bounds.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(universal_impl_trait)]
-
 use std::fmt::Display;
 
 fn foo(f: impl Display + Clone) -> String {
diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.stderr b/src/test/ui/impl-trait/universal_wrong_bounds.stderr
index a02fc1f748faa..02ac4707bc555 100644
--- a/src/test/ui/impl-trait/universal_wrong_bounds.stderr
+++ b/src/test/ui/impl-trait/universal_wrong_bounds.stderr
@@ -1,11 +1,11 @@
 error[E0425]: cannot find function `wants_clone` in this scope
-  --> $DIR/universal_wrong_bounds.rs:18:5
+  --> $DIR/universal_wrong_bounds.rs:16:5
    |
 LL |     wants_clone(f); //~ ERROR cannot find
    |     ^^^^^^^^^^^ did you mean `wants_cone`?
 
 error[E0405]: cannot find trait `Debug` in this scope
-  --> $DIR/universal_wrong_bounds.rs:21:24
+  --> $DIR/universal_wrong_bounds.rs:19:24
    |
 LL | fn wants_debug(g: impl Debug) { } //~ ERROR cannot find
    |                        ^^^^^ not found in this scope
@@ -15,7 +15,7 @@ LL | use std::fmt::Debug;
    |
 
 error[E0405]: cannot find trait `Debug` in this scope
-  --> $DIR/universal_wrong_bounds.rs:22:26
+  --> $DIR/universal_wrong_bounds.rs:20:26
    |
 LL | fn wants_display(g: impl Debug) { } //~ ERROR cannot find
    |                          ^^^^^ not found in this scope
@@ -24,5 +24,7 @@ help: possible candidate is found in another module, you can import it into scop
 LL | use std::fmt::Debug;
    |
 
-error: cannot continue compilation due to previous error
+error: aborting due to 3 previous errors
 
+Some errors occurred: E0405, E0425.
+For more information about an error, try `rustc --explain E0405`.
diff --git a/src/test/ui/impl_trait_projections.rs b/src/test/ui/impl_trait_projections.rs
index f69a78b1450f1..6a72794227109 100644
--- a/src/test/ui/impl_trait_projections.rs
+++ b/src/test/ui/impl_trait_projections.rs
@@ -7,7 +7,7 @@
 // <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(dyn_trait, conservative_impl_trait, universal_impl_trait)]
+#![feature(dyn_trait)]
 
 use std::fmt::Debug;
 use std::option;
diff --git a/src/test/ui/in-band-lifetimes/E0687_where.rs b/src/test/ui/in-band-lifetimes/E0687_where.rs
index ac67558772007..c1b268eac701c 100644
--- a/src/test/ui/in-band-lifetimes/E0687_where.rs
+++ b/src/test/ui/in-band-lifetimes/E0687_where.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![allow(warnings)]
-#![feature(in_band_lifetimes, universal_impl_trait)]
+#![feature(in_band_lifetimes)]
 
 fn bar<F>(x: &F) where F: Fn(&'a u32) {} //~ ERROR must be explicitly
 
diff --git a/src/test/ui/in-band-lifetimes/impl/assoc-type.rs b/src/test/ui/in-band-lifetimes/impl/assoc-type.rs
new file mode 100644
index 0000000000000..54f38b2e729b1
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/assoc-type.rs
@@ -0,0 +1,38 @@
+// Copyright 2018 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.
+
+// Test that we do not yet support elision in associated types, even
+// when there is just one name we could take from the impl header.
+
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait {
+    type Output;
+}
+
+impl MyTrait for &i32 {
+    type Output = &i32;
+    //~^ ERROR missing lifetime specifier
+}
+
+impl MyTrait for &u32 {
+    type Output = &'_ i32;
+    //~^ ERROR missing lifetime specifier
+}
+
+// This is what you have to do:
+impl MyTrait for &'a f32 {
+    type Output = &'a f32;
+}
+
+fn main() { }
diff --git a/src/test/ui/in-band-lifetimes/impl/assoc-type.stderr b/src/test/ui/in-band-lifetimes/impl/assoc-type.stderr
new file mode 100644
index 0000000000000..909b86daef0fc
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/assoc-type.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/assoc-type.rs:24:19
+   |
+LL |     type Output = &i32;
+   |                   ^ expected lifetime parameter
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/assoc-type.rs:29:20
+   |
+LL |     type Output = &'_ i32;
+   |                    ^^ expected lifetime parameter
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.rs b/src/test/ui/in-band-lifetimes/impl/dyn-trait.rs
new file mode 100644
index 0000000000000..e839248b0e317
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.rs
@@ -0,0 +1,45 @@
+// Copyright 2018 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.
+
+// Test that `impl MyTrait<'_> for &i32` is equivalent to `impl<'a,
+// 'b> MyTrait<'a> for &'b i32`.
+
+#![allow(warnings)]
+
+#![feature(dyn_trait)]
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+use std::fmt::Debug;
+
+// Equivalent to `Box<dyn Debug + 'static>`:
+trait StaticTrait { }
+impl StaticTrait for Box<dyn Debug> { }
+
+// Equivalent to `Box<dyn Debug + 'static>`:
+trait NotStaticTrait { }
+impl NotStaticTrait for Box<dyn Debug + '_> { }
+
+fn static_val<T: StaticTrait>(_: T) {
+}
+
+fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
+    static_val(x); //~ ERROR cannot infer
+}
+
+fn not_static_val<T: NotStaticTrait>(_: T) {
+}
+
+fn with_dyn_debug_not_static<'a>(x: Box<dyn Debug + 'a>) {
+    not_static_val(x); // OK
+}
+
+fn main() {
+}
diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr b/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr
new file mode 100644
index 0000000000000..0054ca3d1a5bf
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr
@@ -0,0 +1,22 @@
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+  --> $DIR/dyn-trait.rs:34:16
+   |
+LL |     static_val(x); //~ ERROR cannot infer
+   |                ^
+   |
+note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 33:1...
+  --> $DIR/dyn-trait.rs:33:1
+   |
+LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...so that the expression is assignable:
+           expected std::boxed::Box<std::fmt::Debug>
+              found std::boxed::Box<std::fmt::Debug + 'a>
+   = note: but, the lifetime must be valid for the static lifetime...
+   = note: ...so that the types are compatible:
+           expected StaticTrait
+              found StaticTrait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/in-band-lifetimes/impl/path-elided.rs b/src/test/ui/in-band-lifetimes/impl/path-elided.rs
new file mode 100644
index 0000000000000..fa1b45238895f
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/path-elided.rs
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait { }
+
+struct Foo<'a> { x: &'a u32 }
+
+impl MyTrait for Foo {
+    //~^ ERROR missing lifetime specifier
+}
+
+fn main() {}
diff --git a/src/test/ui/in-band-lifetimes/impl/path-elided.stderr b/src/test/ui/in-band-lifetimes/impl/path-elided.stderr
new file mode 100644
index 0000000000000..19e69c61a0337
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/path-elided.stderr
@@ -0,0 +1,9 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/path-elided.rs:19:18
+   |
+LL | impl MyTrait for Foo {
+   |                  ^^^ expected lifetime parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/in-band-lifetimes/impl/path-underscore.rs b/src/test/ui/in-band-lifetimes/impl/path-underscore.rs
new file mode 100644
index 0000000000000..56f2d93d9e0a9
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/path-underscore.rs
@@ -0,0 +1,47 @@
+// Copyright 2018 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.
+
+// Test that `impl MyTrait for Foo<'_>` works.
+
+// run-pass
+
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait { }
+
+struct Foo<'a> { x: &'a u32 }
+
+impl MyTrait for Foo<'_> {
+}
+
+fn impls_my_trait<T: MyTrait>() { }
+
+fn impls_my_trait_val<T: MyTrait>(_: T) {
+    impls_my_trait::<T>();
+}
+
+fn random_where_clause()
+where for<'a> Foo<'a>: MyTrait { }
+
+fn main() {
+    let x = 22;
+    let f = Foo { x: &x };
+
+    // This type is `Foo<'x>` for a local lifetime `'x`; so the impl
+    // must apply to any lifetime to apply to this.
+    impls_my_trait_val(f);
+
+    impls_my_trait::<Foo<'static>>();
+
+    random_where_clause();
+}
diff --git a/src/test/ui/in-band-lifetimes/impl/ref-underscore.rs b/src/test/ui/in-band-lifetimes/impl/ref-underscore.rs
new file mode 100644
index 0000000000000..1b1035abeba36
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/ref-underscore.rs
@@ -0,0 +1,43 @@
+// Copyright 2018 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.
+
+// Test that `impl MyTrait for &i32` works and is equivalent to any lifetime.
+
+// run-pass
+
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait { }
+
+impl MyTrait for &i32 {
+}
+
+fn impls_my_trait<T: MyTrait>() { }
+
+fn impls_my_trait_val<T: MyTrait>(_: T) {
+    impls_my_trait::<T>();
+}
+
+fn random_where_clause()
+where for<'a> &'a i32: MyTrait { }
+
+fn main() {
+    let x = 22;
+    let f = &x;
+
+    impls_my_trait_val(f);
+
+    impls_my_trait::<&'static i32>();
+
+    random_where_clause();
+}
diff --git a/src/test/ui/in-band-lifetimes/impl/trait-elided.rs b/src/test/ui/in-band-lifetimes/impl/trait-elided.rs
new file mode 100644
index 0000000000000..7594d66e07839
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/trait-elided.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait<'a> { }
+
+impl MyTrait for u32 {
+    //~^ ERROR missing lifetime specifier
+}
+
+fn main() {}
diff --git a/src/test/ui/in-band-lifetimes/impl/trait-elided.stderr b/src/test/ui/in-band-lifetimes/impl/trait-elided.stderr
new file mode 100644
index 0000000000000..bb301882868a4
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/trait-elided.stderr
@@ -0,0 +1,9 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/trait-elided.rs:17:6
+   |
+LL | impl MyTrait for u32 {
+   |      ^^^^^^^ expected lifetime parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/in-band-lifetimes/impl/trait-underscore.rs b/src/test/ui/in-band-lifetimes/impl/trait-underscore.rs
new file mode 100644
index 0000000000000..077e33c1efde2
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/impl/trait-underscore.rs
@@ -0,0 +1,48 @@
+// Copyright 2018 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.
+
+// Test that `impl MyTrait<'_> for &i32` is equivalent to `impl<'a,
+// 'b> MyTrait<'a> for &'b i32`.
+//
+// run-pass
+
+#![allow(warnings)]
+
+#![feature(in_band_lifetimes)]
+#![feature(underscore_lifetimes)]
+
+trait MyTrait<'a> { }
+
+// This is equivalent to `MyTrait<'a> for &'b i32`, which is proven by
+// the code below.
+impl MyTrait<'_> for &i32 {
+}
+
+// When called, T will be `&'x i32` for some `'x`, so since we can
+// prove that `&'x i32: for<'a> MyTrait<'a>, then we know that the
+// lifetime parameter above is disconnected.
+fn impls_my_trait<T: for<'a> MyTrait<'a>>() { }
+
+fn impls_my_trait_val<T: for<'a> MyTrait<'a>>(_: T) {
+    impls_my_trait::<T>();
+}
+
+fn random_where_clause()
+where for<'a, 'b> &'a i32: MyTrait<'b> { }
+
+fn main() {
+    let x = 22;
+    let f = &x;
+    impls_my_trait_val(f);
+
+    impls_my_trait::<&'static i32>();
+
+    random_where_clause();
+}
diff --git a/src/test/ui/inference-variable-behind-raw-pointer.stderr b/src/test/ui/inference-variable-behind-raw-pointer.stderr
index eb40151615dad..fe6dc0b07482f 100644
--- a/src/test/ui/inference-variable-behind-raw-pointer.stderr
+++ b/src/test/ui/inference-variable-behind-raw-pointer.stderr
@@ -5,6 +5,6 @@ LL |     if data.is_null() {}
    |             ^^^^^^^
    |
    = note: #[warn(tyvar_behind_raw_pointer)] on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 epoch!
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
    = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
 
diff --git a/src/test/ui/inference_unstable.rs b/src/test/ui/inference_unstable.rs
new file mode 100644
index 0000000000000..816c443a06c21
--- /dev/null
+++ b/src/test/ui/inference_unstable.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+// Ensures #[unstable] functions without opting in the corresponding #![feature]
+// will not break inference.
+
+// aux-build:inference_unstable_iterator.rs
+// aux-build:inference_unstable_itertools.rs
+// run-pass
+
+extern crate inference_unstable_iterator;
+extern crate inference_unstable_itertools;
+
+#[allow(unused_imports)]
+use inference_unstable_iterator::IpuIterator;
+use inference_unstable_itertools::IpuItertools;
+
+fn main() {
+    assert_eq!('x'.ipu_flatten(), 1);
+    //~^ WARN a method with this name may be added to the standard library in the future
+    //~^^ WARN once this method is added to the standard library, there will be ambiguity here
+}
diff --git a/src/test/ui/inference_unstable.stderr b/src/test/ui/inference_unstable.stderr
new file mode 100644
index 0000000000000..9c614d659d36f
--- /dev/null
+++ b/src/test/ui/inference_unstable.stderr
@@ -0,0 +1,12 @@
+warning: a method with this name may be added to the standard library in the future
+  --> $DIR/inference_unstable.rs:26:20
+   |
+LL |     assert_eq!('x'.ipu_flatten(), 1);
+   |                    ^^^^^^^^^^^
+   |
+   = note: #[warn(unstable_name_collision)] on by default
+   = warning: once this method is added to the standard library, there will be ambiguity here, which will cause a hard error!
+   = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
+   = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_flatten(...)` to keep using the current method
+   = note: add #![feature(ipu_flatten)] to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten`
+
diff --git a/src/test/ui/inference_unstable_featured.rs b/src/test/ui/inference_unstable_featured.rs
new file mode 100644
index 0000000000000..f5c49bedc7117
--- /dev/null
+++ b/src/test/ui/inference_unstable_featured.rs
@@ -0,0 +1,27 @@
+// Copyright 2018 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.
+
+// There should be E0034 "multiple applicable items in scope" if we opt-in for
+// the feature.
+
+// aux-build:inference_unstable_iterator.rs
+// aux-build:inference_unstable_itertools.rs
+
+#![feature(ipu_flatten)]
+
+extern crate inference_unstable_iterator;
+extern crate inference_unstable_itertools;
+
+use inference_unstable_iterator::IpuIterator;
+use inference_unstable_itertools::IpuItertools;
+
+fn main() {
+    assert_eq!('x'.ipu_flatten(), 0);   //~ ERROR E0034
+}
diff --git a/src/test/ui/inference_unstable_featured.stderr b/src/test/ui/inference_unstable_featured.stderr
new file mode 100644
index 0000000000000..cb5f3623291b5
--- /dev/null
+++ b/src/test/ui/inference_unstable_featured.stderr
@@ -0,0 +1,12 @@
+error[E0034]: multiple applicable items in scope
+  --> $DIR/inference_unstable_featured.rs:26:20
+   |
+LL |     assert_eq!('x'.ipu_flatten(), 0);   //~ ERROR E0034
+   |                    ^^^^^^^^^^^ multiple `ipu_flatten` found
+   |
+   = note: candidate #1 is defined in an impl of the trait `inference_unstable_iterator::IpuIterator` for the type `char`
+   = note: candidate #2 is defined in an impl of the trait `inference_unstable_itertools::IpuItertools` for the type `char`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0034`.
diff --git a/src/test/ui/inference_unstable_forced.rs b/src/test/ui/inference_unstable_forced.rs
new file mode 100644
index 0000000000000..82ce4034ce269
--- /dev/null
+++ b/src/test/ui/inference_unstable_forced.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+// If the unstable API is the only possible solution,
+// still emit E0658 "use of unstable library feature".
+
+// aux-build:inference_unstable_iterator.rs
+
+extern crate inference_unstable_iterator;
+
+use inference_unstable_iterator::IpuIterator;
+
+fn main() {
+    assert_eq!('x'.ipu_flatten(), 0);   //~ ERROR E0658
+}
diff --git a/src/test/ui/inference_unstable_forced.stderr b/src/test/ui/inference_unstable_forced.stderr
new file mode 100644
index 0000000000000..00eb81cd9a239
--- /dev/null
+++ b/src/test/ui/inference_unstable_forced.stderr
@@ -0,0 +1,11 @@
+error[E0658]: use of unstable library feature 'ipu_flatten' (see issue #99999)
+  --> $DIR/inference_unstable_forced.rs:21:20
+   |
+LL |     assert_eq!('x'.ipu_flatten(), 0);   //~ ERROR E0658
+   |                    ^^^^^^^^^^^
+   |
+   = help: add #![feature(ipu_flatten)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/issue-22644.stderr b/src/test/ui/issue-22644.stderr
index 257b9bd235d76..aeb465b2ab233 100644
--- a/src/test/ui/issue-22644.stderr
+++ b/src/test/ui/issue-22644.stderr
@@ -89,3 +89,5 @@ error: expected type, found `4`
 LL |     println!("{}", a: &mut 4); //~ ERROR expected type, found `4`
    |                            ^ expecting a type here because of type ascription
 
+error: aborting due to 9 previous errors
+
diff --git a/src/test/ui/issue-23217.stderr b/src/test/ui/issue-23217.stderr
index be9ec9d73c21c..d542a10e9b605 100644
--- a/src/test/ui/issue-23217.stderr
+++ b/src/test/ui/issue-23217.stderr
@@ -5,6 +5,8 @@ LL | pub enum SomeEnum {
    | ----------------- variant `A` not found here
 LL |     B = SomeEnum::A,
    |         ^^^^^^^^^^^ variant not found in `SomeEnum`
+   |
+   = note: did you mean `variant::B`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-28971.stderr b/src/test/ui/issue-28971.stderr
index 81d8d97963bd0..df114351ff571 100644
--- a/src/test/ui/issue-28971.stderr
+++ b/src/test/ui/issue-28971.stderr
@@ -6,6 +6,8 @@ LL | enum Foo {
 ...
 LL |             Foo::Baz(..) => (),
    |             ^^^^^^^^^^^^ variant not found in `Foo`
+   |
+   = note: did you mean `variant::Bar`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-35869.rs b/src/test/ui/issue-35869.rs
index 17ee62aed1b88..7bab22edcf684 100644
--- a/src/test/ui/issue-35869.rs
+++ b/src/test/ui/issue-35869.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(conservative_impl_trait)]
-
 trait Foo {
     fn foo(_: fn(u8) -> ());
     fn bar(_: Option<u8>);
diff --git a/src/test/ui/issue-35869.stderr b/src/test/ui/issue-35869.stderr
index fa971c111a408..1930dd5bbcb8e 100644
--- a/src/test/ui/issue-35869.stderr
+++ b/src/test/ui/issue-35869.stderr
@@ -1,5 +1,5 @@
 error[E0053]: method `foo` has an incompatible type for trait
-  --> $DIR/issue-35869.rs:23:15
+  --> $DIR/issue-35869.rs:21:15
    |
 LL |     fn foo(_: fn(u8) -> ());
    |               ------------ type in trait
@@ -11,7 +11,7 @@ LL |     fn foo(_: fn(u16) -> ()) {}
               found type `fn(fn(u16))`
 
 error[E0053]: method `bar` has an incompatible type for trait
-  --> $DIR/issue-35869.rs:25:15
+  --> $DIR/issue-35869.rs:23:15
    |
 LL |     fn bar(_: Option<u8>);
    |               ---------- type in trait
@@ -23,7 +23,7 @@ LL |     fn bar(_: Option<u16>) {}
               found type `fn(std::option::Option<u16>)`
 
 error[E0053]: method `baz` has an incompatible type for trait
-  --> $DIR/issue-35869.rs:27:15
+  --> $DIR/issue-35869.rs:25:15
    |
 LL |     fn baz(_: (u8, u16));
    |               --------- type in trait
@@ -35,7 +35,7 @@ LL |     fn baz(_: (u16, u16)) {}
               found type `fn((u16, u16))`
 
 error[E0053]: method `qux` has an incompatible type for trait
-  --> $DIR/issue-35869.rs:29:17
+  --> $DIR/issue-35869.rs:27:17
    |
 LL |     fn qux() -> u8;
    |                 -- type in trait
diff --git a/src/test/ui/issue-44406.stderr b/src/test/ui/issue-44406.stderr
index 443b28cf09968..de7c11732e4a3 100644
--- a/src/test/ui/issue-44406.stderr
+++ b/src/test/ui/issue-44406.stderr
@@ -13,3 +13,5 @@ LL |         bar(baz: $rest)
 LL |     foo!(true); //~ ERROR expected type, found keyword
    |          ^^^^ expecting a type here because of type ascription
 
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/issue-47184.rs b/src/test/ui/issue-47184.rs
new file mode 100644
index 0000000000000..0831b7e0af8e2
--- /dev/null
+++ b/src/test/ui/issue-47184.rs
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(nll)]
+
+fn main() {
+    let _vec: Vec<&'static String> = vec![&String::new()];
+    //~^ ERROR borrowed value does not live long enough [E0597]
+}
diff --git a/src/test/ui/issue-47184.stderr b/src/test/ui/issue-47184.stderr
new file mode 100644
index 0000000000000..a9eb33f01e3e0
--- /dev/null
+++ b/src/test/ui/issue-47184.stderr
@@ -0,0 +1,14 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/issue-47184.rs:14:44
+   |
+LL |     let _vec: Vec<&'static String> = vec![&String::new()];
+   |                                            ^^^^^^^^^^^^^ temporary value does not live long enough
+LL |     //~^ ERROR borrowed value does not live long enough [E0597]
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/issue-49040.rs b/src/test/ui/issue-49040.rs
new file mode 100644
index 0000000000000..866ecd9e1d951
--- /dev/null
+++ b/src/test/ui/issue-49040.rs
@@ -0,0 +1,12 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]; //~ ERROR expected item, found `;`
+fn main() {}
diff --git a/src/test/ui/issue-49040.stderr b/src/test/ui/issue-49040.stderr
new file mode 100644
index 0000000000000..b6f624dac7db6
--- /dev/null
+++ b/src/test/ui/issue-49040.stderr
@@ -0,0 +1,8 @@
+error: expected item, found `;`
+  --> $DIR/issue-49040.rs:11:28
+   |
+LL | #![allow(unused_variables)]; //~ ERROR expected item, found `;`
+   |                            ^ help: consider removing this semicolon
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issue-49257.rs b/src/test/ui/issue-49257.rs
new file mode 100644
index 0000000000000..a319849223740
--- /dev/null
+++ b/src/test/ui/issue-49257.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+// Test for #49257:
+// emits good diagnostics for `..` pattern fragments not in the last position.
+
+#![allow(unused)]
+
+struct Point { x: u8, y: u8 }
+
+fn main() {
+    let p = Point { x: 0, y: 0 };
+    let Point { .., y } = p; //~ ERROR expected `}`, found `,`
+    //~| ERROR pattern does not mention fields `x`, `y`
+}
diff --git a/src/test/ui/issue-49257.stderr b/src/test/ui/issue-49257.stderr
new file mode 100644
index 0000000000000..fec990764bb14
--- /dev/null
+++ b/src/test/ui/issue-49257.stderr
@@ -0,0 +1,15 @@
+error: expected `}`, found `,`
+  --> $DIR/issue-49257.rs:20:19
+   |
+LL |     let Point { .., y } = p; //~ ERROR expected `}`, found `,`
+   |                   ^ `..` must be in the last position, and cannot have a trailing comma
+
+error[E0027]: pattern does not mention fields `x`, `y`
+  --> $DIR/issue-49257.rs:20:9
+   |
+LL |     let Point { .., y } = p; //~ ERROR expected `}`, found `,`
+   |         ^^^^^^^^^^^^^^^ missing fields `x`, `y`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0027`.
diff --git a/src/test/ui/lint-ctypes.rs b/src/test/ui/lint-ctypes.rs
index 77cb1ef0f5130..85957831653e7 100644
--- a/src/test/ui/lint-ctypes.rs
+++ b/src/test/ui/lint-ctypes.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![deny(improper_ctypes)]
-#![feature(libc, i128_type, repr_transparent)]
+#![feature(libc, repr_transparent)]
 
 extern crate libc;
 
diff --git a/src/test/ui/lint-output-format-2.stderr b/src/test/ui/lint-output-format-2.stderr
index b2d1e1ac05822..d484061ef9661 100644
--- a/src/test/ui/lint-output-format-2.stderr
+++ b/src/test/ui/lint-output-format-2.stderr
@@ -22,3 +22,5 @@ LL | |     let _y = bar();
 LL | | }
    | |_^
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/type-overflow.rs b/src/test/ui/lint/type-overflow.rs
index 495989587e585..30e6fb2883b8b 100644
--- a/src/test/ui/lint/type-overflow.rs
+++ b/src/test/ui/lint/type-overflow.rs
@@ -10,8 +10,6 @@
 
 // must-compile-successfully
 
-#![feature(i128_type)]
-
 fn main() {
     let error = 255i8; //~WARNING literal out of range for i8
 
diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr
index d3fcb1335e209..6f5d3d07aea2d 100644
--- a/src/test/ui/lint/type-overflow.stderr
+++ b/src/test/ui/lint/type-overflow.stderr
@@ -1,5 +1,5 @@
 warning: literal out of range for i8
-  --> $DIR/type-overflow.rs:16:17
+  --> $DIR/type-overflow.rs:14:17
    |
 LL |     let error = 255i8; //~WARNING literal out of range for i8
    |                 ^^^^^
@@ -7,7 +7,7 @@ LL |     let error = 255i8; //~WARNING literal out of range for i8
    = note: #[warn(overflowing_literals)] on by default
 
 warning: literal out of range for i8
-  --> $DIR/type-overflow.rs:21:16
+  --> $DIR/type-overflow.rs:19:16
    |
 LL |     let fail = 0b1000_0001i8; //~WARNING literal out of range for i8
    |                ^^^^^^^^^^^^^ help: consider using `u8` instead: `0b1000_0001u8`
@@ -15,7 +15,7 @@ LL |     let fail = 0b1000_0001i8; //~WARNING literal out of range for i8
    = note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8`
 
 warning: literal out of range for i64
-  --> $DIR/type-overflow.rs:23:16
+  --> $DIR/type-overflow.rs:21:16
    |
 LL |     let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64
    |                ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x8000_0000_0000_0000u64`
@@ -23,7 +23,7 @@ LL |     let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range fo
    = note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64`
 
 warning: literal out of range for u32
-  --> $DIR/type-overflow.rs:25:16
+  --> $DIR/type-overflow.rs:23:16
    |
 LL |     let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32
    |                ^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x1_FFFF_FFFFu64`
@@ -31,7 +31,7 @@ LL |     let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32
    = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32`
 
 warning: literal out of range for i128
-  --> $DIR/type-overflow.rs:27:22
+  --> $DIR/type-overflow.rs:25:22
    |
 LL |     let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000;
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL |     let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000;
    = help: consider using `u128` instead
 
 warning: literal out of range for i32
-  --> $DIR/type-overflow.rs:30:16
+  --> $DIR/type-overflow.rs:28:16
    |
 LL |     let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32
    |                ^^^^^^^^^^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL |     let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i
    = help: consider using `i128` instead
 
 warning: literal out of range for i8
-  --> $DIR/type-overflow.rs:32:17
+  --> $DIR/type-overflow.rs:30:17
    |
 LL |     let fail = -0b1111_1111i8; //~WARNING literal out of range for i8
    |                 ^^^^^^^^^^^^^ help: consider using `i16` instead: `0b1111_1111i16`
diff --git a/src/test/ui/loops-reject-duplicate-labels-2.stderr b/src/test/ui/loops-reject-duplicate-labels-2.stderr
index d35ed4ff88a67..830270a99d112 100644
--- a/src/test/ui/loops-reject-duplicate-labels-2.stderr
+++ b/src/test/ui/loops-reject-duplicate-labels-2.stderr
@@ -70,3 +70,5 @@ LL | |     foo();
 LL | | }
    | |_^
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/loops-reject-duplicate-labels.stderr b/src/test/ui/loops-reject-duplicate-labels.stderr
index d1b874ea99729..a71f98b812a8c 100644
--- a/src/test/ui/loops-reject-duplicate-labels.stderr
+++ b/src/test/ui/loops-reject-duplicate-labels.stderr
@@ -73,3 +73,5 @@ LL | |     foo();
 LL | | }
    | |_^
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr b/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr
index 0cdd58fdbd75d..af524d5b01766 100644
--- a/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr
+++ b/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr
@@ -108,3 +108,5 @@ LL | |     foo();
 LL | | }
    | |_^
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/loops-reject-lifetime-shadowing-label.stderr b/src/test/ui/loops-reject-lifetime-shadowing-label.stderr
index a050aec50c72b..999cfb9cc3c6b 100644
--- a/src/test/ui/loops-reject-lifetime-shadowing-label.stderr
+++ b/src/test/ui/loops-reject-lifetime-shadowing-label.stderr
@@ -14,3 +14,5 @@ LL | |     foo();
 LL | | }
    | |_^
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/macro-context.stderr b/src/test/ui/macro-context.stderr
index 4dc6bbe4d656c..b3e67fb2607cd 100644
--- a/src/test/ui/macro-context.stderr
+++ b/src/test/ui/macro-context.stderr
@@ -43,3 +43,5 @@ LL |     () => ( i ; typeof );   //~ ERROR expected expression, found reserved k
 LL |     m!();
    |     ----- in this macro invocation
 
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/macros/macro_path_as_generic_bound.stderr b/src/test/ui/macros/macro_path_as_generic_bound.stderr
index 06d22714dd8b6..0f9f0607c5bf2 100644
--- a/src/test/ui/macros/macro_path_as_generic_bound.stderr
+++ b/src/test/ui/macros/macro_path_as_generic_bound.stderr
@@ -4,5 +4,6 @@ error[E0433]: failed to resolve. Use of undeclared type or module `m`
 LL | foo!(m::m2::A); //~ ERROR failed to resolve
    |      ^ Use of undeclared type or module `m`
 
-error: cannot continue compilation due to previous error
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr
index 9fb5b17a3114b..a9ffef8ef8090 100644
--- a/src/test/ui/macros/trace_faulty_macros.stderr
+++ b/src/test/ui/macros/trace_faulty_macros.stderr
@@ -45,3 +45,5 @@ LL |     my_recursive_macro!();
    = note: expanding `my_recursive_macro! {  }`
    = note: to `my_recursive_macro ! (  ) ;`
 
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/mismatched_types/issue-38371.rs b/src/test/ui/mismatched_types/issue-38371.rs
index b9b6b05996b66..8e613d4edba14 100644
--- a/src/test/ui/mismatched_types/issue-38371.rs
+++ b/src/test/ui/mismatched_types/issue-38371.rs
@@ -7,8 +7,6 @@
 // <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(slice_patterns)]
-
 
 struct Foo {
 }
diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr
index 1bf1521e39e03..dd5da76907515 100644
--- a/src/test/ui/mismatched_types/issue-38371.stderr
+++ b/src/test/ui/mismatched_types/issue-38371.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-38371.rs:16:8
+  --> $DIR/issue-38371.rs:14:8
    |
 LL | fn foo(&foo: Foo) { //~ ERROR mismatched types
    |        ^^^^ expected struct `Foo`, found reference
@@ -9,7 +9,7 @@ LL | fn foo(&foo: Foo) { //~ ERROR mismatched types
    = help: did you mean `foo: &Foo`?
 
 error[E0308]: mismatched types
-  --> $DIR/issue-38371.rs:30:9
+  --> $DIR/issue-38371.rs:28:9
    |
 LL | fn agh(&&bar: &u32) { //~ ERROR mismatched types
    |         ^^^^ expected u32, found reference
@@ -19,7 +19,7 @@ LL | fn agh(&&bar: &u32) { //~ ERROR mismatched types
    = help: did you mean `bar: &u32`?
 
 error[E0308]: mismatched types
-  --> $DIR/issue-38371.rs:33:8
+  --> $DIR/issue-38371.rs:31:8
    |
 LL | fn bgh(&&bar: u32) { //~ ERROR mismatched types
    |        ^^^^^ expected u32, found reference
@@ -28,7 +28,7 @@ LL | fn bgh(&&bar: u32) { //~ ERROR mismatched types
               found type `&_`
 
 error[E0529]: expected an array or slice, found `u32`
-  --> $DIR/issue-38371.rs:36:9
+  --> $DIR/issue-38371.rs:34:9
    |
 LL | fn ugh(&[bar]: &u32) { //~ ERROR expected an array or slice
    |         ^^^^^ pattern cannot match with input type `u32`
diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs
new file mode 100644
index 0000000000000..dfde37994998b
--- /dev/null
+++ b/src/test/ui/missing-fields-in-struct-pattern.rs
@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+struct S(usize, usize, usize, usize);
+
+fn main() {
+    if let S { a, b, c, d } = S(1, 2, 3, 4) {
+    //~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026]
+    //~| ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027]
+        println!("hi");
+    }
+}
diff --git a/src/test/ui/missing-fields-in-struct-pattern.stderr b/src/test/ui/missing-fields-in-struct-pattern.stderr
new file mode 100644
index 0000000000000..d1c3260f11e30
--- /dev/null
+++ b/src/test/ui/missing-fields-in-struct-pattern.stderr
@@ -0,0 +1,18 @@
+error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d`
+  --> $DIR/missing-fields-in-struct-pattern.rs:14:16
+   |
+LL |     if let S { a, b, c, d } = S(1, 2, 3, 4) {
+   |                ^  ^  ^  ^ struct `S` does not have these fields
+
+error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3`
+  --> $DIR/missing-fields-in-struct-pattern.rs:14:12
+   |
+LL |     if let S { a, b, c, d } = S(1, 2, 3, 4) {
+   |            ^^^^^^^^^^^^^^^^ missing fields `0`, `1`, `2`, `3`
+   |
+   = note: trying to match a tuple variant with a struct variant pattern
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0026, E0027.
+For more information about an error, try `rustc --explain E0026`.
diff --git a/src/test/ui/nested_impl_trait.rs b/src/test/ui/nested_impl_trait.rs
index f6302c0f3b3e2..be0454472dd0b 100644
--- a/src/test/ui/nested_impl_trait.rs
+++ b/src/test/ui/nested_impl_trait.rs
@@ -7,8 +7,6 @@
 // <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(conservative_impl_trait, universal_impl_trait)]
-
 use std::fmt::Debug;
 
 fn fine(x: impl Into<u32>) -> impl Into<u32> { x }
diff --git a/src/test/ui/nested_impl_trait.stderr b/src/test/ui/nested_impl_trait.stderr
index 10d767db8d321..ee53194e2b484 100644
--- a/src/test/ui/nested_impl_trait.stderr
+++ b/src/test/ui/nested_impl_trait.stderr
@@ -1,5 +1,5 @@
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/nested_impl_trait.rs:16:56
+  --> $DIR/nested_impl_trait.rs:14:56
    |
 LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                              ----------^^^^^^^^^^-
@@ -8,7 +8,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                              outer `impl Trait`
 
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/nested_impl_trait.rs:19:42
+  --> $DIR/nested_impl_trait.rs:17:42
    |
 LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
    |                                ----------^^^^^^^^^^-
@@ -17,7 +17,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
    |                                outer `impl Trait`
 
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/nested_impl_trait.rs:23:37
+  --> $DIR/nested_impl_trait.rs:21:37
    |
 LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
    |                           ----------^^^^^^^^^^-
@@ -26,7 +26,7 @@ LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
    |                           outer `impl Trait`
 
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/nested_impl_trait.rs:28:44
+  --> $DIR/nested_impl_trait.rs:26:44
    |
 LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                  ----------^^^^^^^^^^-
@@ -35,13 +35,13 @@ LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                  outer `impl Trait`
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/nested_impl_trait.rs:19:32
+  --> $DIR/nested_impl_trait.rs:17:32
    |
 LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
    |                                ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/nested_impl_trait.rs:36:42
+  --> $DIR/nested_impl_trait.rs:34:42
    |
 LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
    |                                          ^^^^^^^^^^^^^^
diff --git a/src/test/ui/nll/issue-48238.rs b/src/test/ui/nll/issue-48238.rs
new file mode 100644
index 0000000000000..6f7644da3d349
--- /dev/null
+++ b/src/test/ui/nll/issue-48238.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+// Regression test for issue #48238
+
+#![feature(nll)]
+
+fn use_val<'a>(val: &'a u8) -> &'a u8 {
+    val
+}
+
+fn main() {
+    let orig: u8 = 5;
+    move || use_val(&orig); //~ ERROR free region `` does not outlive free region `'_#1r`
+}
diff --git a/src/test/ui/nll/issue-48238.stderr b/src/test/ui/nll/issue-48238.stderr
new file mode 100644
index 0000000000000..29385d9b2430f
--- /dev/null
+++ b/src/test/ui/nll/issue-48238.stderr
@@ -0,0 +1,8 @@
+error: free region `` does not outlive free region `'_#1r`
+  --> $DIR/issue-48238.rs:21:21
+   |
+LL |     move || use_val(&orig); //~ ERROR free region `` does not outlive free region `'_#1r`
+   |                     ^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs
index 850cd1e7336d7..571bd9fd76e86 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs
+++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs
@@ -11,7 +11,6 @@
 // compile-flags:-Znll -Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
-#![feature(conservative_impl_trait)]
 
 trait Foo<'a> {
 }
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
index bfa58bfc80748..92e4f72da3a10 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
+++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
@@ -1,11 +1,11 @@
 warning: not reporting region error due to -Znll
-  --> $DIR/impl-trait-captures.rs:22:5
+  --> $DIR/impl-trait-captures.rs:21:5
    |
 LL |     x
    |     ^
 
 error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/impl-trait-captures.rs:22:5
+  --> $DIR/impl-trait-captures.rs:21:5
    |
 LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
    |               - consider changing the type of `x` to `&ReEarlyBound(0, 'a) T`
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs b/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs
index 135805a733944..2e0671f1a51e8 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs
+++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs
@@ -11,7 +11,6 @@
 // compile-flags:-Znll -Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
-#![feature(conservative_impl_trait)]
 
 use std::fmt::Debug;
 
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
index f29d2233e7072..2b90d53774e65 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
+++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
@@ -1,17 +1,17 @@
 warning: not reporting region error due to -Znll
-  --> $DIR/impl-trait-outlives.rs:18:35
+  --> $DIR/impl-trait-outlives.rs:17:35
    |
 LL | fn no_region<'a, T>(x: Box<T>) -> impl Debug + 'a
    |                                   ^^^^^^^^^^^^^^^
 
 warning: not reporting region error due to -Znll
-  --> $DIR/impl-trait-outlives.rs:34:42
+  --> $DIR/impl-trait-outlives.rs:33:42
    |
 LL | fn wrong_region<'a, 'b, T>(x: Box<T>) -> impl Debug + 'a
    |                                          ^^^^^^^^^^^^^^^
 
 error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/impl-trait-outlives.rs:23:5
+  --> $DIR/impl-trait-outlives.rs:22:5
    |
 LL |     x
    |     ^
@@ -19,7 +19,7 @@ LL |     x
    = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
 
 error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/impl-trait-outlives.rs:39:5
+  --> $DIR/impl-trait-outlives.rs:38:5
    |
 LL |     x
    |     ^
diff --git a/src/test/ui/non-exhaustive-pattern-witness.rs b/src/test/ui/non-exhaustive-pattern-witness.rs
index 0b12a9acbcb9e..dd14a10a2bcec 100644
--- a/src/test/ui/non-exhaustive-pattern-witness.rs
+++ b/src/test/ui/non-exhaustive-pattern-witness.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(advanced_slice_patterns)]
 #![feature(slice_patterns)]
 
 struct Foo {
diff --git a/src/test/ui/non-exhaustive-pattern-witness.stderr b/src/test/ui/non-exhaustive-pattern-witness.stderr
index 7179b4b135a12..e364e822ea878 100644
--- a/src/test/ui/non-exhaustive-pattern-witness.stderr
+++ b/src/test/ui/non-exhaustive-pattern-witness.stderr
@@ -1,41 +1,41 @@
 error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered
-  --> $DIR/non-exhaustive-pattern-witness.rs:20:11
+  --> $DIR/non-exhaustive-pattern-witness.rs:19:11
    |
 LL |     match (Foo { first: true, second: None }) {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered
 
 error[E0004]: non-exhaustive patterns: `Red` not covered
-  --> $DIR/non-exhaustive-pattern-witness.rs:36:11
+  --> $DIR/non-exhaustive-pattern-witness.rs:35:11
    |
 LL |     match Color::Red {
    |           ^^^^^^^^^^ pattern `Red` not covered
 
 error[E0004]: non-exhaustive patterns: `East`, `South` and `West` not covered
-  --> $DIR/non-exhaustive-pattern-witness.rs:48:11
+  --> $DIR/non-exhaustive-pattern-witness.rs:47:11
    |
 LL |     match Direction::North {
    |           ^^^^^^^^^^^^^^^^ patterns `East`, `South` and `West` not covered
 
 error[E0004]: non-exhaustive patterns: `Second`, `Third`, `Fourth` and 8 more not covered
-  --> $DIR/non-exhaustive-pattern-witness.rs:59:11
+  --> $DIR/non-exhaustive-pattern-witness.rs:58:11
    |
 LL |     match ExcessiveEnum::First {
    |           ^^^^^^^^^^^^^^^^^^^^ patterns `Second`, `Third`, `Fourth` and 8 more not covered
 
 error[E0004]: non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
-  --> $DIR/non-exhaustive-pattern-witness.rs:67:11
+  --> $DIR/non-exhaustive-pattern-witness.rs:66:11
    |
 LL |     match Color::Red {
    |           ^^^^^^^^^^ pattern `CustomRGBA { a: true, .. }` not covered
 
 error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not covered
-  --> $DIR/non-exhaustive-pattern-witness.rs:83:11
+  --> $DIR/non-exhaustive-pattern-witness.rs:82:11
    |
 LL |     match *x {
    |           ^^ pattern `[Second(true), Second(false)]` not covered
 
 error[E0004]: non-exhaustive patterns: `((), false)` not covered
-  --> $DIR/non-exhaustive-pattern-witness.rs:96:11
+  --> $DIR/non-exhaustive-pattern-witness.rs:95:11
    |
 LL |     match ((), false) {
    |           ^^^^^^^^^^^ pattern `((), false)` not covered
diff --git a/src/test/ui/numeric-fields.stderr b/src/test/ui/numeric-fields.stderr
index 607980ba3bf54..68a87da8ded32 100644
--- a/src/test/ui/numeric-fields.stderr
+++ b/src/test/ui/numeric-fields.stderr
@@ -10,7 +10,7 @@ error[E0026]: struct `S` does not have a field named `0x1`
   --> $DIR/numeric-fields.rs:17:17
    |
 LL |         S{0: a, 0x1: b, ..} => {}
-   |                 ^^^^^^ struct `S` does not have field `0x1`
+   |                 ^^^^^^ struct `S` does not have this field
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pat-slice-old-style.stderr b/src/test/ui/pat-slice-old-style.stderr
deleted file mode 100644
index 6fa5b18a14e86..0000000000000
--- a/src/test/ui/pat-slice-old-style.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: non-reference pattern used to match a reference (see issue #42640)
-  --> $DIR/pat-slice-old-style.rs:19:9
-   |
-LL |         [a, b..] => {},
-   |         ^^^^^^^^ help: consider using a reference: `&[a, b..]`
-   |
-   = help: add #![feature(match_default_bindings)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/raw-literal-keywords.rs b/src/test/ui/raw-literal-keywords.rs
new file mode 100644
index 0000000000000..9b28aa0b15116
--- /dev/null
+++ b/src/test/ui/raw-literal-keywords.rs
@@ -0,0 +1,26 @@
+// Copyright 2018 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.
+
+// compile-flags: -Z parse-only
+
+#![feature(dyn_trait)]
+#![feature(raw_identifiers)]
+
+fn test_if() {
+    r#if true { } //~ ERROR found `true`
+}
+
+fn test_struct() {
+    r#struct Test; //~ ERROR found `Test`
+}
+
+fn test_union() {
+    r#union Test; //~ ERROR found `Test`
+}
diff --git a/src/test/ui/raw-literal-keywords.stderr b/src/test/ui/raw-literal-keywords.stderr
new file mode 100644
index 0000000000000..3758568323cc0
--- /dev/null
+++ b/src/test/ui/raw-literal-keywords.stderr
@@ -0,0 +1,20 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `true`
+  --> $DIR/raw-literal-keywords.rs:17:10
+   |
+LL |     r#if true { } //~ ERROR found `true`
+   |          ^^^^ expected one of 8 possible tokens here
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test`
+  --> $DIR/raw-literal-keywords.rs:21:14
+   |
+LL |     r#struct Test; //~ ERROR found `Test`
+   |              ^^^^ expected one of 8 possible tokens here
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test`
+  --> $DIR/raw-literal-keywords.rs:25:13
+   |
+LL |     r#union Test; //~ ERROR found `Test`
+   |             ^^^^ expected one of 8 possible tokens here
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/raw-literal-self.rs b/src/test/ui/raw-literal-self.rs
new file mode 100644
index 0000000000000..f88d6cf9a67bd
--- /dev/null
+++ b/src/test/ui/raw-literal-self.rs
@@ -0,0 +1,17 @@
+// Copyright 2018 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.
+
+// compile-flags: -Z parse-only
+
+#![feature(raw_identifiers)]
+
+fn self_test(r#self: u32) {
+    //~^ ERROR `r#self` is not currently supported.
+}
diff --git a/src/test/ui/raw-literal-self.stderr b/src/test/ui/raw-literal-self.stderr
new file mode 100644
index 0000000000000..e3345847aa895
--- /dev/null
+++ b/src/test/ui/raw-literal-self.stderr
@@ -0,0 +1,8 @@
+error: `r#self` is not currently supported.
+  --> $DIR/raw-literal-self.rs:15:14
+   |
+LL | fn self_test(r#self: u32) {
+   |              ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/raw-literal-underscore.rs b/src/test/ui/raw-literal-underscore.rs
new file mode 100644
index 0000000000000..ec33e4861958e
--- /dev/null
+++ b/src/test/ui/raw-literal-underscore.rs
@@ -0,0 +1,15 @@
+// Copyright 2018 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.
+
+// compile-flags: -Z parse-only
+
+fn underscore_test(r#_: u32) {
+    //~^ ERROR `r#_` is not currently supported.
+}
diff --git a/src/test/ui/raw-literal-underscore.stderr b/src/test/ui/raw-literal-underscore.stderr
new file mode 100644
index 0000000000000..8072eee4f0604
--- /dev/null
+++ b/src/test/ui/raw-literal-underscore.stderr
@@ -0,0 +1,8 @@
+error: `r#_` is not currently supported.
+  --> $DIR/raw-literal-underscore.rs:13:20
+   |
+LL | fn underscore_test(r#_: u32) {
+   |                    ^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/raw_string.stderr b/src/test/ui/raw_string.stderr
index b8aa596ef953a..ddf1cfe406f7c 100644
--- a/src/test/ui/raw_string.stderr
+++ b/src/test/ui/raw_string.stderr
@@ -6,3 +6,5 @@ LL |     let x = r##"lol"#;
    |
    = note: this raw string should be terminated with `"##`
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr
index a9d2aeee2d151..3edfa33d80a02 100644
--- a/src/test/ui/resolve/issue-21221-1.stderr
+++ b/src/test/ui/resolve/issue-21221-1.stderr
@@ -45,5 +45,7 @@ help: possible candidate is found in another module, you can import it into scop
 LL | use std::ops::Div;
    |
 
-error: cannot continue compilation due to previous error
+error: aborting due to 4 previous errors
 
+Some errors occurred: E0405, E0412.
+For more information about an error, try `rustc --explain E0405`.
diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr
index c61ffe3b33e8a..e11fe9ac4cf11 100644
--- a/src/test/ui/resolve/issue-21221-2.stderr
+++ b/src/test/ui/resolve/issue-21221-2.stderr
@@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop
 LL | use foo::bar::T;
    |
 
-error: cannot continue compilation due to previous error
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0405`.
diff --git a/src/test/ui/resolve/issue-21221-3.stderr b/src/test/ui/resolve/issue-21221-3.stderr
index 7725f74cb49fc..f406cd6e35fcf 100644
--- a/src/test/ui/resolve/issue-21221-3.stderr
+++ b/src/test/ui/resolve/issue-21221-3.stderr
@@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop
 LL | use issue_21221_3::outer::OuterTrait;
    |
 
-error: cannot continue compilation due to previous error
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0405`.
diff --git a/src/test/ui/resolve/issue-21221-4.stderr b/src/test/ui/resolve/issue-21221-4.stderr
index b0a4d5ba4d898..c0a7f1734f49c 100644
--- a/src/test/ui/resolve/issue-21221-4.stderr
+++ b/src/test/ui/resolve/issue-21221-4.stderr
@@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop
 LL | use issue_21221_4::T;
    |
 
-error: cannot continue compilation due to previous error
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0405`.
diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr
index 2b8b2b20685f8..3627c09b28fd9 100644
--- a/src/test/ui/resolve/issue-3907.stderr
+++ b/src/test/ui/resolve/issue-3907.stderr
@@ -8,5 +8,6 @@ help: possible better candidate is found in another module, you can import it in
 LL | use issue_3907::Foo;
    |
 
-error: cannot continue compilation due to previous error
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0404`.
diff --git a/src/test/ui/resolve/issue-5035.stderr b/src/test/ui/resolve/issue-5035.stderr
index 6597f05889af8..353a0b1c3d9d0 100644
--- a/src/test/ui/resolve/issue-5035.stderr
+++ b/src/test/ui/resolve/issue-5035.stderr
@@ -13,5 +13,7 @@ LL | impl K for isize {} //~ ERROR expected trait, found type alias `K`
    |      did you mean `I`?
    |      type aliases cannot be used for traits
 
-error: cannot continue compilation due to previous error
+error: aborting due to 2 previous errors
 
+Some errors occurred: E0404, E0432.
+For more information about an error, try `rustc --explain E0404`.
diff --git a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr
index 6e7bd28d16fc3..f32c5e9b2c6bd 100644
--- a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr
+++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr
@@ -10,5 +10,7 @@ error[E0404]: expected trait, found type alias `Typedef`
 LL | fn g<F:Typedef(isize) -> isize>(x: F) {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^ type aliases cannot be used for traits
 
-error: cannot continue compilation due to previous error
+error: aborting due to 2 previous errors
 
+Some errors occurred: E0404, E0405.
+For more information about an error, try `rustc --explain E0404`.
diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs
similarity index 78%
rename from src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs
rename to src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs
index 93e2561adf753..425f51ca2fb54 100644
--- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs
@@ -7,9 +7,7 @@
 // <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(termination_trait)]
 
-fn main() -> char {
-//~^ ERROR: the trait bound `char: std::process::Termination` is not satisfied
+fn main() -> char { //~ ERROR
     ' '
 }
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr
new file mode 100644
index 0000000000000..e53872593843c
--- /dev/null
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr
@@ -0,0 +1,11 @@
+error[E0277]: `main` has invalid return type `char`
+  --> $DIR/termination-trait-main-wrong-type.rs:11:14
+   |
+LL | fn main() -> char { //~ ERROR
+   |              ^^^^ `main` can only return types that implement `std::process::Termination`
+   |
+   = help: consider using `()`, or a `Result`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2005-default-binding-mode/const.rs b/src/test/ui/rfc-2005-default-binding-mode/const.rs
index fca99f064a273..f80e47507ff04 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/const.rs
+++ b/src/test/ui/rfc-2005-default-binding-mode/const.rs
@@ -10,8 +10,6 @@
 
 // FIXME(tschottdorf): this test should pass.
 
-#![feature(match_default_bindings)]
-
 #[derive(PartialEq, Eq)]
 struct Foo {
     bar: i32,
diff --git a/src/test/ui/rfc-2005-default-binding-mode/const.stderr b/src/test/ui/rfc-2005-default-binding-mode/const.stderr
index 302b3a8dbc325..4849c39a5d099 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/const.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/const.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/const.rs:26:9
+  --> $DIR/const.rs:24:9
    |
 LL |         FOO => {}, //~ ERROR mismatched types
    |         ^^^ expected &Foo, found struct `Foo`
diff --git a/src/test/ui/rfc-2005-default-binding-mode/enum.rs b/src/test/ui/rfc-2005-default-binding-mode/enum.rs
index 76ea64e248ef8..a108653f85d20 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/enum.rs
+++ b/src/test/ui/rfc-2005-default-binding-mode/enum.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 enum Wrapper {
     Wrap(i32),
 }
diff --git a/src/test/ui/rfc-2005-default-binding-mode/enum.stderr b/src/test/ui/rfc-2005-default-binding-mode/enum.stderr
index 18cd0774667c3..a7f3b507508e8 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/enum.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/enum.stderr
@@ -1,5 +1,5 @@
 error[E0594]: cannot assign to immutable borrowed content `*x`
-  --> $DIR/enum.rs:21:5
+  --> $DIR/enum.rs:19:5
    |
 LL |     let Wrap(x) = &Wrap(3);
    |              - consider changing this to `x`
@@ -7,7 +7,7 @@ LL |     *x += 1; //~ ERROR cannot assign to immutable
    |     ^^^^^^^ cannot borrow as mutable
 
 error[E0594]: cannot assign to immutable borrowed content `*x`
-  --> $DIR/enum.rs:25:9
+  --> $DIR/enum.rs:23:9
    |
 LL |     if let Some(x) = &Some(3) {
    |                 - consider changing this to `x`
@@ -15,7 +15,7 @@ LL |         *x += 1; //~ ERROR cannot assign to immutable
    |         ^^^^^^^ cannot borrow as mutable
 
 error[E0594]: cannot assign to immutable borrowed content `*x`
-  --> $DIR/enum.rs:31:9
+  --> $DIR/enum.rs:29:9
    |
 LL |     while let Some(x) = &Some(3) {
    |                    - consider changing this to `x`
diff --git a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs
index 2e43d9722a900..8001d980174e0 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs
+++ b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 // Verify the binding mode shifts - only when no `&` are auto-dereferenced is the
 // final default binding mode mutable.
 
diff --git a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr
index 392efecb9cd1f..f2b9bde41ab33 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr
@@ -1,5 +1,5 @@
 error[E0594]: cannot assign to immutable borrowed content `*n`
-  --> $DIR/explicit-mut.rs:19:13
+  --> $DIR/explicit-mut.rs:17:13
    |
 LL |         Some(n) => {
    |              - consider changing this to `n`
@@ -7,7 +7,7 @@ LL |             *n += 1; //~ ERROR cannot assign to immutable
    |             ^^^^^^^ cannot borrow as mutable
 
 error[E0594]: cannot assign to immutable borrowed content `*n`
-  --> $DIR/explicit-mut.rs:27:13
+  --> $DIR/explicit-mut.rs:25:13
    |
 LL |         Some(n) => {
    |              - consider changing this to `n`
@@ -15,7 +15,7 @@ LL |             *n += 1; //~ ERROR cannot assign to immutable
    |             ^^^^^^^ cannot borrow as mutable
 
 error[E0594]: cannot assign to immutable borrowed content `*n`
-  --> $DIR/explicit-mut.rs:35:13
+  --> $DIR/explicit-mut.rs:33:13
    |
 LL |         Some(n) => {
    |              - consider changing this to `n`
diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.rs b/src/test/ui/rfc-2005-default-binding-mode/for.rs
index e9004c13a0e27..a354d2216a9c7 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/for.rs
+++ b/src/test/ui/rfc-2005-default-binding-mode/for.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 struct Foo {}
 
 pub fn main() {
diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.stderr b/src/test/ui/rfc-2005-default-binding-mode/for.stderr
index 4094c185063e6..dbd4bd5dbec43 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/for.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/for.stderr
@@ -1,5 +1,5 @@
 error[E0009]: cannot bind by-move and by-ref in the same pattern
-  --> $DIR/for.rs:18:13
+  --> $DIR/for.rs:16:13
    |
 LL |     for (n, mut m) in &tups {
    |          -  ^^^^^ by-move pattern here
diff --git a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs
index 9fbcf5d68b6ff..4f4c2a149a7d6 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs
+++ b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 // FIXME(tschottdorf): This should compile. See #44912.
 
 pub fn main() {
diff --git a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr
index 154fa79fa3f38..04fa3708ffb75 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr
@@ -1,5 +1,5 @@
 error[E0409]: variable `x` is bound in inconsistent ways within the same match arm
-  --> $DIR/issue-44912-or.rs:18:35
+  --> $DIR/issue-44912-or.rs:16:35
    |
 LL |         Some((x, 3)) | &Some((ref x, 5)) => x,
    |               - first binding     ^ bound in different ways
diff --git a/src/test/ui/rfc-2005-default-binding-mode/lit.rs b/src/test/ui/rfc-2005-default-binding-mode/lit.rs
index 783287fd458bc..209f584534615 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/lit.rs
+++ b/src/test/ui/rfc-2005-default-binding-mode/lit.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(match_default_bindings)]
-
 // FIXME(tschottdorf): we want these to compile, but they don't.
 
 fn with_str() {
diff --git a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr
index dde1f2d352c70..d5c230bc8de54 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/lit.rs:19:13
+  --> $DIR/lit.rs:17:13
    |
 LL |             "abc" => true, //~ ERROR mismatched types
    |             ^^^^^ expected &str, found str
@@ -8,7 +8,7 @@ LL |             "abc" => true, //~ ERROR mismatched types
               found type `&'static str`
 
 error[E0308]: mismatched types
-  --> $DIR/lit.rs:28:9
+  --> $DIR/lit.rs:26:9
    |
 LL |         b"abc" => true, //~ ERROR mismatched types
    |         ^^^^^^ expected &[u8], found array of 3 elements
diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfc-2005-default-binding-mode/slice.rs
index 40aa957242cb8..fbe4dfe216196 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/slice.rs
+++ b/src/test/ui/rfc-2005-default-binding-mode/slice.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![feature(slice_patterns)]
-#![feature(match_default_bindings)]
 
 pub fn main() {
     let sl: &[u8] = b"foo";
diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr
index c0127e5990e97..18dc6b2869ab9 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `&[]` not covered
-  --> $DIR/slice.rs:17:11
+  --> $DIR/slice.rs:16:11
    |
 LL |     match sl { //~ ERROR non-exhaustive patterns
    |           ^^ pattern `&[]` not covered
diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr
deleted file mode 100644
index ea58c62fc8476..0000000000000
--- a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: non-reference pattern used to match a reference (see issue #42640)
-  --> $DIR/suggestion.rs:12:12
-   |
-LL |     if let Some(y) = &Some(22) { //~ ERROR non-reference pattern
-   |            ^^^^^^^ help: consider using a reference: `&Some(y)`
-   |
-   = help: add #![feature(match_default_bindings)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr
index bb55d86f620b7..e69de29bb2d1d 100644
--- a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr
@@ -1,2 +0,0 @@
-error: cannot continue compilation due to previous error
-
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
index 8e03c303e54d7..e8227971691e9 100644
--- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
@@ -58,7 +58,10 @@ fn test6() {
 
 fn test7() {
     fn foo<F>(_: F) where F: FnMut(Box<FnMut(isize)>, isize) {}
-    let mut f = |g: Box<FnMut(isize)>, b: isize| {};
+    let s = String::new();  // Capture to make f !Copy
+    let mut f = move |g: Box<FnMut(isize)>, b: isize| {
+        let _ = s.len();
+    };
     f(Box::new(|a| {
         foo(f);
         //~^ ERROR cannot move `f` into closure because it is borrowed
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
index 318b77dedcba4..2e7e1e0744141 100644
--- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
@@ -28,7 +28,7 @@ LL |     f.f.call_mut(())
    |     ^^^ cannot borrow as mutable
 
 error[E0504]: cannot move `f` into closure because it is borrowed
-  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:63:13
+  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:66:13
    |
 LL |     f(Box::new(|a| {
    |     - borrow of `f` occurs here
@@ -36,11 +36,11 @@ LL |         foo(f);
    |             ^ move into closure occurs here
 
 error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
-  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:63:13
+  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:66:13
    |
-LL |     let mut f = |g: Box<FnMut(isize)>, b: isize| {};
+LL |     let mut f = move |g: Box<FnMut(isize)>, b: isize| {
    |         ----- captured outer variable
-LL |     f(Box::new(|a| {
+...
 LL |         foo(f);
    |             ^ cannot move out of captured outer variable in an `FnMut` closure
 
diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr
index 6a4ec73b27a66..b496a1a76c017 100644
--- a/src/test/ui/span/issue-24690.stderr
+++ b/src/test/ui/span/issue-24690.stderr
@@ -36,3 +36,5 @@ LL | |     println!("{}", theTwo);
 LL | | }
    | |_^
 
+error: aborting due to previous error
+
diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr
index 2d4a7cc72f5f6..1dd45bb1e5efe 100644
--- a/src/test/ui/span/issue-35987.stderr
+++ b/src/test/ui/span/issue-35987.stderr
@@ -8,5 +8,6 @@ help: possible better candidate is found in another module, you can import it in
 LL | use std::ops::Add;
    |
 
-error: cannot continue compilation due to previous error
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0404`.
diff --git a/src/test/compile-fail/unboxed-closer-non-implicit-copyable.rs b/src/test/ui/suggest-remove-refs-1.rs
similarity index 75%
rename from src/test/compile-fail/unboxed-closer-non-implicit-copyable.rs
rename to src/test/ui/suggest-remove-refs-1.rs
index 2d55979491981..0f19c48337b1e 100644
--- a/src/test/compile-fail/unboxed-closer-non-implicit-copyable.rs
+++ b/src/test/ui/suggest-remove-refs-1.rs
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
-
-fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
-
 fn main() {
-    let f = to_fn_once(move|| ());
-    f();
-    f(); //~ ERROR use of moved value
+    let v = vec![0, 1, 2, 3];
+
+    for (i, n) in &v.iter().enumerate() {
+        //~^ ERROR the trait bound
+        println!("{}", i);
+    }
 }
diff --git a/src/test/ui/suggest-remove-refs-1.stderr b/src/test/ui/suggest-remove-refs-1.stderr
new file mode 100644
index 0000000000000..c47b4d283d7cd
--- /dev/null
+++ b/src/test/ui/suggest-remove-refs-1.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>: std::iter::Iterator` is not satisfied
+  --> $DIR/suggest-remove-refs-1.rs:14:19
+   |
+LL |     for (i, n) in &v.iter().enumerate() {
+   |                   -^^^^^^^^^^^^^^^^^^^^
+   |                   |
+   |                   `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator; maybe try calling `.iter()` or a similar method
+   |                   help: consider removing 1 leading `&`-references
+   |
+   = help: the trait `std::iter::Iterator` is not implemented for `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>`
+   = note: required by `std::iter::IntoIterator::into_iter`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggest-remove-refs-2.rs b/src/test/ui/suggest-remove-refs-2.rs
new file mode 100644
index 0000000000000..c427f697ae1ef
--- /dev/null
+++ b/src/test/ui/suggest-remove-refs-2.rs
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let v = vec![0, 1, 2, 3];
+
+    for (i, n) in & & & & &v.iter().enumerate() {
+        //~^ ERROR the trait bound
+        println!("{}", i);
+    }
+}
diff --git a/src/test/ui/suggest-remove-refs-2.stderr b/src/test/ui/suggest-remove-refs-2.stderr
new file mode 100644
index 0000000000000..fdd654ea3923f
--- /dev/null
+++ b/src/test/ui/suggest-remove-refs-2.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>: std::iter::Iterator` is not satisfied
+  --> $DIR/suggest-remove-refs-2.rs:14:19
+   |
+LL |     for (i, n) in & & & & &v.iter().enumerate() {
+   |                   ---------^^^^^^^^^^^^^^^^^^^^
+   |                   |
+   |                   `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator; maybe try calling `.iter()` or a similar method
+   |                   help: consider removing 5 leading `&`-references
+   |
+   = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>`
+   = note: required by `std::iter::IntoIterator::into_iter`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggest-remove-refs-3.rs b/src/test/ui/suggest-remove-refs-3.rs
new file mode 100644
index 0000000000000..f54ae30caebca
--- /dev/null
+++ b/src/test/ui/suggest-remove-refs-3.rs
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let v = vec![0, 1, 2, 3];
+
+    for (i, n) in & & &
+        & &v
+        .iter()
+        .enumerate() {
+        //~^^^^ ERROR the trait bound
+        println!("{}", i);
+    }
+}
diff --git a/src/test/ui/suggest-remove-refs-3.stderr b/src/test/ui/suggest-remove-refs-3.stderr
new file mode 100644
index 0000000000000..b0920a0fa523e
--- /dev/null
+++ b/src/test/ui/suggest-remove-refs-3.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>: std::iter::Iterator` is not satisfied
+  --> $DIR/suggest-remove-refs-3.rs:14:19
+   |
+LL |        for (i, n) in & & &
+   |   ___________________^
+   |  |___________________|
+   | ||
+LL | ||         & &v
+   | ||___________- help: consider removing 5 leading `&`-references
+LL | |          .iter()
+LL | |          .enumerate() {
+   | |_____________________^ `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator; maybe try calling `.iter()` or a similar method
+   |
+   = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>`
+   = note: required by `std::iter::IntoIterator::into_iter`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/const-type-mismatch.rs b/src/test/ui/suggestions/const-type-mismatch.rs
new file mode 100644
index 0000000000000..ddad4e79cfdaa
--- /dev/null
+++ b/src/test/ui/suggestions/const-type-mismatch.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+// `const`s shouldn't suggest `.into()`
+
+const TEN: u8 = 10;
+const TWELVE: u16 = TEN + 2;
+//~^ ERROR mismatched types [E0308]
+
+fn main() {
+    const TEN: u8 = 10;
+    const ALSO_TEN: u16 = TEN;
+    //~^ ERROR mismatched types [E0308]
+}
diff --git a/src/test/ui/suggestions/const-type-mismatch.stderr b/src/test/ui/suggestions/const-type-mismatch.stderr
new file mode 100644
index 0000000000000..965995f82c53a
--- /dev/null
+++ b/src/test/ui/suggestions/const-type-mismatch.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/const-type-mismatch.rs:14:21
+   |
+LL | const TWELVE: u16 = TEN + 2;
+   |                     ^^^^^^^ expected u16, found u8
+
+error[E0308]: mismatched types
+  --> $DIR/const-type-mismatch.rs:19:27
+   |
+LL |     const ALSO_TEN: u16 = TEN;
+   |                           ^^^ expected u16, found u8
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs
deleted file mode 100644
index 0a2e7ef322606..0000000000000
--- a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn foo(s: &str) -> bool { true }
-
-fn main() {
-    let x = vec![(String::new(), String::new())];
-    x.iter()
-        .filter(|&(ref a, _)| foo(a))
-        //~^ ERROR non-reference pattern used to match a reference
-        .collect();
-}
diff --git a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr
deleted file mode 100644
index 4e2a321ffac09..0000000000000
--- a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: non-reference pattern used to match a reference (see issue #42640)
-  --> $DIR/dont-suggest-dereference-on-arg.rs:16:18
-   |
-LL |         .filter(|&(ref a, _)| foo(a))
-   |                  ^^^^^^^^^^^ help: consider using a reference: `&&(ref a, _)`
-   |
-   = help: add #![feature(match_default_bindings)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/type-alias-bounds.rs b/src/test/ui/type-alias-bounds.rs
new file mode 100644
index 0000000000000..c1cdeef3a4638
--- /dev/null
+++ b/src/test/ui/type-alias-bounds.rs
@@ -0,0 +1,69 @@
+// Copyright 2014 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.
+
+// Test ignored_generic_bounds lint warning about bounds in type aliases
+
+// must-compile-successfully
+#![allow(dead_code)]
+
+use std::rc::Rc;
+
+type SVec<T: Send+Send> = Vec<T>;
+//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
+type S2Vec<T> where T: Send = Vec<T>;
+//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]
+type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>);
+//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
+type WVec<'b, T: 'b+'b> = (&'b u32, Vec<T>);
+//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
+type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
+//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]
+
+static STATIC : u32 = 0;
+
+fn foo<'a>(y: &'a i32) {
+    // If any of the bounds above would matter, the code below would be rejected.
+    // This can be seen when replacing the type aliases above by newtype structs.
+    // (The type aliases have no unused parameters to make that a valid transformation.)
+    let mut x : SVec<_> = Vec::new();
+    x.push(Rc::new(42)); // is not send
+
+    let mut x : S2Vec<_> = Vec::new();
+    x.push(Rc::new(42)); // is not send
+
+    let mut x : VVec<'static, 'a> = (&STATIC, Vec::new());
+    x.1.push(y); // 'a: 'static does not hold
+
+    let mut x : WVec<'static, &'a i32> = (&STATIC, Vec::new());
+    x.1.push(y); // &'a i32: 'static does not hold
+
+    let mut x : W2Vec<'static, &'a i32> = (&STATIC, Vec::new());
+    x.1.push(y); // &'a i32: 'static does not hold
+}
+
+// Bounds are not checked either, i.e. the definition is not necessarily well-formed
+struct Sendable<T: Send>(T);
+type MySendable<T> = Sendable<T>; // no error here!
+
+// However, bounds *are* taken into account when accessing associated types
+trait Bound { type Assoc; }
+type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases
+type T2<U> where U: Bound = U::Assoc;  //~ WARN not enforced in type aliases
+
+// This errors
+// type T3<U> = U::Assoc;
+// Do this instead
+type T4<U> = <U as Bound>::Assoc;
+
+// Make sure the help about associatd types is not shown incorrectly
+type T5<U: Bound> = <U as Bound>::Assoc;  //~ WARN not enforced in type aliases
+type T6<U: Bound> = ::std::vec::Vec<U>;  //~ WARN not enforced in type aliases
+
+fn main() {}
diff --git a/src/test/ui/type-alias-bounds.stderr b/src/test/ui/type-alias-bounds.stderr
new file mode 100644
index 0000000000000..2a2b0b0f26e34
--- /dev/null
+++ b/src/test/ui/type-alias-bounds.stderr
@@ -0,0 +1,83 @@
+warning: bounds on generic parameters are not enforced in type aliases
+  --> $DIR/type-alias-bounds.rs:18:14
+   |
+LL | type SVec<T: Send+Send> = Vec<T>;
+   |              ^^^^ ^^^^
+   |
+   = note: #[warn(type_alias_bounds)] on by default
+   = help: the bound will not be checked when the type alias is used, and should be removed
+
+warning: where clauses are not enforced in type aliases
+  --> $DIR/type-alias-bounds.rs:20:21
+   |
+LL | type S2Vec<T> where T: Send = Vec<T>;
+   |                     ^^^^^^^
+   |
+   = help: the clause will not be checked when the type alias is used, and should be removed
+
+warning: bounds on generic parameters are not enforced in type aliases
+  --> $DIR/type-alias-bounds.rs:22:19
+   |
+LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>);
+   |                   ^^ ^^
+   |
+   = help: the bound will not be checked when the type alias is used, and should be removed
+
+warning: bounds on generic parameters are not enforced in type aliases
+  --> $DIR/type-alias-bounds.rs:24:18
+   |
+LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec<T>);
+   |                  ^^ ^^
+   |
+   = help: the bound will not be checked when the type alias is used, and should be removed
+
+warning: where clauses are not enforced in type aliases
+  --> $DIR/type-alias-bounds.rs:26:25
+   |
+LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
+   |                         ^^^^^  ^^^^^
+   |
+   = help: the clause will not be checked when the type alias is used, and should be removed
+
+warning: bounds on generic parameters are not enforced in type aliases
+  --> $DIR/type-alias-bounds.rs:57:12
+   |
+LL | type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases
+   |            ^^^^^
+   |
+   = help: the bound will not be checked when the type alias is used, and should be removed
+help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
+  --> $DIR/type-alias-bounds.rs:57:21
+   |
+LL | type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases
+   |                     ^^^^^^^^
+
+warning: where clauses are not enforced in type aliases
+  --> $DIR/type-alias-bounds.rs:58:18
+   |
+LL | type T2<U> where U: Bound = U::Assoc;  //~ WARN not enforced in type aliases
+   |                  ^^^^^^^^
+   |
+   = help: the clause will not be checked when the type alias is used, and should be removed
+help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
+  --> $DIR/type-alias-bounds.rs:58:29
+   |
+LL | type T2<U> where U: Bound = U::Assoc;  //~ WARN not enforced in type aliases
+   |                             ^^^^^^^^
+
+warning: bounds on generic parameters are not enforced in type aliases
+  --> $DIR/type-alias-bounds.rs:66:12
+   |
+LL | type T5<U: Bound> = <U as Bound>::Assoc;  //~ WARN not enforced in type aliases
+   |            ^^^^^
+   |
+   = help: the bound will not be checked when the type alias is used, and should be removed
+
+warning: bounds on generic parameters are not enforced in type aliases
+  --> $DIR/type-alias-bounds.rs:67:12
+   |
+LL | type T6<U: Bound> = ::std::vec::Vec<U>;  //~ WARN not enforced in type aliases
+   |            ^^^^^
+   |
+   = help: the bound will not be checked when the type alias is used, and should be removed
+
diff --git a/src/test/ui/type-check/issue-41314.stderr b/src/test/ui/type-check/issue-41314.stderr
index bcb0f9a99a779..f7d4bb9a02f45 100644
--- a/src/test/ui/type-check/issue-41314.stderr
+++ b/src/test/ui/type-check/issue-41314.stderr
@@ -2,7 +2,7 @@ error[E0026]: variant `X::Y` does not have a field named `number`
   --> $DIR/issue-41314.rs:17:16
    |
 LL |         X::Y { number } => {} //~ ERROR does not have a field named `number`
-   |                ^^^^^^ variant `X::Y` does not have field `number`
+   |                ^^^^^^ variant `X::Y` does not have this field
 
 error[E0027]: pattern does not mention field `0`
   --> $DIR/issue-41314.rs:17:9
diff --git a/src/test/ui/type-dependent-def-issue-49241.rs b/src/test/ui/type-dependent-def-issue-49241.rs
new file mode 100644
index 0000000000000..64264999fd2f1
--- /dev/null
+++ b/src/test/ui/type-dependent-def-issue-49241.rs
@@ -0,0 +1,15 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let v = vec![0];
+    const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item
+    let s: [u32; l] = v.into_iter().collect(); //~ ERROR constant evaluation error
+}
diff --git a/src/test/ui/type-dependent-def-issue-49241.stderr b/src/test/ui/type-dependent-def-issue-49241.stderr
new file mode 100644
index 0000000000000..f00edccae5d50
--- /dev/null
+++ b/src/test/ui/type-dependent-def-issue-49241.stderr
@@ -0,0 +1,18 @@
+error[E0434]: can't capture dynamic environment in a fn item
+  --> $DIR/type-dependent-def-issue-49241.rs:13:22
+   |
+LL |     const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item
+   |                      ^
+   |
+   = help: use the `|| { ... }` closure form instead
+
+error[E0080]: constant evaluation error
+  --> $DIR/type-dependent-def-issue-49241.rs:14:18
+   |
+LL |     let s: [u32; l] = v.into_iter().collect(); //~ ERROR constant evaluation error
+   |                  ^ encountered constants with type errors, stopping evaluation
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0080, E0434.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/src/test/ui/underscore-ident-matcher.rs b/src/test/ui/underscore-ident-matcher.rs
new file mode 100644
index 0000000000000..eee99296c7941
--- /dev/null
+++ b/src/test/ui/underscore-ident-matcher.rs
@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+macro_rules! identity {
+    ($i: ident) => (
+        $i
+    )
+}
+
+fn main() {
+    let identity!(_) = 10; //~ ERROR no rules expected the token `_`
+}
diff --git a/src/test/ui/underscore-ident-matcher.stderr b/src/test/ui/underscore-ident-matcher.stderr
new file mode 100644
index 0000000000000..7f2b6ac30b0da
--- /dev/null
+++ b/src/test/ui/underscore-ident-matcher.stderr
@@ -0,0 +1,8 @@
+error: no rules expected the token `_`
+  --> $DIR/underscore-ident-matcher.rs:18:19
+   |
+LL |     let identity!(_) = 10; //~ ERROR no rules expected the token `_`
+   |                   ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs
new file mode 100644
index 0000000000000..d10541ad33b52
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs
@@ -0,0 +1,26 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Check that the `'_` in `dyn Trait + '_` acts like ordinary elision,
+// and not like an object lifetime default.
+//
+// cc #48468
+
+#![feature(dyn_trait)]
+#![feature(underscore_lifetimes)]
+
+use std::fmt::Debug;
+
+struct Foo {
+    x: Box<dyn Debug + '_>, //~ ERROR missing lifetime specifier
+    //~^ ERROR E0228
+}
+
+fn main() { }
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr
new file mode 100644
index 0000000000000..a88ecb18dd6fe
--- /dev/null
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr
@@ -0,0 +1,16 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/dyn-trait-underscore-in-struct.rs:22:24
+   |
+LL |     x: Box<dyn Debug + '_>, //~ ERROR missing lifetime specifier
+   |                        ^^ expected lifetime parameter
+
+error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
+  --> $DIR/dyn-trait-underscore-in-struct.rs:22:12
+   |
+LL |     x: Box<dyn Debug + '_>, //~ ERROR missing lifetime specifier
+   |            ^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0106, E0228.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/src/test/ui/feature-gate-copy-closures.rs b/src/test/ui/unevaluated_fixed_size_array_len.rs
similarity index 64%
rename from src/test/ui/feature-gate-copy-closures.rs
rename to src/test/ui/unevaluated_fixed_size_array_len.rs
index b11b09eb9fd9b..a6ed9f32106fb 100644
--- a/src/test/ui/feature-gate-copy-closures.rs
+++ b/src/test/ui/unevaluated_fixed_size_array_len.rs
@@ -1,4 +1,4 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,12 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
-    let a = 5;
-    let hello = || {
-        println!("Hello {}", a);
-    };
+// https://github.com/rust-lang/rust/issues/49208
+
+trait Foo {
+    fn foo();
+}
 
-    let b = hello;
-    let c = hello; //~ ERROR use of moved value: `hello` [E0382]
+impl Foo for [(); 1] {
+    fn foo() {}
+}
+
+fn main() {
+    <[(); 0] as Foo>::foo() //~ ERROR E0277
 }
diff --git a/src/test/ui/unevaluated_fixed_size_array_len.stderr b/src/test/ui/unevaluated_fixed_size_array_len.stderr
new file mode 100644
index 0000000000000..6e959da99397b
--- /dev/null
+++ b/src/test/ui/unevaluated_fixed_size_array_len.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied
+  --> $DIR/unevaluated_fixed_size_array_len.rs:22:5
+   |
+LL |     <[(); 0] as Foo>::foo() //~ ERROR E0277
+   |     ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[(); 0]`
+   |
+   = help: the following implementations were found:
+             <[(); 1] as Foo>
+note: required by `Foo::foo`
+  --> $DIR/unevaluated_fixed_size_array_len.rs:14:5
+   |
+LL |     fn foo();
+   |     ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/union/union-fields-2.stderr b/src/test/ui/union/union-fields-2.stderr
index 3ea4d3426dad7..cfb5bc7520b59 100644
--- a/src/test/ui/union/union-fields-2.stderr
+++ b/src/test/ui/union/union-fields-2.stderr
@@ -52,7 +52,7 @@ error[E0026]: union `U` does not have a field named `c`
   --> $DIR/union-fields-2.rs:28:19
    |
 LL |     let U { a, b, c } = u; //~ ERROR union patterns should have exactly one field
-   |                   ^ union `U` does not have field `c`
+   |                   ^ union `U` does not have this field
 
 error: union patterns should have exactly one field
   --> $DIR/union-fields-2.rs:28:9
diff --git a/src/test/ui/wasm-custom-section/malformed.rs b/src/test/ui/wasm-custom-section/malformed.rs
new file mode 100644
index 0000000000000..13b1685a48072
--- /dev/null
+++ b/src/test/ui/wasm-custom-section/malformed.rs
@@ -0,0 +1,19 @@
+// Copyright 2018 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(wasm_custom_section)]
+
+#[wasm_custom_section] //~ ERROR: must be of the form
+const A: [u8; 1] = [0];
+
+#[wasm_custom_section(foo)] //~ ERROR: must be of the form
+const B: [u8; 1] = [0];
+
+fn main() {}
diff --git a/src/test/ui/wasm-custom-section/malformed.stderr b/src/test/ui/wasm-custom-section/malformed.stderr
new file mode 100644
index 0000000000000..c716c824aebda
--- /dev/null
+++ b/src/test/ui/wasm-custom-section/malformed.stderr
@@ -0,0 +1,14 @@
+error: must be of the form #[wasm_custom_section = "foo"]
+  --> $DIR/malformed.rs:13:1
+   |
+LL | #[wasm_custom_section] //~ ERROR: must be of the form
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: must be of the form #[wasm_custom_section = "foo"]
+  --> $DIR/malformed.rs:16:1
+   |
+LL | #[wasm_custom_section(foo)] //~ ERROR: must be of the form
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/wasm-custom-section/not-const.rs b/src/test/ui/wasm-custom-section/not-const.rs
new file mode 100644
index 0000000000000..68077fb2fe4ac
--- /dev/null
+++ b/src/test/ui/wasm-custom-section/not-const.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 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(wasm_custom_section)]
+
+#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+static A: [u8; 2] = [1, 2];
+
+#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+struct B {}
+
+#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+enum C {}
+
+#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+impl B {}
+
+#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+mod d {}
+
+#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+fn main() {}
diff --git a/src/test/ui/wasm-custom-section/not-const.stderr b/src/test/ui/wasm-custom-section/not-const.stderr
new file mode 100644
index 0000000000000..17c85b3e848eb
--- /dev/null
+++ b/src/test/ui/wasm-custom-section/not-const.stderr
@@ -0,0 +1,38 @@
+error: only allowed on consts
+  --> $DIR/not-const.rs:13:1
+   |
+LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: only allowed on consts
+  --> $DIR/not-const.rs:16:1
+   |
+LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: only allowed on consts
+  --> $DIR/not-const.rs:19:1
+   |
+LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: only allowed on consts
+  --> $DIR/not-const.rs:22:1
+   |
+LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: only allowed on consts
+  --> $DIR/not-const.rs:25:1
+   |
+LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: only allowed on consts
+  --> $DIR/not-const.rs:28:1
+   |
+LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/wasm-custom-section/not-slice.rs b/src/test/ui/wasm-custom-section/not-slice.rs
new file mode 100644
index 0000000000000..2d91641a5f756
--- /dev/null
+++ b/src/test/ui/wasm-custom-section/not-slice.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 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(wasm_custom_section)]
+
+#[wasm_custom_section = "foo"]
+const A: u8 = 0; //~ ERROR: must be an array of bytes
+
+#[wasm_custom_section = "foo"]
+const B: &[u8] = &[0]; //~ ERROR: must be an array of bytes
+
+#[wasm_custom_section = "foo"]
+const C: &[u8; 1] = &[0]; //~ ERROR: must be an array of bytes
+
+fn main() {}
diff --git a/src/test/ui/wasm-custom-section/not-slice.stderr b/src/test/ui/wasm-custom-section/not-slice.stderr
new file mode 100644
index 0000000000000..f2563ce0dddc1
--- /dev/null
+++ b/src/test/ui/wasm-custom-section/not-slice.stderr
@@ -0,0 +1,20 @@
+error: must be an array of bytes like `[u8; N]`
+  --> $DIR/not-slice.rs:14:1
+   |
+LL | const A: u8 = 0; //~ ERROR: must be an array of bytes
+   | ^^^^^^^^^^^^^^^^
+
+error: must be an array of bytes like `[u8; N]`
+  --> $DIR/not-slice.rs:17:1
+   |
+LL | const B: &[u8] = &[0]; //~ ERROR: must be an array of bytes
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: must be an array of bytes like `[u8; N]`
+  --> $DIR/not-slice.rs:20:1
+   |
+LL | const C: &[u8; 1] = &[0]; //~ ERROR: must be an array of bytes
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/wasm-import-module.rs b/src/test/ui/wasm-import-module.rs
new file mode 100644
index 0000000000000..0b743d9e486b6
--- /dev/null
+++ b/src/test/ui/wasm-import-module.rs
@@ -0,0 +1,20 @@
+// Copyright 2018 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(wasm_import_module)]
+
+#[wasm_import_module] //~ ERROR: must be of the form
+extern {}
+
+#[wasm_import_module = "foo"] //~ ERROR: must only be attached to
+fn foo() {}
+
+fn main() {}
+
diff --git a/src/test/ui/wasm-import-module.stderr b/src/test/ui/wasm-import-module.stderr
new file mode 100644
index 0000000000000..bf301ce5269a7
--- /dev/null
+++ b/src/test/ui/wasm-import-module.stderr
@@ -0,0 +1,14 @@
+error: must be of the form #[wasm_import_module = "..."]
+  --> $DIR/wasm-import-module.rs:13:1
+   |
+LL | #[wasm_import_module] //~ ERROR: must be of the form
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: must only be attached to foreign modules
+  --> $DIR/wasm-import-module.rs:16:1
+   |
+LL | #[wasm_import_module = "foo"] //~ ERROR: must only be attached to
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/cargo b/src/tools/cargo
index 5f83bb4044f32..311a5eda6f90d 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 5f83bb4044f32b60d06717c609610f67411fc671
+Subproject commit 311a5eda6f90d660bb23e97c8ee77090519b9eda
diff --git a/src/tools/clippy b/src/tools/clippy
index 6f3f25878f227..eafd09010815d 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 6f3f25878f2271911e4b6de4d0cf86accc397455
+Subproject commit eafd09010815da43302ac947afee45b0f5219e6b
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 953a13a3f5820..e826c5366a81f 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1324,6 +1324,8 @@ impl<'test> TestCx<'test> {
         let mut rustdoc = Command::new(rustdoc_path);
 
         rustdoc
+            .arg("-L")
+            .arg(self.config.run_lib_path.to_str().unwrap())
             .arg("-L")
             .arg(aux_dir)
             .arg("-o")
@@ -2358,11 +2360,6 @@ impl<'test> TestCx<'test> {
     }
 
     fn run_rmake_test(&self) {
-        // FIXME(#11094): we should fix these tests
-        if self.config.host != self.config.target {
-            return;
-        }
-
         let cwd = env::current_dir().unwrap();
         let src_root = self.config
             .src_base
@@ -2399,13 +2396,6 @@ impl<'test> TestCx<'test> {
             .env("S", src_root)
             .env("RUST_BUILD_STAGE", &self.config.stage_id)
             .env("RUSTC", cwd.join(&self.config.rustc_path))
-            .env(
-                "RUSTDOC",
-                cwd.join(&self.config
-                    .rustdoc_path
-                    .as_ref()
-                    .expect("--rustdoc-path passed")),
-            )
             .env("TMPDIR", &tmpdir)
             .env("LD_LIB_PATH_ENVVAR", dylib_env_var())
             .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
@@ -2420,6 +2410,14 @@ impl<'test> TestCx<'test> {
             .env_remove("MFLAGS")
             .env_remove("CARGO_MAKEFLAGS");
 
+        if let Some(ref rustdoc) = self.config.rustdoc_path {
+            cmd.env("RUSTDOC", cwd.join(rustdoc));
+        }
+
+        if let Some(ref node) = self.config.nodejs {
+            cmd.env("NODE", node);
+        }
+
         if let Some(ref linker) = self.config.linker {
             cmd.env("RUSTC_LINKER", linker);
         }
@@ -2428,7 +2426,7 @@ impl<'test> TestCx<'test> {
         // compiler flags set in the test cases:
         cmd.env_remove("RUSTFLAGS");
 
-        if self.config.target.contains("msvc") {
+        if self.config.target.contains("msvc") && self.config.cc != "" {
             // We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe`
             // and that `lib.exe` lives next to it.
             let lib = Path::new(&self.config.cc).parent().unwrap().join("lib.exe");
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 0e3fa25b13ce9..c612f0117aaf7 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -14,21 +14,25 @@ use common::Config;
 /// Conversion table from triple OS name to Rust SYSNAME
 const OS_TABLE: &'static [(&'static str, &'static str)] = &[
     ("android", "android"),
+    ("androideabi", "android"),
     ("bitrig", "bitrig"),
     ("cloudabi", "cloudabi"),
     ("darwin", "macos"),
     ("dragonfly", "dragonfly"),
+    ("emscripten", "emscripten"),
     ("freebsd", "freebsd"),
+    ("fuchsia", "fuchsia"),
     ("haiku", "haiku"),
     ("ios", "ios"),
+    ("l4re", "l4re"),
     ("linux", "linux"),
     ("mingw32", "windows"),
     ("netbsd", "netbsd"),
     ("openbsd", "openbsd"),
+    ("redox", "redox"),
+    ("solaris", "solaris"),
     ("win32", "windows"),
     ("windows", "windows"),
-    ("solaris", "solaris"),
-    ("emscripten", "emscripten"),
 ];
 
 const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
@@ -36,20 +40,33 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
     ("amd64", "x86_64"),
     ("arm", "arm"),
     ("arm64", "aarch64"),
+    ("armv4t", "arm"),
+    ("armv5te", "arm"),
+    ("armv7", "arm"),
+    ("armv7s", "arm"),
+    ("asmjs", "asmjs"),
     ("hexagon", "hexagon"),
     ("i386", "x86"),
     ("i586", "x86"),
     ("i686", "x86"),
-    ("mips64", "mips64"),
     ("mips", "mips"),
+    ("mips64", "mips64"),
+    ("mips64el", "mips64"),
+    ("mipsel", "mips"),
     ("msp430", "msp430"),
     ("powerpc", "powerpc"),
+    ("powerpc64", "powerpc64"),
+    ("powerpc64le", "powerpc64"),
     ("s390x", "s390x"),
     ("sparc", "sparc"),
+    ("sparc64", "sparc64"),
+    ("sparcv9", "sparc64"),
+    ("thumbv6m", "thumb"),
+    ("thumbv7em", "thumb"),
+    ("thumbv7m", "thumb"),
+    ("wasm32", "wasm32"),
     ("x86_64", "x86_64"),
     ("xcore", "xcore"),
-    ("asmjs", "asmjs"),
-    ("wasm32", "wasm32"),
 ];
 
 pub fn matches_os(triple: &str, name: &str) -> bool {
@@ -58,16 +75,18 @@ pub fn matches_os(triple: &str, name: &str) -> bool {
     if triple == "wasm32-unknown-unknown" {
         return name == "emscripten" || name == "wasm32-bare"
     }
+    let triple: Vec<_> = triple.split('-').collect();
     for &(triple_os, os) in OS_TABLE {
-        if triple.contains(triple_os) {
+        if triple.contains(&triple_os) {
             return os == name;
         }
     }
     panic!("Cannot determine OS from triple");
 }
 pub fn get_arch(triple: &str) -> &'static str {
+    let triple: Vec<_> = triple.split('-').collect();
     for &(triple_arch, arch) in ARCH_TABLE {
-        if triple.contains(triple_arch) {
+        if triple.contains(&triple_arch) {
             return arch;
         }
     }
diff --git a/src/tools/rls b/src/tools/rls
index fc4db0a5e99e4..f5a0c91a39368 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit fc4db0a5e99e426fd97de370c6f36f585b6af13a
+Subproject commit f5a0c91a39368395b1c1ad322e04be7b6074bc65
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
index 346238f49740d..a4462d18bf6b9 160000
--- a/src/tools/rustfmt
+++ b/src/tools/rustfmt
@@ -1 +1 @@
-Subproject commit 346238f49740d6c98102a6a59811b1625c73a9d7
+Subproject commit a4462d18bf6b92aaec1eeb1c30d5ddf94a3ca987
diff --git a/src/tools/unstable-book-gen/Cargo.toml b/src/tools/unstable-book-gen/Cargo.toml
index 4751a5e41510c..2839f93f8e279 100644
--- a/src/tools/unstable-book-gen/Cargo.toml
+++ b/src/tools/unstable-book-gen/Cargo.toml
@@ -7,3 +7,7 @@ license = "MIT/Apache-2.0"
 
 [dependencies]
 tidy = { path = "../tidy" }
+
+# not actually needed but required for now to unify the feature selection of
+# `num-traits` between this and `rustbook`
+num-traits = "0.2"