Auto merge of #55318 - Aaron1011:fix/final-auto-trait-resolve, r=nikomatsakis

Ensure that Rustdoc discovers all necessary auto trait bounds

Fixes #50159

This commit makes several improvements to AutoTraitFinder:

* Call infcx.resolve_type_vars_if_possible before processing new
predicates. This ensures that we eliminate inference variables wherever
possible.
* Process all nested obligations we get from a vtable, not just ones
with depth=1.
  * The 'depth=1' check was a hack to work around issues processing
certain predicates. The other changes in this commit allow us to
properly process all predicates that we encounter, so the check is no
longer necessary,
* Ensure that we only display predicates *without* inference variables
to the user, and only attempt to unify predicates that *have* an
inference variable as their type.

Additionally, the internal helper method is_of_param now operates
directly on a type, rather than taking a Substs. This allows us to use
the 'self_ty' method, rather than directly dealing with Substs.
diff --git a/.gitmodules b/.gitmodules
index bf9bdd9..4a136cf 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -56,9 +56,15 @@
 [submodule "src/tools/lldb"]
 	path = src/tools/lldb
 	url = https://github.com/rust-lang-nursery/lldb.git
-	branch = rust-release-80-v1
+	branch = rust-release-80-v2
 [submodule "src/tools/clang"]
 	path = src/tools/clang
 	url = https://github.com/rust-lang-nursery/clang.git
-	branch = rust-release-80-v1
+	branch = rust-release-80-v2
 
+[submodule "src/doc/rustc-guide"]
+	path = src/doc/rustc-guide
+	url = https://github.com/rust-lang/rustc-guide.git
+[submodule "src/doc/edition-guide"]
+	path = src/doc/edition-guide
+	url = https://github.com/rust-lang-nursery/edition-guide
diff --git a/.travis.yml b/.travis.yml
index fa66220..3f2e43a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,7 +30,7 @@
 
     - env: >
         RUST_CHECK_TARGET=dist
-        RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler --set rust.jemalloc"
+        RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler --enable-lldb --set rust.jemalloc"
         SRC=.
         DEPLOY_ALT=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
@@ -87,7 +87,7 @@
     # OSX 10.7 and `xcode7` is the latest Xcode able to compile LLVM for 10.7.
     - env: >
         RUST_CHECK_TARGET=dist
-        RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-full-tools --enable-profiler --set rust.jemalloc"
+        RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-full-tools --enable-profiler --enable-lldb --set rust.jemalloc"
         SRC=.
         DEPLOY=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
@@ -102,7 +102,7 @@
 
     - env: >
         RUST_CHECK_TARGET=dist
-        RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc"
+        RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --enable-lldb --set rust.jemalloc"
         SRC=.
         DEPLOY=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
@@ -177,7 +177,7 @@
     - env: IMAGE=x86_64-gnu-aux
       if: branch = auto
     - env: IMAGE=x86_64-gnu-tools
-      if: branch = auto OR (type = pull_request AND commit_message =~ /(?i:^update.*\b(rls|rustfmt|clippy|miri)\b)/)
+      if: branch = auto OR (type = pull_request AND commit_message =~ /(?i:^update.*\b(rls|rustfmt|clippy|miri|cargo)\b)/)
     - env: IMAGE=x86_64-gnu-debug
       if: branch = auto
     - env: IMAGE=x86_64-gnu-nopt
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e04b1bd..137fe61 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -640,7 +640,7 @@
 * **Google!** ([search only in Rust Documentation][gsearchdocs] to find types, traits, etc. quickly)
 * Don't be afraid to ask! The Rust community is friendly and helpful.
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
 [gdfrustc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
 [gsearchdocs]: https://www.google.com/search?q=site:doc.rust-lang.org+your+query+here
 [rif]: http://internals.rust-lang.org
@@ -648,5 +648,5 @@
 [rustforge]: https://forge.rust-lang.org/
 [tlgba]: http://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/
 [ro]: http://www.rustaceans.org/
-[rctd]: https://rust-lang-nursery.github.io/rustc-guide/tests/intro.html
+[rctd]: https://rust-lang.github.io/rustc-guide/tests/intro.html
 [cheatsheet]: https://buildbot2.rust-lang.org/homu/
diff --git a/Cargo.lock b/Cargo.lock
index a7b83f8..02c6320 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -159,10 +159,10 @@
 
 [[package]]
 name = "bytecount"
-version = "0.3.2"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "simd 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "packed_simd 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -201,6 +201,7 @@
  "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "ignore 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "im-rc 12.2.0 (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.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -211,6 +212,7 @@
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "opener 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pretty_env_logger 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-workspace-hack 1.0.0",
  "rustfix 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -625,6 +627,15 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "directories"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "dlmalloc"
 version = "0.0.0"
 dependencies = [
@@ -979,6 +990,15 @@
 ]
 
 [[package]]
+name = "im-rc"
+version = "12.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "installer"
 version = "0.0.0"
 dependencies = [
@@ -1059,7 +1079,7 @@
 
 [[package]]
 name = "languageserver-types"
-version = "0.45.0"
+version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1316,6 +1336,7 @@
  "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiletest_rs 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "vergen 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1438,6 +1459,14 @@
 ]
 
 [[package]]
+name = "packed_simd"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "panic_abort"
 version = "0.0.0"
 dependencies = [
@@ -1581,6 +1610,17 @@
 ]
 
 [[package]]
+name = "pretty_env_logger"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "proc-macro2"
 version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1599,12 +1639,6 @@
 [[package]]
 name = "proc_macro"
 version = "0.0.0"
-dependencies = [
- "rustc_data_structures 0.0.0",
- "rustc_errors 0.0.0",
- "syntax 0.0.0",
- "syntax_pos 0.0.0",
-]
 
 [[package]]
 name = "profiler_builtins"
@@ -1826,7 +1860,7 @@
  "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "languageserver-types 0.45.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "languageserver-types 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1835,7 +1869,7 @@
  "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "rls-analysis 0.16.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rls-analysis 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-data 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-rustc 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1855,7 +1889,7 @@
 
 [[package]]
 name = "rls-analysis"
-version = "0.16.8"
+version = "0.16.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1933,7 +1967,6 @@
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc_macro 0.0.0",
  "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_apfloat 0.0.0",
@@ -2319,7 +2352,6 @@
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
- "rustc_mir 0.0.0",
  "rustc_target 0.0.0",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
@@ -2351,7 +2383,6 @@
  "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc_macro 0.0.0",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -2573,7 +2604,7 @@
 dependencies = [
  "assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytecount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2704,11 +2735,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
-name = "simd"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
 name = "siphasher"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2890,7 +2916,6 @@
 dependencies = [
  "fmt_macros 0.0.0",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc_macro 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
@@ -2980,6 +3005,7 @@
 version = "0.0.0"
 dependencies = [
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc_macro 0.0.0",
  "term 0.0.0",
 ]
 
@@ -3039,6 +3065,11 @@
 ]
 
 [[package]]
+name = "typenum"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "ucd-util"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3259,7 +3290,7 @@
 "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
 "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
 "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
-"checksum bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f861d9ce359f56dbcb6e0c2a1cb84e52ad732cadb57b806adeb3c7668caccbd8"
+"checksum bytecount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b92204551573580e078dc80017f36a213eb77a0450e4ddd8cfa0f3f2d1f0178f"
 "checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
 "checksum bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010"
 "checksum cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d8dfe3adeb30f7938e6c1dd5327f29235d8ada3e898aeb08c343005ec2915a2"
@@ -3293,6 +3324,7 @@
 "checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
 "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
+"checksum directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72d337a64190607d4fcca2cb78982c5dd57f4916e19696b48a575fa746b6cb0f"
 "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
 "checksum elasticlunr-rs 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4837d77a1e157489a3933b743fd774ae75074e0e390b2b7f071530048a0d87ee"
 "checksum ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f56c93cc076508c549d9bb747f79aa9b4eb098be7b8cad8830c3137ef52d1e00"
@@ -3331,6 +3363,7 @@
 "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
 "checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec"
 "checksum ignore 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e9faa7c84064f07b40da27044af629f578bc7994b650d3e458d0c29183c1d91"
+"checksum im-rc 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4591152fd573cf453a890b5f9fdc5c328a751a0785539316739d5f85e5c468c"
 "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053"
 "checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
 "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
@@ -3339,7 +3372,7 @@
 "checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be"
 "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"
-"checksum languageserver-types 0.45.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d91d91d1c23db74187096d191967cb49f49bb175ad6d855fa9229d16ef2c982"
+"checksum languageserver-types 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)" = "68de833188ada4e175d04a028f03f244f6370eedbcc75a05604d47d925933f69"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
 "checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
 "checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0"
@@ -3380,6 +3413,7 @@
 "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
 "checksum ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd20eec3dbe4376829cb7d80ae6ac45e0a766831dca50202ff2d40db46a8a024"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
+"checksum packed_simd 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25d36de864f7218ec5633572a800109bbe5a1cc8d9d95a967f3daf93ea7e6ddc"
 "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
 "checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
 "checksum parking_lot_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06a2b6aae052309c2fd2161ef58f5067bc17bb758377a0de9d4b279d603fdd8a"
@@ -3395,6 +3429,7 @@
 "checksum polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b6b0a7f5f4278b991ffd14abce1d01b013121ad297460237ef0a2f08d43201"
 "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
+"checksum pretty_env_logger 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8d1e63042e889b85228620629b51c011d380eed2c7e0015f8a644def280c28"
 "checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
 "checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
 "checksum proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "926d0604475349f463fe44130aae73f2294b5309ab2ca0310b998bd334ef191f"
@@ -3418,7 +3453,7 @@
 "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
 "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
 "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
-"checksum rls-analysis 0.16.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2a1d3a2a8c03e380331aefb8b5e3e06f3065602fbaa6657ba0ac649dc99d8537"
+"checksum rls-analysis 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2de1187cceaf16d7642cc78835a2890b55b35ed9e8a8e3c6348a6297d8dd0fb1"
 "checksum rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ce1fdac03e138c4617ff87b194e1ff57a39bb985a044ccbd8673d30701e411"
 "checksum rls-data 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a209ce46bb52813cbe0786a7baadc0c1a3f5543ef93f179eda3b841ed72cf2e"
 "checksum rls-rustc 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9dba7390427aefa953608429701e3665192ca810ba8ae09301e001b7c7bed0"
@@ -3454,7 +3489,6 @@
 "checksum serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "bb47a3d5c84320222f66d7db21157c4a7407755de41798f9b4c1c40593397b1a"
 "checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9"
 "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
-"checksum simd 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0048b17eb9577ac545c61d85c3559b41dfb4cbea41c9bd9ca6a4f73ff05fda84"
 "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
 "checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
 "checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
@@ -3482,6 +3516,7 @@
 "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
 "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9"
 "checksum toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6854664bfc6df0360c695480836ee90e2d0c965f06db291d10be9344792d43e8"
+"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
 "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
 "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
 "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
diff --git a/Cargo.toml b/Cargo.toml
index 89cf687..b763caa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -65,6 +65,6 @@
 # here
 rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' }
 
-[patch."https://github.com/rust-lang-nursery/rust-clippy"]
+[patch."https://github.com/rust-lang/rust-clippy"]
 clippy_lints = { path = "src/tools/clippy/clippy_lints" }
 rustc_tools_util = { path = "src/tools/clippy/rustc_tools_util" }
diff --git a/README.md b/README.md
index 0e5b717..3744266 100644
--- a/README.md
+++ b/README.md
@@ -233,7 +233,7 @@
 [IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
 [#rust]: irc://irc.mozilla.org/rust
 [#rust-beginners]: irc://irc.mozilla.org/rust-beginners
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
 [rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
 
 ## License
diff --git a/config.toml.example b/config.toml.example
index 8b11014..f75e220 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -400,6 +400,11 @@
 # override the default allocator for rustc and LLVM.
 #jemalloc = false
 
+# Run tests in various test suites with the "nll compare mode" in addition to
+# running the tests in normal mode. Largely only used on CI and during local
+# development of NLL
+#test-compare-mode = false
+
 # =============================================================================
 # Options for specific targets
 #
diff --git a/src/README.md b/src/README.md
index a4f8996..6522891 100644
--- a/src/README.md
+++ b/src/README.md
@@ -12,4 +12,4 @@
 - https://github.com/rust-lang/rust/tree/master/src/librustc/infer/higher_ranked
 - https://github.com/rust-lang/rust/tree/master/src/librustc/infer/lexical_region_resolve
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index afe1b4c..d18a48e 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -129,10 +129,12 @@
         // Help the libc crate compile by assisting it in finding the MUSL
         // native libraries.
         if let Some(s) = env::var_os("MUSL_ROOT") {
-            let mut root = OsString::from("native=");
-            root.push(&s);
-            root.push("/lib");
-            cmd.arg("-L").arg(&root);
+            if target.contains("musl") {
+                let mut root = OsString::from("native=");
+                root.push(&s);
+                root.push("/lib");
+                cmd.arg("-L").arg(&root);
+            }
         }
 
         // Override linker if necessary.
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 900f336..98005f9 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -390,7 +390,6 @@
                 test::RunPassFullDeps,
                 test::RunFailFullDeps,
                 test::CompileFailFullDeps,
-                test::IncrementalFullDeps,
                 test::Rustdoc,
                 test::Pretty,
                 test::RunPassPretty,
@@ -443,7 +442,8 @@
                 doc::RustdocBook,
                 doc::RustByExample,
                 doc::RustcBook,
-                doc::CargoBook
+                doc::CargoBook,
+                doc::EditionGuide,
             ),
             Kind::Dist => describe!(
                 dist::Docs,
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 0f249ee..8fc2d57 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -58,6 +58,7 @@
     pub ignore_git: bool,
     pub exclude: Vec<PathBuf>,
     pub rustc_error_format: Option<String>,
+    pub test_compare_mode: bool,
 
     pub run_host_only: bool,
 
@@ -326,6 +327,7 @@
     verify_llvm_ir: Option<bool>,
     remap_debuginfo: Option<bool>,
     jemalloc: Option<bool>,
+    test_compare_mode: Option<bool>,
 }
 
 /// TOML representation of how each build target is configured.
@@ -540,6 +542,7 @@
             set(&mut config.codegen_tests, rust.codegen_tests);
             set(&mut config.rust_rpath, rust.rpath);
             set(&mut config.jemalloc, rust.jemalloc);
+            set(&mut config.test_compare_mode, rust.test_compare_mode);
             set(&mut config.backtrace, rust.backtrace);
             set(&mut config.channel, rust.channel.clone());
             set(&mut config.rust_dist_src, rust.dist_src);
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index f9b19ff..e9c27a3 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -70,6 +70,7 @@
 book!(
     Nomicon, "src/doc/nomicon", "nomicon";
     Reference, "src/doc/reference", "reference";
+    EditionGuide, "src/doc/edition-guide", "edition-guide";
     RustdocBook, "src/doc/rustdoc", "rustdoc";
     RustcBook, "src/doc/rustc", "rustc";
     RustByExample, "src/doc/rust-by-example", "rust-by-example";
@@ -696,9 +697,6 @@
             return;
         }
 
-        // Build libstd docs so that we generate relative links.
-        builder.ensure(Std { stage, target });
-
         // Build rustc.
         builder.ensure(compile::Rustc { compiler, target });
 
@@ -717,12 +715,16 @@
 
         // Find dependencies for top level crates.
         let mut compiler_crates = HashSet::new();
-        for root_crate in &["rustc", "rustc_driver", "rustc_codegen_llvm"] {
+        for root_crate in &["rustc_driver", "rustc_codegen_llvm", "rustc_codegen_ssa"] {
             let interned_root_crate = INTERNER.intern_str(root_crate);
             find_compiler_crates(builder, &interned_root_crate, &mut compiler_crates);
         }
 
         for krate in &compiler_crates {
+            // 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)));
             cargo.arg("-p").arg(krate);
         }
 
@@ -796,8 +798,8 @@
             return;
         }
 
-        // Build libstd docs so that we generate relative links.
-        builder.ensure(Std { stage, target });
+        // Build rustc docs so that we generate relative links.
+        builder.ensure(Rustc { stage, target });
 
         // Build rustdoc.
         builder.ensure(tool::Rustdoc { host: compiler.host });
@@ -821,6 +823,10 @@
             &[]
         );
 
+        // Only include compiler crates, no dependencies of those, such as `libc`.
+        cargo.arg("--no-deps");
+        cargo.arg("-p").arg("rustdoc");
+
         cargo.env("RUSTDOCFLAGS", "--document-private-items");
         builder.run(&mut cargo);
     }
@@ -914,13 +920,13 @@
     }
     if let Ok(m) = fs::symlink_metadata(dst) {
         if m.file_type().is_dir() {
-            try!(fs::remove_dir_all(dst));
+            fs::remove_dir_all(dst)?;
         } else {
             // handle directory junctions on windows by falling back to
             // `remove_dir`.
-            try!(fs::remove_file(dst).or_else(|_| {
+            fs::remove_file(dst).or_else(|_| {
                 fs::remove_dir(dst)
-            }));
+            })?;
         }
     }
 
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 76697e4..2832f5b 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -777,10 +777,10 @@
     fn cflags(&self, target: Interned<String>, which: GitRepo) -> Vec<String> {
         // Filter out -O and /O (the optimization flags) that we picked up from
         // cc-rs because the build scripts will determine that for themselves.
-        let mut base: Vec<String> = self.cc[&target].args().iter()
+        let mut base = self.cc[&target].args().iter()
                            .map(|s| s.to_string_lossy().into_owned())
                            .filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
-                           .collect::<Vec<_>>();
+                           .collect::<Vec<String>>();
 
         // If we're compiling on macOS then we add a few unconditional flags
         // indicating that we want libc++ (more filled out than libstdc++) and
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index e5577301..da82735 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -839,12 +839,6 @@
     suite: "compile-fail-fulldeps"
 });
 
-host_test!(IncrementalFullDeps {
-    path: "src/test/incremental-fulldeps",
-    mode: "incremental",
-    suite: "incremental-fulldeps"
-});
-
 host_test!(Rustdoc {
     path: "src/test/rustdoc",
     mode: "rustdoc",
@@ -982,6 +976,11 @@
             builder.ensure(compile::Std { compiler, target: compiler.host });
         }
 
+        // HACK(eddyb) ensure that `libproc_macro` is available on the host.
+        builder.ensure(compile::Test { compiler, target: compiler.host });
+        // Also provide `rust_test_helpers` for the host.
+        builder.ensure(native::TestHelpers { target: compiler.host });
+
         builder.ensure(native::TestHelpers { target });
         builder.ensure(RemoteCopyLibs { compiler, target });
 
@@ -1023,7 +1022,13 @@
             cmd.arg("--bless");
         }
 
-        let compare_mode = builder.config.cmd.compare_mode().or(self.compare_mode);
+        let compare_mode = builder.config.cmd.compare_mode().or_else(|| {
+            if builder.config.test_compare_mode {
+                self.compare_mode
+            } else {
+                None
+            }
+        });
 
         if let Some(ref nodejs) = builder.config.nodejs {
             cmd.arg("--nodejs").arg(nodejs);
@@ -1049,7 +1054,11 @@
             cmd.arg("--linker").arg(linker);
         }
 
-        let hostflags = flags.clone();
+        let mut hostflags = flags.clone();
+        hostflags.push(format!(
+            "-Lnative={}",
+            builder.test_helpers_out(compiler.host).display()
+        ));
         cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
 
         let mut targetflags = flags;
diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs
index 8ce8f20..be24ae0 100644
--- a/src/bootstrap/util.rs
+++ b/src/bootstrap/util.rs
@@ -203,11 +203,11 @@
         // We're using low-level APIs to create the junction, and these are more
         // picky about paths. For example, forward slashes cannot be used as a
         // path separator, so we should try to canonicalize the path first.
-        let target = try!(fs::canonicalize(target));
+        let target = fs::canonicalize(target)?;
 
-        try!(fs::create_dir(junction));
+        fs::create_dir(junction)?;
 
-        let path = try!(to_u16s(junction));
+        let path = to_u16s(junction)?;
 
         unsafe {
             let h = CreateFileW(path.as_ptr(),
diff --git a/src/ci/docker/x86_64-gnu-nopt/Dockerfile b/src/ci/docker/x86_64-gnu-nopt/Dockerfile
index d2b0dd1..b0780fd 100644
--- a/src/ci/docker/x86_64-gnu-nopt/Dockerfile
+++ b/src/ci/docker/x86_64-gnu-nopt/Dockerfile
@@ -16,5 +16,7 @@
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
-ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --disable-optimize-tests
+ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu \
+  --disable-optimize-tests \
+  --set rust.test-compare-mode
 ENV RUST_CHECK_TARGET check
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
new file mode 160000
index 0000000..419edb8
--- /dev/null
+++ b/src/doc/edition-guide
@@ -0,0 +1 @@
+Subproject commit 419edb885ec1a98c0747b3907003d79e3e6b93a9
diff --git a/src/doc/index.md b/src/doc/index.md
index 33ee767..b79a349 100644
--- a/src/doc/index.md
+++ b/src/doc/index.md
@@ -21,6 +21,9 @@
 #search-but:hover, #search-input:focus {
     border-color: #55a9ff;
 }
+h2 {
+    font-size: 18px;
+}
 </style>
 
 Welcome to an overview of the documentation provided by the Rust project.
diff --git a/src/doc/nomicon b/src/doc/nomicon
index f8a4e96..b7eb4a0 160000
--- a/src/doc/nomicon
+++ b/src/doc/nomicon
@@ -1 +1 @@
-Subproject commit f8a4e96feb2e5a6ed1ef170ad40e3509a7755cb4
+Subproject commit b7eb4a087207af2405c0669fa577f8545b894c66
diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide
new file mode 160000
index 0000000..344c4e4
--- /dev/null
+++ b/src/doc/rustc-guide
@@ -0,0 +1 @@
+Subproject commit 344c4e437ba4cfa5c14db643ec4d6b68dcd164c5
diff --git a/src/doc/rustc/src/contributing.md b/src/doc/rustc/src/contributing.md
index fcb8e6b..3a1cafe 100644
--- a/src/doc/rustc/src/contributing.md
+++ b/src/doc/rustc/src/contributing.md
@@ -1,6 +1,6 @@
 # Contributing to rustc
 
 We'd love to have your help improving `rustc`! To that end, we've written [a
-whole book](https://rust-lang-nursery.github.io/rustc-guide/) on its
+whole book](https://rust-lang.github.io/rustc-guide/) on its
 internals, how it works, and how to get started working on it. To learn
-more, you'll want to check that out.
\ No newline at end of file
+more, you'll want to check that out.
diff --git a/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md b/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md
deleted file mode 100644
index 251fc72..0000000
--- a/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# `macro_at_most_once_rep`
-
-NOTE: This feature is only available in the 2018 Edition.
-
-The tracking issue for this feature is: #48075
-
-With this feature gate enabled, one can use `?` as a Kleene operator meaning "0
-or 1 repetitions" in a macro definition. Previously only `+` and `*` were allowed.
-
-For example:
-
-```rust,ignore
-#![feature(macro_at_most_once_rep)]
-
-macro_rules! foo {
-    (something $(,)?) // `?` indicates `,` is "optional"...
-        => {}
-}
-```
-
-------------------------
-
diff --git a/src/doc/unstable-book/src/language-features/marker-trait-attr.md b/src/doc/unstable-book/src/language-features/marker-trait-attr.md
index 9dd7b6f..dedc7d3 100644
--- a/src/doc/unstable-book/src/language-features/marker-trait-attr.md
+++ b/src/doc/unstable-book/src/language-features/marker-trait-attr.md
@@ -17,15 +17,17 @@
 ```rust
 #![feature(marker_trait_attr)]
 
-use std::fmt::{Debug, Display};
+#[marker] trait CheapToClone: Clone {}
 
-#[marker] trait MyMarker {}
+impl<T: Copy> CheapToClone for T {}
 
-impl<T: Debug> MyMarker for T {}
-impl<T: Display> MyMarker for T {}
+// These could potentally overlap with the blanket implementation above,
+// so are only allowed because CheapToClone is a marker trait.
+impl<T: CheapToClone, U: CheapToClone> CheapToClone for (T, U) {}
+impl<T: CheapToClone> CheapToClone for std::ops::Range<T> {}
 
-fn foo<T: MyMarker>(t: T) -> T {
-    t
+fn cheap_clone<T: CheapToClone>(t: T) -> T {
+    t.clone()
 }
 ```
 
diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md
index 74bdd4d..03ea392 100644
--- a/src/doc/unstable-book/src/language-features/plugin.md
+++ b/src/doc/unstable-book/src/language-features/plugin.md
@@ -181,7 +181,6 @@
 ```rust,ignore
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 extern crate syntax;
 
diff --git a/src/doc/unstable-book/src/language-features/self-in-typedefs.md b/src/doc/unstable-book/src/language-features/self-in-typedefs.md
deleted file mode 100644
index 2416e85..0000000
--- a/src/doc/unstable-book/src/language-features/self-in-typedefs.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# `self_in_typedefs`
-
-The tracking issue for this feature is: [#49303]
-
-[#49303]: https://github.com/rust-lang/rust/issues/49303
-
-------------------------
-
-The `self_in_typedefs` feature gate lets you use the special `Self` identifier
-in `struct`, `enum`, and `union` type definitions.
-
-A simple example is:
-
-```rust
-#![feature(self_in_typedefs)]
-
-enum List<T>
-where
-    Self: PartialOrd<Self> // can write `Self` instead of `List<T>`
-{
-    Nil,
-    Cons(T, Box<Self>) // likewise here
-}
-```
diff --git a/src/doc/unstable-book/src/language-features/self-struct-ctor.md b/src/doc/unstable-book/src/language-features/self-struct-ctor.md
deleted file mode 100644
index b4742c4..0000000
--- a/src/doc/unstable-book/src/language-features/self-struct-ctor.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# `self_struct_ctor`
-
-The tracking issue for this feature is: [#51994]
-[#51994]: https://github.com/rust-lang/rust/issues/51994
-
-------------------------
-
-The `self_struct_ctor` feature gate lets you use the special `Self`
-identifier as a constructor and a pattern.
-
-A simple example is:
-
-```rust
-#![feature(self_struct_ctor)]
-
-struct ST(i32, i32);
-
-impl ST {
-    fn new() -> Self {
-        ST(0, 1)
-    }
-
-    fn ctor() -> Self {
-        Self(1,2)           // constructed by `Self`, it is the same as `ST(1, 2)`
-    }
-
-    fn pattern(self) {
-        match self {
-            Self(x, y) => println!("{} {}", x, y), // used as a pattern
-        }
-    }
-}
-```
diff --git a/src/grammar/parser-lalr.y b/src/grammar/parser-lalr.y
index a7da69f..8ea1cb2 100644
--- a/src/grammar/parser-lalr.y
+++ b/src/grammar/parser-lalr.y
@@ -741,14 +741,14 @@
 ;
 
 fn_params_with_self
-: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')'              { $$ = mk_node("SelfValue", 3, $2, $4, $5); }
+: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')'              { $$ = mk_node("SelfLower", 3, $2, $4, $5); }
 | '(' '&' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')'          { $$ = mk_node("SelfRegion", 3, $3, $5, $6); }
 | '(' '&' lifetime maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfRegion", 4, $3, $4, $6, $7); }
 | '(' maybe_params ')'                                                       { $$ = mk_node("SelfStatic", 1, $2); }
 ;
 
 fn_anon_params_with_self
-: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')'              { $$ = mk_node("SelfValue", 3, $2, $4, $5); }
+: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')'              { $$ = mk_node("SelfLower", 3, $2, $4, $5); }
 | '(' '&' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')'          { $$ = mk_node("SelfRegion", 3, $3, $5, $6); }
 | '(' '&' lifetime maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfRegion", 4, $3, $4, $6, $7); }
 | '(' maybe_anon_params ')'                                                       { $$ = mk_node("SelfStatic", 1, $2); }
diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs
index fcadcb5..8c36962 100644
--- a/src/liballoc/collections/binary_heap.rs
+++ b/src/liballoc/collections/binary_heap.rs
@@ -529,7 +529,7 @@
     /// assert!(heap.capacity() >= 10);
     /// ```
     #[inline]
-    #[unstable(feature = "shrink_to", reason = "new API", issue="0")]
+    #[unstable(feature = "shrink_to", reason = "new API", issue="56431")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.data.shrink_to(min_capacity)
     }
diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs
index f9b455f..215689d 100644
--- a/src/liballoc/collections/btree/node.rs
+++ b/src/liballoc/collections/btree/node.rs
@@ -602,7 +602,7 @@
         } else {
             unsafe {
                 slice::from_raw_parts_mut(
-                    self.as_leaf_mut().keys.get_mut() as *mut [K] as *mut K,
+                    self.as_leaf_mut().keys.as_mut_ptr() as *mut K,
                     self.len()
                 )
             }
@@ -613,7 +613,7 @@
         debug_assert!(!self.is_shared_root());
         unsafe {
             slice::from_raw_parts_mut(
-                self.as_leaf_mut().vals.get_mut() as *mut [V] as *mut V,
+                self.as_leaf_mut().vals.as_mut_ptr() as *mut V,
                 self.len()
             )
         }
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index cbf104a..c8ee40f 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -19,7 +19,7 @@
 
 use core::cmp::Ordering;
 use core::fmt;
-use core::iter::{repeat, repeat_with, FromIterator, FusedIterator};
+use core::iter::{repeat_with, FromIterator, FusedIterator};
 use core::mem;
 use core::ops::Bound::{Excluded, Included, Unbounded};
 use core::ops::{Index, IndexMut, RangeBounds};
@@ -701,7 +701,7 @@
     /// buf.shrink_to(0);
     /// assert!(buf.capacity() >= 4);
     /// ```
-    #[unstable(feature = "shrink_to", reason = "new API", issue="0")]
+    #[unstable(feature = "shrink_to", reason = "new API", issue="56431")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity");
 
@@ -1886,40 +1886,6 @@
             debug_assert!(!self.is_full());
         }
     }
-}
-
-impl<T: Clone> VecDeque<T> {
-    /// Modifies the `VecDeque` in-place so that `len()` is equal to new_len,
-    /// either by removing excess elements from the back or by appending clones of `value`
-    /// to the back.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::VecDeque;
-    ///
-    /// let mut buf = VecDeque::new();
-    /// buf.push_back(5);
-    /// buf.push_back(10);
-    /// buf.push_back(15);
-    /// assert_eq!(buf, [5, 10, 15]);
-    ///
-    /// buf.resize(2, 0);
-    /// assert_eq!(buf, [5, 10]);
-    ///
-    /// buf.resize(5, 20);
-    /// assert_eq!(buf, [5, 10, 20, 20, 20]);
-    /// ```
-    #[stable(feature = "deque_extras", since = "1.16.0")]
-    pub fn resize(&mut self, new_len: usize, value: T) {
-        let len = self.len();
-
-        if new_len > len {
-            self.extend(repeat(value).take(new_len - len))
-        } else {
-            self.truncate(new_len);
-        }
-    }
 
     /// Modifies the `VecDeque` in-place so that `len()` is equal to `new_len`,
     /// either by removing excess elements from the back or by appending
@@ -1960,6 +1926,34 @@
     }
 }
 
+impl<T: Clone> VecDeque<T> {
+    /// Modifies the `VecDeque` in-place so that `len()` is equal to new_len,
+    /// either by removing excess elements from the back or by appending clones of `value`
+    /// to the back.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(5);
+    /// buf.push_back(10);
+    /// buf.push_back(15);
+    /// assert_eq!(buf, [5, 10, 15]);
+    ///
+    /// buf.resize(2, 0);
+    /// assert_eq!(buf, [5, 10]);
+    ///
+    /// buf.resize(5, 20);
+    /// assert_eq!(buf, [5, 10, 20, 20, 20]);
+    /// ```
+    #[stable(feature = "deque_extras", since = "1.16.0")]
+    pub fn resize(&mut self, new_len: usize, value: T) {
+        self.resize_with(new_len, || value.clone());
+    }
+}
+
 /// Returns the index in the underlying buffer for a given logical element index.
 #[inline]
 fn wrap_index(index: usize, size: usize) -> usize {
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 3ca6de1..c0a947e 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -1187,8 +1187,9 @@
 
 impl<T> Weak<T> {
     /// Constructs a new `Weak<T>`, without allocating any memory.
-    /// Calling [`upgrade`][Weak::upgrade] on the return value always gives [`None`].
+    /// Calling [`upgrade`] on the return value always gives [`None`].
     ///
+    /// [`upgrade`]: #method.upgrade
     /// [`None`]: ../../std/option/enum.Option.html
     ///
     /// # Examples
@@ -1260,6 +1261,52 @@
             Some(unsafe { self.ptr.as_ref() })
         }
     }
+
+    /// Returns true if the two `Weak`s point to the same value (not just values
+    /// that compare as equal).
+    ///
+    /// # Notes
+    ///
+    /// Since this compares pointers it means that `Weak::new()` will equal each
+    /// other, even though they don't point to any value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(weak_ptr_eq)]
+    /// use std::rc::{Rc, Weak};
+    ///
+    /// let first_rc = Rc::new(5);
+    /// let first = Rc::downgrade(&first_rc);
+    /// let second = Rc::downgrade(&first_rc);
+    ///
+    /// assert!(Weak::ptr_eq(&first, &second));
+    ///
+    /// let third_rc = Rc::new(5);
+    /// let third = Rc::downgrade(&third_rc);
+    ///
+    /// assert!(!Weak::ptr_eq(&first, &third));
+    /// ```
+    ///
+    /// Comparing `Weak::new`.
+    ///
+    /// ```
+    /// #![feature(weak_ptr_eq)]
+    /// use std::rc::{Rc, Weak};
+    ///
+    /// let first = Weak::new();
+    /// let second = Weak::new();
+    /// assert!(Weak::ptr_eq(&first, &second));
+    ///
+    /// let third_rc = Rc::new(());
+    /// let third = Rc::downgrade(&third_rc);
+    /// assert!(!Weak::ptr_eq(&first, &third));
+    /// ```
+    #[inline]
+    #[unstable(feature = "weak_ptr_eq", issue = "55981")]
+    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
+        this.ptr.as_ptr() == other.ptr.as_ptr()
+    }
 }
 
 #[stable(feature = "rc_weak", since = "1.4.0")]
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 8d00910..006c602 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -577,7 +577,7 @@
             return Cow::Borrowed("");
         };
 
-        const REPLACEMENT: &'static str = "\u{FFFD}";
+        const REPLACEMENT: &str = "\u{FFFD}";
 
         let mut res = String::with_capacity(v.len());
         res.push_str(first_valid);
@@ -618,6 +618,8 @@
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error> {
+        // This isn't done via collect::<Result<_, _>>() for performance reasons.
+        // FIXME: the function can be simplified again when #48994 is closed.
         let mut ret = String::with_capacity(v.len());
         for c in decode_utf16(v.iter().cloned()) {
             if let Ok(c) = c {
@@ -1048,7 +1050,7 @@
     /// assert!(s.capacity() >= 3);
     /// ```
     #[inline]
-    #[unstable(feature = "shrink_to", reason = "new API", issue="0")]
+    #[unstable(feature = "shrink_to", reason = "new API", issue="56431")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.vec.shrink_to(min_capacity)
     }
@@ -1730,18 +1732,37 @@
 #[stable(feature = "extend_string", since = "1.4.0")]
 impl FromIterator<String> for String {
     fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String {
-        let mut buf = String::new();
-        buf.extend(iter);
-        buf
+        let mut iterator = iter.into_iter();
+
+        // Because we're iterating over `String`s, we can avoid at least
+        // one allocation by getting the first string from the iterator
+        // and appending to it all the subsequent strings.
+        match iterator.next() {
+            None => String::new(),
+            Some(mut buf) => {
+                buf.extend(iterator);
+                buf
+            }
+        }
     }
 }
 
 #[stable(feature = "herd_cows", since = "1.19.0")]
 impl<'a> FromIterator<Cow<'a, str>> for String {
     fn from_iter<I: IntoIterator<Item = Cow<'a, str>>>(iter: I) -> String {
-        let mut buf = String::new();
-        buf.extend(iter);
-        buf
+        let mut iterator = iter.into_iter();
+
+        // Because we're iterating over CoWs, we can (potentially) avoid at least
+        // one allocation by getting the first item and appending to it all the
+        // subsequent items.
+        match iterator.next() {
+            None => String::new(),
+            Some(cow) => {
+                let mut buf = cow.into_owned();
+                buf.extend(iterator);
+                buf
+            }
+        }
     }
 }
 
@@ -1751,9 +1772,7 @@
         let iterator = iter.into_iter();
         let (lower_bound, _) = iterator.size_hint();
         self.reserve(lower_bound);
-        for ch in iterator {
-            self.push(ch)
-        }
+        iterator.for_each(move |c| self.push(c));
     }
 }
 
@@ -1767,27 +1786,21 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Extend<&'a str> for String {
     fn extend<I: IntoIterator<Item = &'a str>>(&mut self, iter: I) {
-        for s in iter {
-            self.push_str(s)
-        }
+        iter.into_iter().for_each(move |s| self.push_str(s));
     }
 }
 
 #[stable(feature = "extend_string", since = "1.4.0")]
 impl Extend<String> for String {
     fn extend<I: IntoIterator<Item = String>>(&mut self, iter: I) {
-        for s in iter {
-            self.push_str(&s)
-        }
+        iter.into_iter().for_each(move |s| self.push_str(&s));
     }
 }
 
 #[stable(feature = "herd_cows", since = "1.19.0")]
 impl<'a> Extend<Cow<'a, str>> for String {
     fn extend<I: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: I) {
-        for s in iter {
-            self.push_str(&s)
-        }
+        iter.into_iter().for_each(move |s| self.push_str(&s));
     }
 }
 
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 4f4031e..0a397f7 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -1130,6 +1130,53 @@
             Some(unsafe { self.ptr.as_ref() })
         }
     }
+
+    /// Returns true if the two `Weak`s point to the same value (not just values
+    /// that compare as equal).
+    ///
+    /// # Notes
+    ///
+    /// Since this compares pointers it means that `Weak::new()` will equal each
+    /// other, even though they don't point to any value.
+    ///
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(weak_ptr_eq)]
+    /// use std::sync::{Arc, Weak};
+    ///
+    /// let first_rc = Arc::new(5);
+    /// let first = Arc::downgrade(&first_rc);
+    /// let second = Arc::downgrade(&first_rc);
+    ///
+    /// assert!(Weak::ptr_eq(&first, &second));
+    ///
+    /// let third_rc = Arc::new(5);
+    /// let third = Arc::downgrade(&third_rc);
+    ///
+    /// assert!(!Weak::ptr_eq(&first, &third));
+    /// ```
+    ///
+    /// Comparing `Weak::new`.
+    ///
+    /// ```
+    /// #![feature(weak_ptr_eq)]
+    /// use std::sync::{Arc, Weak};
+    ///
+    /// let first = Weak::new();
+    /// let second = Weak::new();
+    /// assert!(Weak::ptr_eq(&first, &second));
+    ///
+    /// let third_rc = Arc::new(());
+    /// let third = Arc::downgrade(&third_rc);
+    /// assert!(!Weak::ptr_eq(&first, &third));
+    /// ```
+    #[inline]
+    #[unstable(feature = "weak_ptr_eq", issue = "55981")]
+    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
+        this.ptr.as_ptr() == other.ptr.as_ptr()
+    }
 }
 
 #[stable(feature = "arc_weak", since = "1.4.0")]
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index f7a0bbd..ca7c766 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -613,7 +613,7 @@
     /// vec.shrink_to(0);
     /// assert!(vec.capacity() >= 3);
     /// ```
-    #[unstable(feature = "shrink_to", reason = "new API", issue="0")]
+    #[unstable(feature = "shrink_to", reason = "new API", issue="56431")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.buf.shrink_to_fit(cmp::max(self.len, min_capacity));
     }
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index dae05a3..aef3edd 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -224,14 +224,14 @@
         unsafe {
             // Clear the last chunk, which is partially filled.
             let mut chunks_borrow = self.chunks.borrow_mut();
-            if let Some(mut last_chunk) = chunks_borrow.pop() {
+            if let Some(mut last_chunk) = chunks_borrow.last_mut() {
                 self.clear_last_chunk(&mut last_chunk);
+                let len = chunks_borrow.len();
                 // If `T` is ZST, code below has no effect.
-                for mut chunk in chunks_borrow.drain(..) {
+                for mut chunk in chunks_borrow.drain(..len-1) {
                     let cap = chunk.storage.cap();
                     chunk.destroy(cap);
                 }
-                chunks_borrow.push(last_chunk);
             }
         }
     }
@@ -298,6 +298,7 @@
 unsafe impl Send for DroplessArena {}
 
 impl Default for DroplessArena {
+    #[inline]
     fn default() -> DroplessArena {
         DroplessArena {
             ptr: Cell::new(0 as *mut u8),
@@ -310,15 +311,11 @@
 impl DroplessArena {
     pub fn in_arena<T: ?Sized>(&self, ptr: *const T) -> bool {
         let ptr = ptr as *const u8 as *mut u8;
-        for chunk in &*self.chunks.borrow() {
-            if chunk.start() <= ptr && ptr < chunk.end() {
-                return true;
-            }
-        }
 
-        false
+        self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end())
     }
 
+    #[inline]
     fn align(&self, align: usize) {
         let final_address = ((self.ptr.get() as usize) + align - 1) & !(align - 1);
         self.ptr.set(final_address as *mut u8);
@@ -408,7 +405,7 @@
     {
         assert!(!mem::needs_drop::<T>());
         assert!(mem::size_of::<T>() != 0);
-        assert!(slice.len() != 0);
+        assert!(!slice.is_empty());
 
         let mem = self.alloc_raw(
             slice.len() * mem::size_of::<T>(),
@@ -604,6 +601,15 @@
         }
     }
 
+    #[bench]
+    pub fn bench_typed_arena_clear(b: &mut Bencher) {
+        let mut arena = TypedArena::default();
+        b.iter(|| {
+            arena.alloc(Point { x: 1, y: 2, z: 3 });
+            arena.clear();
+        })
+    }
+
     // Drop tests
 
     struct DropCounter<'a> {
diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml
index 0b01cfc..7fd61f0 100644
--- a/src/libcore/Cargo.toml
+++ b/src/libcore/Cargo.toml
@@ -21,3 +21,7 @@
 
 [dev-dependencies]
 rand = "0.5"
+
+[features]
+# Make panics and failed asserts immediately abort without formatting any message
+panic_immediate_abort = []
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 3d24f89..26e7a79 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -149,6 +149,15 @@
             }
 
             #[unstable(feature = "try_from", issue = "33417")]
+            impl<'a, T> TryFrom<&'a [T]> for [T; $N] where T: Copy {
+                type Error = TryFromSliceError;
+
+                fn try_from(slice: &[T]) -> Result<[T; $N], TryFromSliceError> {
+                    <&Self>::try_from(slice).map(|r| *r)
+                }
+            }
+
+            #[unstable(feature = "try_from", issue = "33417")]
             impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
                 type Error = TryFromSliceError;
 
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index a03756f..edeb3b0 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -1,6 +1,7 @@
 #![stable(feature = "", since = "1.30.0")]
 
 #![allow(non_camel_case_types)]
+#![cfg_attr(stage0, allow(dead_code))]
 
 //! Utilities related to FFI bindings.
 
@@ -40,3 +41,187 @@
         f.pad("c_void")
     }
 }
+
+/// Basic implementation of a `va_list`.
+#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
+              not(target_arch = "x86_64")),
+          windows))]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "27745")]
+extern {
+    type VaListImpl;
+}
+
+#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
+              not(target_arch = "x86_64")),
+          windows))]
+impl fmt::Debug for VaListImpl {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "va_list* {:p}", self)
+    }
+}
+
+/// AArch64 ABI implementation of a `va_list`. See the
+/// [Aarch64 Procedure Call Standard] for more details.
+///
+/// [AArch64 Procedure Call Standard]:
+/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
+#[cfg(all(target_arch = "aarch64", not(windows)))]
+#[repr(C)]
+#[derive(Debug)]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "27745")]
+struct VaListImpl {
+    stack: *mut (),
+    gr_top: *mut (),
+    vr_top: *mut (),
+    gr_offs: i32,
+    vr_offs: i32,
+}
+
+/// PowerPC ABI implementation of a `va_list`.
+#[cfg(all(target_arch = "powerpc", not(windows)))]
+#[repr(C)]
+#[derive(Debug)]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "27745")]
+struct VaListImpl {
+    gpr: u8,
+    fpr: u8,
+    reserved: u16,
+    overflow_arg_area: *mut (),
+    reg_save_area: *mut (),
+}
+
+/// x86_64 ABI implementation of a `va_list`.
+#[cfg(all(target_arch = "x86_64", not(windows)))]
+#[repr(C)]
+#[derive(Debug)]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "27745")]
+struct VaListImpl {
+    gp_offset: i32,
+    fp_offset: i32,
+    overflow_arg_area: *mut (),
+    reg_save_area: *mut (),
+}
+
+/// A wrapper for a `va_list`
+#[lang = "va_list"]
+#[derive(Debug)]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "27745")]
+#[repr(transparent)]
+#[cfg(not(stage0))]
+pub struct VaList<'a>(&'a mut VaListImpl);
+
+// The VaArgSafe trait needs to be used in public interfaces, however, the trait
+// itself must not be allowed to be used outside this module. Allowing users to
+// implement the trait for a new type (thereby allowing the va_arg intrinsic to
+// be used on a new type) is likely to cause undefined behavior.
+//
+// FIXME(dlrobertson): In order to use the VaArgSafe trait in a public interface
+// but also ensure it cannot be used elsewhere, the trait needs to be public
+// within a private module. Once RFC 2145 has been implemented look into
+// improving this.
+mod sealed_trait {
+    /// Trait which whitelists the allowed types to be used with [VaList::arg]
+    ///
+    /// [VaList::va_arg]: struct.VaList.html#method.arg
+    #[unstable(feature = "c_variadic",
+               reason = "the `c_variadic` feature has not been properly tested on \
+                         all supported platforms",
+               issue = "27745")]
+    pub trait VaArgSafe {}
+}
+
+macro_rules! impl_va_arg_safe {
+    ($($t:ty),+) => {
+        $(
+            #[unstable(feature = "c_variadic",
+                       reason = "the `c_variadic` feature has not been properly tested on \
+                                 all supported platforms",
+                       issue = "27745")]
+            impl sealed_trait::VaArgSafe for $t {}
+        )+
+    }
+}
+
+impl_va_arg_safe!{i8, i16, i32, i64, usize}
+impl_va_arg_safe!{u8, u16, u32, u64, isize}
+impl_va_arg_safe!{f64}
+
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "27745")]
+impl<T> sealed_trait::VaArgSafe for *mut T {}
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "27745")]
+impl<T> sealed_trait::VaArgSafe for *const T {}
+
+#[cfg(not(stage0))]
+impl<'a> VaList<'a> {
+    /// Advance to the next arg.
+    #[unstable(feature = "c_variadic",
+               reason = "the `c_variadic` feature has not been properly tested on \
+                         all supported platforms",
+               issue = "27745")]
+    pub unsafe fn arg<T: sealed_trait::VaArgSafe>(&mut self) -> T {
+        va_arg(self)
+    }
+
+    /// Copy the `va_list` at the current location.
+    #[unstable(feature = "c_variadic",
+               reason = "the `c_variadic` feature has not been properly tested on \
+                         all supported platforms",
+               issue = "27745")]
+    pub unsafe fn copy<F, R>(&mut self, f: F) -> R
+            where F: for<'copy> FnOnce(VaList<'copy>) -> R {
+        #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
+                      not(target_arch = "x86_64")),
+                  windows))]
+        let mut ap = va_copy(self);
+        #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
+                  not(windows)))]
+        let mut ap_inner = va_copy(self);
+        #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
+                  not(windows)))]
+        let mut ap = VaList(&mut ap_inner);
+        let ret = f(VaList(ap.0));
+        va_end(&mut ap);
+        ret
+    }
+}
+
+#[cfg(not(stage0))]
+extern "rust-intrinsic" {
+    /// Destroy the arglist `ap` after initialization with `va_start` or
+    /// `va_copy`.
+    fn va_end(ap: &mut VaList);
+
+    /// Copy the current location of arglist `src` to the arglist `dst`.
+    #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
+                  not(target_arch = "x86_64")),
+              windows))]
+    fn va_copy<'a>(src: &VaList<'a>) -> VaList<'a>;
+    #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
+              not(windows)))]
+    fn va_copy(src: &VaList) -> VaListImpl;
+
+    /// Loads an argument of type `T` from the `va_list` `ap` and increment the
+    /// argument `ap` points to.
+    fn va_arg<T: sealed_trait::VaArgSafe>(ap: &mut VaList) -> T;
+}
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index d01cd01..3717a78 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -22,6 +22,9 @@
     unsafe {
         let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64
         let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized();
+        // FIXME(#53491): Technically, this is calling `get_mut` on an uninitialized
+        // `MaybeUninit` (here and elsewhere in this file).  Revisit this once
+        // we decided whether that is valid or not.
         let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
                                                     *num, sign, precision,
                                                     false, buf.get_mut(), parts.get_mut());
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 75ec0d7..0c5256b 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1381,7 +1381,7 @@
         for part in formatted.parts {
             match *part {
                 flt2dec::Part::Zero(mut nzeroes) => {
-                    const ZEROES: &'static str = // 64 zeroes
+                    const ZEROES: &str = // 64 zeroes
                         "0000000000000000000000000000000000000000000000000000000000000000";
                     while nzeroes > ZEROES.len() {
                         self.buf.write_str(ZEROES)?;
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index fd4189e..3063cb1 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -519,7 +519,7 @@
     /// element.
     ///
     /// `map()` transforms one iterator into another, by means of its argument:
-    /// something that implements `FnMut`. It produces a new iterator which
+    /// something that implements [`FnMut`]. It produces a new iterator which
     /// calls this closure on each element of the original iterator.
     ///
     /// If you are good at thinking in types, you can think of `map()` like this:
@@ -533,6 +533,7 @@
     /// more idiomatic to use [`for`] than `map()`.
     ///
     /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
+    /// [`FnMut`]: ../../std/ops/trait.FnMut.html
     ///
     /// # Examples
     ///
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 62e1f9f..de7ab88 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -602,7 +602,9 @@
     }
 
     #[inline]
-    fn may_have_side_effect() -> bool { false }
+    fn may_have_side_effect() -> bool {
+        I::may_have_side_effect()
+    }
 }
 
 #[unstable(feature = "trusted_len", issue = "37572")]
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index a02b5bc..726e891 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -93,7 +93,6 @@
 #![feature(never_type)]
 #![feature(nll)]
 #![feature(exhaustive_patterns)]
-#![feature(macro_at_most_once_rep)]
 #![feature(no_core)]
 #![feature(on_unimplemented)]
 #![feature(optin_builtin_traits)]
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index c008b78..5ba0e94 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -238,6 +238,10 @@
 /// with converting downstream errors.
 ///
 /// The `?` operator was added to replace `try!` and should be used instead.
+/// Furthermore, `try` is a reserved word in Rust 2018, so if you must use
+/// it, you will need to use the [raw-identifier syntax][ris]: `r#try`.
+///
+/// [ris]: https://doc.rust-lang.org/nightly/rust-by-example/compatibility/raw_identifiers.html
 ///
 /// `try!` matches the given [`Result`]. In case of the `Ok` variant, the
 /// expression has the value of the wrapped value.
@@ -278,14 +282,14 @@
 ///
 /// // The previous method of quick returning Errors
 /// fn write_to_file_using_try() -> Result<(), MyError> {
-///     let mut file = try!(File::create("my_best_friends.txt"));
-///     try!(file.write_all(b"This is a list of my best friends."));
+///     let mut file = r#try!(File::create("my_best_friends.txt"));
+///     r#try!(file.write_all(b"This is a list of my best friends."));
 ///     Ok(())
 /// }
 ///
 /// // This is equivalent to:
 /// fn write_to_file_using_match() -> Result<(), MyError> {
-///     let mut file = try!(File::create("my_best_friends.txt"));
+///     let mut file = r#try!(File::create("my_best_friends.txt"));
 ///     match file.write_all(b"This is a list of my best friends.") {
 ///         Ok(v) => v,
 ///         Err(e) => return Err(From::from(e)),
@@ -296,14 +300,14 @@
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(alias = "?")]
-macro_rules! try {
+macro_rules! r#try {
     ($expr:expr) => (match $expr {
         $crate::result::Result::Ok(val) => val,
         $crate::result::Result::Err(err) => {
             return $crate::result::Result::Err($crate::convert::From::from(err))
         }
     });
-    ($expr:expr,) => (try!($expr));
+    ($expr:expr,) => (r#try!($expr));
 }
 
 /// Write formatted data into a buffer.
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 3bcdfab..23f0777 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -596,7 +596,7 @@
 /// This affects, for example, whether a `static` of that type is
 /// placed in read-only static memory or writable static memory.
 #[lang = "freeze"]
-unsafe auto trait Freeze {}
+pub(crate) unsafe auto trait Freeze {}
 
 impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
 unsafe impl<T: ?Sized> Freeze for PhantomData<T> {}
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index a5603ff..e4b2800 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -1118,6 +1118,9 @@
     ///
     /// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
     /// state, otherwise this will immediately cause undefined behavior.
+    // FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references
+    // to uninitialized data (e.g. in `libcore/fmt/float.rs`).  We should make
+    // a final decision about the rules before stabilization.
     #[unstable(feature = "maybe_uninit", issue = "53491")]
     #[inline(always)]
     pub unsafe fn get_mut(&mut self) -> &mut T {
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index 436cd1f..a89c6ca 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -11,14 +11,23 @@
 //! Exposes the NonZero lang item which provides optimization hints.
 
 use ops::{CoerceUnsized, DispatchFromDyn};
+use marker::Freeze;
 
 /// A wrapper type for raw pointers and integers that will never be
 /// NULL or 0 that might allow certain optimizations.
 #[rustc_layout_scalar_valid_range_start(1)]
-#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
 #[repr(transparent)]
-pub(crate) struct NonZero<T>(pub(crate) T);
+pub(crate) struct NonZero<T: Freeze>(pub(crate) T);
 
-impl<T: CoerceUnsized<U>, U> CoerceUnsized<NonZero<U>> for NonZero<T> {}
+// Do not call `T::clone` as theoretically it could turn the field into `0`
+// invalidating `NonZero`'s invariant.
+impl<T: Copy + Freeze> Clone for NonZero<T> {
+    fn clone(&self) -> Self {
+        unsafe { NonZero(self.0) }
+    }
+}
 
-impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<NonZero<U>> for NonZero<T> {}
+impl<T: CoerceUnsized<U> + Freeze, U: Freeze> CoerceUnsized<NonZero<U>> for NonZero<T> {}
+
+impl<T: DispatchFromDyn<U> + Freeze, U: Freeze> DispatchFromDyn<NonZero<U>> for NonZero<T> {}
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 57b5903..7f5d596 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -70,7 +70,7 @@
                 #[stable(feature = "nonzero", since = "1.28.0")]
                 #[inline]
                 pub const unsafe fn new_unchecked(n: $Int) -> Self {
-                    $Ty(NonZero(n))
+                    $Ty(unsafe { NonZero(n) })
                 }
 
                 /// Create a non-zero if the given value is not zero.
@@ -78,7 +78,7 @@
                 #[inline]
                 pub fn new(n: $Int) -> Option<Self> {
                     if n != 0 {
-                        Some($Ty(NonZero(n)))
+                        Some($Ty(unsafe { NonZero(n) }))
                     } else {
                         None
                     }
@@ -1989,6 +1989,19 @@
 ```
 let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -2008,6 +2021,19 @@
 ```
 let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -2037,6 +2063,19 @@
         ", $le_bytes, "
     });
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -3614,6 +3653,7 @@
 assert_eq!(", stringify!($SelfT), "::max_value().checked_next_power_of_two(), None);",
 $EndFeature, "
 ```"),
+            #[inline]
             #[stable(feature = "rust1", since = "1.0.0")]
             pub fn checked_next_power_of_two(self) -> Option<Self> {
                 self.one_less_than_next_power_of_two().checked_add(1)
@@ -3719,6 +3759,19 @@
 ```
 let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -3738,6 +3791,19 @@
 ```
 let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -3767,6 +3833,19 @@
         ", $le_bytes, "
     });
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 58407de..aa18a60 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -39,9 +39,16 @@
 use fmt;
 use panic::{Location, PanicInfo};
 
-#[cold] #[inline(never)] // this is the slow path, always
+#[cold]
+// never inline unless panic_immediate_abort to avoid code
+// bloat at the call sites as much as possible
+#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
 #[lang = "panic"]
 pub fn panic(expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { super::intrinsics::abort() }
+    }
+
     // Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially
     // reduce size overhead. The format_args! macro uses str's Display trait to
     // write expr, which calls Formatter::pad, which must accommodate string
@@ -52,16 +59,27 @@
     panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), &(file, line, col))
 }
 
-#[cold] #[inline(never)]
+#[cold]
+#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
 #[lang = "panic_bounds_check"]
 fn panic_bounds_check(file_line_col: &(&'static str, u32, u32),
                      index: usize, len: usize) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { super::intrinsics::abort() }
+    }
+
     panic_fmt(format_args!("index out of bounds: the len is {} but the index is {}",
                            len, index), file_line_col)
 }
 
-#[cold] #[inline(never)]
+#[cold]
+#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
+#[cfg_attr(    feature="panic_immediate_abort" ,inline)]
 pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { super::intrinsics::abort() }
+    }
+
     // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
     #[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe
     extern "Rust" {
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 947b67e..0387708 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -189,12 +189,22 @@
 /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place`
 /// manually.
 #[stable(feature = "drop_in_place", since = "1.8.0")]
+#[inline(always)]
+pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+    real_drop_in_place(&mut *to_drop)
+}
+
+// The real `drop_in_place` -- the one that gets called implicitly when variables go
+// out of scope -- should have a safe reference and not a raw pointer as argument
+// type.  When we drop a local variable, we access it with a pointer that behaves
+// like a safe reference; transmuting that to a raw pointer does not mean we can
+// actually access it with raw pointers.
 #[lang = "drop_in_place"]
 #[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+unsafe fn real_drop_in_place<T: ?Sized>(to_drop: &mut T) {
     // Code here does not matter - this is replaced by the
     // real drop glue by the compiler.
-    drop_in_place(to_drop);
+    real_drop_in_place(to_drop)
 }
 
 /// Creates a null raw pointer.
@@ -2749,7 +2759,7 @@
     /// Creates a new `Unique` if `ptr` is non-null.
     pub fn new(ptr: *mut T) -> Option<Self> {
         if !ptr.is_null() {
-            Some(Unique { pointer: NonZero(ptr as _), _marker: PhantomData })
+            Some(Unique { pointer: unsafe { NonZero(ptr as _) }, _marker: PhantomData })
         } else {
             None
         }
@@ -2805,14 +2815,14 @@
 #[unstable(feature = "ptr_internals", issue = "0")]
 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 }
+        Unique { pointer: unsafe { NonZero(reference as _) }, _marker: PhantomData }
     }
 }
 
 #[unstable(feature = "ptr_internals", issue = "0")]
 impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
     fn from(reference: &'a T) -> Self {
-        Unique { pointer: NonZero(reference as _), _marker: PhantomData }
+        Unique { pointer: unsafe { NonZero(reference as _) }, _marker: PhantomData }
     }
 }
 
@@ -2885,7 +2895,7 @@
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
-        NonNull { pointer: NonZero(ptr as _) }
+        NonNull { pointer: unsafe { NonZero(ptr as _) } }
     }
 
     /// Creates a new `NonNull` if `ptr` is non-null.
@@ -2893,7 +2903,7 @@
     #[inline]
     pub fn new(ptr: *mut T) -> Option<Self> {
         if !ptr.is_null() {
-            Some(NonNull { pointer: NonZero(ptr as _) })
+            Some(unsafe { Self::new_unchecked(ptr) })
         } else {
             None
         }
@@ -3015,7 +3025,7 @@
 impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
     #[inline]
     fn from(reference: &'a mut T) -> Self {
-        NonNull { pointer: NonZero(reference as _) }
+        NonNull { pointer: unsafe { NonZero(reference as _) } }
     }
 }
 
@@ -3023,6 +3033,6 @@
 impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
     #[inline]
     fn from(reference: &'a T) -> Self {
-        NonNull { pointer: NonZero(reference as _) }
+        NonNull { pointer: unsafe { NonZero(reference as _) } }
     }
 }
diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs
index 186d6ad..52abd8f 100644
--- a/src/libcore/str/lossy.rs
+++ b/src/libcore/str/lossy.rs
@@ -62,18 +62,15 @@
         }
 
         const TAG_CONT_U8: u8 = 128;
-        fn unsafe_get(xs: &[u8], i: usize) -> u8 {
-            unsafe { *xs.get_unchecked(i) }
-        }
         fn safe_get(xs: &[u8], i: usize) -> u8 {
-            if i >= xs.len() { 0 } else { unsafe_get(xs, i) }
+            *xs.get(i).unwrap_or(&0)
         }
 
         let mut i = 0;
         while i < self.source.len() {
             let i_ = i;
 
-            let byte = unsafe_get(self.source, i);
+            let byte = unsafe { *self.source.get_unchecked(i) };
             i += 1;
 
             if byte < 128 {
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 89efa12..6c953d1 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -536,10 +536,9 @@
     where I: DoubleEndedIterator<Item = &'a u8>,
 {
     // Decode UTF-8
-    let w = match bytes.next_back() {
-        None => return None,
-        Some(&next_byte) if next_byte < 128 => return Some(next_byte as u32),
-        Some(&back_byte) => back_byte,
+    let w = match *bytes.next_back()? {
+        next_byte if next_byte < 128 => return Some(next_byte as u32),
+        back_byte => back_byte,
     };
 
     // Multibyte case follows
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 56d3b42..27eeb04 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -173,11 +173,11 @@
 
 /// Atomic memory orderings
 ///
-/// Memory orderings limit the ways that both the compiler and CPU may reorder
-/// instructions around atomic operations. At its most restrictive,
-/// "sequentially consistent" atomics allow neither reads nor writes
-/// to be moved either before or after the atomic operation; on the other end
-/// "relaxed" atomics allow all reorderings.
+/// Memory orderings specify the way atomic operations synchronize memory.
+/// In its weakest [`Relaxed`][Ordering::Relaxed], only the memory directly touched by the
+/// operation is synchronized. On the other hand, a store-load pair of [`SeqCst`][Ordering::SeqCst]
+/// operations synchronize other memory while additionally preserving a total order of such
+/// operations across all threads.
 ///
 /// Rust's memory orderings are [the same as
 /// LLVM's](https://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations).
@@ -185,6 +185,8 @@
 /// For more information see the [nomicon].
 ///
 /// [nomicon]: ../../../nomicon/atomics.html
+/// [Ordering::Relaxed]: #variant.Relaxed
+/// [Ordering::SeqCst]: #variant.SeqCst
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Copy, Clone, Debug)]
 #[non_exhaustive]
@@ -234,8 +236,8 @@
     /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering.
     ///
     /// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up
-    /// not performing any store and hence it has just `Acquire` ordering. However,
-    /// `AcqRel` will never perform [`Relaxed`] accesses.
+    /// not performing any store and hence it has just [`Acquire`] ordering. However,
+    /// [`AcqRel`][`AcquireRelease`] will never perform [`Relaxed`] accesses.
     ///
     /// This ordering is only applicable for operations that combine both loads and stores.
     ///
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 495483d..19be1a0 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1250,6 +1250,23 @@
 }
 
 #[test]
+fn test_cloned_side_effects() {
+    let mut count = 0;
+    {
+        let iter = [1, 2, 3]
+            .iter()
+            .map(|x| {
+                count += 1;
+                x
+            })
+            .cloned()
+            .zip(&[1]);
+        for _ in iter {}
+    }
+    assert_eq!(count, 2);
+}
+
+#[test]
 fn test_double_ended_map() {
     let xs = [1, 2, 3, 4, 5, 6];
     let mut it = xs.iter().map(|&x| x * -1);
diff --git a/src/libcore/unicode/printable.rs b/src/libcore/unicode/printable.rs
index 519dd17..32e4b6b 100644
--- a/src/libcore/unicode/printable.rs
+++ b/src/libcore/unicode/printable.rs
@@ -80,7 +80,7 @@
     }
 }
 
-const SINGLETONS0U: &'static [(u8, u8)] = &[
+const SINGLETONS0U: &[(u8, u8)] = &[
     (0x00, 1),
     (0x03, 5),
     (0x05, 6),
@@ -122,7 +122,7 @@
     (0xfe, 3),
     (0xff, 9),
 ];
-const SINGLETONS0L: &'static [u8] = &[
+const SINGLETONS0L: &[u8] = &[
     0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57,
     0x58, 0x8b, 0x8c, 0x90, 0x1c, 0x1d, 0xdd, 0x0e,
     0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f,
@@ -162,7 +162,7 @@
     0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9,
     0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
 ];
-const SINGLETONS1U: &'static [(u8, u8)] = &[
+const SINGLETONS1U: &[(u8, u8)] = &[
     (0x00, 6),
     (0x01, 1),
     (0x03, 1),
@@ -197,7 +197,7 @@
     (0xf0, 4),
     (0xf9, 4),
 ];
-const SINGLETONS1L: &'static [u8] = &[
+const SINGLETONS1L: &[u8] = &[
     0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e,
     0x9e, 0x9f, 0x06, 0x07, 0x09, 0x36, 0x3d, 0x3e,
     0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36,
@@ -219,7 +219,7 @@
     0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0,
     0xc0, 0xd0, 0x3f, 0x71, 0x72, 0x7b,
 ];
-const NORMAL0: &'static [u8] = &[
+const NORMAL0: &[u8] = &[
     0x00, 0x20,
     0x5f, 0x22,
     0x82, 0xdf, 0x04,
@@ -363,7 +363,7 @@
     0x1b, 0x03,
     0x0f, 0x0d,
 ];
-const NORMAL1: &'static [u8] = &[
+const NORMAL1: &[u8] = &[
     0x5e, 0x22,
     0x7b, 0x05,
     0x03, 0x04,
diff --git a/src/libproc_macro/Cargo.toml b/src/libproc_macro/Cargo.toml
index c1b2622..f903f79 100644
--- a/src/libproc_macro/Cargo.toml
+++ b/src/libproc_macro/Cargo.toml
@@ -5,10 +5,3 @@
 
 [lib]
 path = "lib.rs"
-crate-type = ["dylib"]
-
-[dependencies]
-syntax = { path = "../libsyntax" }
-syntax_pos = { path = "../libsyntax_pos" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/libproc_macro/bridge/buffer.rs b/src/libproc_macro/bridge/buffer.rs
new file mode 100644
index 0000000..f228841
--- /dev/null
+++ b/src/libproc_macro/bridge/buffer.rs
@@ -0,0 +1,170 @@
+// 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.
+
+//! Buffer management for same-process client<->server communication.
+
+use std::io::{self, Write};
+use std::mem;
+use std::ops::{Deref, DerefMut};
+use std::slice;
+
+#[repr(C)]
+struct Slice<'a, T: 'a> {
+    data: &'a [T; 0],
+    len: usize,
+}
+
+unsafe impl<'a, T: Sync> Sync for Slice<'a, T> {}
+unsafe impl<'a, T: Sync> Send for Slice<'a, T> {}
+
+impl<T> Copy for Slice<'a, T> {}
+impl<T> Clone for Slice<'a, T> {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+impl<T> From<&'a [T]> for Slice<'a, T> {
+    fn from(xs: &'a [T]) -> Self {
+        Slice {
+            data: unsafe { &*(xs.as_ptr() as *const [T; 0]) },
+            len: xs.len(),
+        }
+    }
+}
+
+impl<T> Deref for Slice<'a, T> {
+    type Target = [T];
+    fn deref(&self) -> &[T] {
+        unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) }
+    }
+}
+
+#[repr(C)]
+pub struct Buffer<T: Copy> {
+    data: *mut T,
+    len: usize,
+    capacity: usize,
+    extend_from_slice: extern "C" fn(Buffer<T>, Slice<T>) -> Buffer<T>,
+    drop: extern "C" fn(Buffer<T>),
+}
+
+unsafe impl<T: Copy + Sync> Sync for Buffer<T> {}
+unsafe impl<T: Copy + Send> Send for Buffer<T> {}
+
+impl<T: Copy> Default for Buffer<T> {
+    fn default() -> Self {
+        Self::from(vec![])
+    }
+}
+
+impl<T: Copy> Deref for Buffer<T> {
+    type Target = [T];
+    fn deref(&self) -> &[T] {
+        unsafe { slice::from_raw_parts(self.data as *const T, self.len) }
+    }
+}
+
+impl<T: Copy> DerefMut for Buffer<T> {
+    fn deref_mut(&mut self) -> &mut [T] {
+        unsafe { slice::from_raw_parts_mut(self.data, self.len) }
+    }
+}
+
+impl<T: Copy> Buffer<T> {
+    pub(super) fn new() -> Self {
+        Self::default()
+    }
+
+    pub(super) fn clear(&mut self) {
+        self.len = 0;
+    }
+
+    pub(super) fn take(&mut self) -> Self {
+        mem::replace(self, Self::default())
+    }
+
+    pub(super) fn extend_from_slice(&mut self, xs: &[T]) {
+        // Fast path to avoid going through an FFI call.
+        if let Some(final_len) = self.len.checked_add(xs.len()) {
+            if final_len <= self.capacity {
+                let dst = unsafe { slice::from_raw_parts_mut(self.data, self.capacity) };
+                dst[self.len..][..xs.len()].copy_from_slice(xs);
+                self.len = final_len;
+                return;
+            }
+        }
+        let b = self.take();
+        *self = (b.extend_from_slice)(b, Slice::from(xs));
+    }
+}
+
+impl Write for Buffer<u8> {
+    fn write(&mut self, xs: &[u8]) -> io::Result<usize> {
+        self.extend_from_slice(xs);
+        Ok(xs.len())
+    }
+
+    fn write_all(&mut self, xs: &[u8]) -> io::Result<()> {
+        self.extend_from_slice(xs);
+        Ok(())
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+impl<T: Copy> Drop for Buffer<T> {
+    fn drop(&mut self) {
+        let b = self.take();
+        (b.drop)(b);
+    }
+}
+
+impl<T: Copy> From<Vec<T>> for Buffer<T> {
+    fn from(mut v: Vec<T>) -> Self {
+        let (data, len, capacity) = (v.as_mut_ptr(), v.len(), v.capacity());
+        mem::forget(v);
+
+        // This utility function is nested in here because it can *only*
+        // be safely called on `Buffer`s created by *this* `proc_macro`.
+        fn to_vec<T: Copy>(b: Buffer<T>) -> Vec<T> {
+            unsafe {
+                let Buffer {
+                    data,
+                    len,
+                    capacity,
+                    ..
+                } = b;
+                mem::forget(b);
+                Vec::from_raw_parts(data, len, capacity)
+            }
+        }
+
+        extern "C" fn extend_from_slice<T: Copy>(b: Buffer<T>, xs: Slice<T>) -> Buffer<T> {
+            let mut v = to_vec(b);
+            v.extend_from_slice(&xs);
+            Buffer::from(v)
+        }
+
+        extern "C" fn drop<T: Copy>(b: Buffer<T>) {
+            mem::drop(to_vec(b));
+        }
+
+        Buffer {
+            data,
+            len,
+            capacity,
+            extend_from_slice,
+            drop,
+        }
+    }
+}
diff --git a/src/libproc_macro/bridge/client.rs b/src/libproc_macro/bridge/client.rs
new file mode 100644
index 0000000..ed27df4
--- /dev/null
+++ b/src/libproc_macro/bridge/client.rs
@@ -0,0 +1,504 @@
+// 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.
+
+//! Client-side types.
+
+use super::*;
+
+macro_rules! define_handles {
+    (
+        'owned: $($oty:ident,)*
+        'interned: $($ity:ident,)*
+    ) => {
+        #[repr(C)]
+        #[allow(non_snake_case)]
+        pub struct HandleCounters {
+            $($oty: AtomicUsize,)*
+            $($ity: AtomicUsize,)*
+        }
+
+        impl HandleCounters {
+            // FIXME(#53451) public to work around `Cannot create local mono-item` ICE.
+            pub extern "C" fn get() -> &'static Self {
+                static COUNTERS: HandleCounters = HandleCounters {
+                    $($oty: AtomicUsize::new(1),)*
+                    $($ity: AtomicUsize::new(1),)*
+                };
+                &COUNTERS
+            }
+        }
+
+        // FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
+        #[repr(C)]
+        #[allow(non_snake_case)]
+        pub(super) struct HandleStore<S: server::Types> {
+            $($oty: handle::OwnedStore<S::$oty>,)*
+            $($ity: handle::InternedStore<S::$ity>,)*
+        }
+
+        impl<S: server::Types> HandleStore<S> {
+            pub(super) fn new(handle_counters: &'static HandleCounters) -> Self {
+                HandleStore {
+                    $($oty: handle::OwnedStore::new(&handle_counters.$oty),)*
+                    $($ity: handle::InternedStore::new(&handle_counters.$ity),)*
+                }
+            }
+        }
+
+        $(
+            #[repr(C)]
+            pub(crate) struct $oty(handle::Handle);
+            impl !Send for $oty {}
+            impl !Sync for $oty {}
+
+            // Forward `Drop::drop` to the inherent `drop` method.
+            impl Drop for $oty {
+                fn drop(&mut self) {
+                    $oty(self.0).drop();
+                }
+            }
+
+            impl<S> Encode<S> for $oty {
+                fn encode(self, w: &mut Writer, s: &mut S) {
+                    let handle = self.0;
+                    mem::forget(self);
+                    handle.encode(w, s);
+                }
+            }
+
+            impl<S: server::Types> DecodeMut<'_, '_, HandleStore<server::MarkedTypes<S>>>
+                for Marked<S::$oty, $oty>
+            {
+                fn decode(r: &mut Reader, s: &mut HandleStore<server::MarkedTypes<S>>) -> Self {
+                    s.$oty.take(handle::Handle::decode(r, &mut ()))
+                }
+            }
+
+            impl<S> Encode<S> for &$oty {
+                fn encode(self, w: &mut Writer, s: &mut S) {
+                    self.0.encode(w, s);
+                }
+            }
+
+            impl<S: server::Types> Decode<'_, 's, HandleStore<server::MarkedTypes<S>>>
+                for &'s Marked<S::$oty, $oty>
+            {
+                fn decode(r: &mut Reader, s: &'s HandleStore<server::MarkedTypes<S>>) -> Self {
+                    &s.$oty[handle::Handle::decode(r, &mut ())]
+                }
+            }
+
+            impl<S> Encode<S> for &mut $oty {
+                fn encode(self, w: &mut Writer, s: &mut S) {
+                    self.0.encode(w, s);
+                }
+            }
+
+            impl<S: server::Types> DecodeMut<'_, 's, HandleStore<server::MarkedTypes<S>>>
+                for &'s mut Marked<S::$oty, $oty>
+            {
+                fn decode(r: &mut Reader, s: &'s mut HandleStore<server::MarkedTypes<S>>) -> Self {
+                    &mut s.$oty[handle::Handle::decode(r, &mut ())]
+                }
+            }
+
+            impl<S: server::Types> Encode<HandleStore<server::MarkedTypes<S>>>
+                for Marked<S::$oty, $oty>
+            {
+                fn encode(self, w: &mut Writer, s: &mut HandleStore<server::MarkedTypes<S>>) {
+                    s.$oty.alloc(self).encode(w, s);
+                }
+            }
+
+            impl<S> DecodeMut<'_, '_, S> for $oty {
+                fn decode(r: &mut Reader, s: &mut S) -> Self {
+                    $oty(handle::Handle::decode(r, s))
+                }
+            }
+        )*
+
+        $(
+            #[repr(C)]
+            #[derive(Copy, Clone, PartialEq, Eq, Hash)]
+            pub(crate) struct $ity(handle::Handle);
+            impl !Send for $ity {}
+            impl !Sync for $ity {}
+
+            impl<S> Encode<S> for $ity {
+                fn encode(self, w: &mut Writer, s: &mut S) {
+                    self.0.encode(w, s);
+                }
+            }
+
+            impl<S: server::Types> DecodeMut<'_, '_, HandleStore<server::MarkedTypes<S>>>
+                for Marked<S::$ity, $ity>
+            {
+                fn decode(r: &mut Reader, s: &mut HandleStore<server::MarkedTypes<S>>) -> Self {
+                    s.$ity.copy(handle::Handle::decode(r, &mut ()))
+                }
+            }
+
+            impl<S: server::Types> Encode<HandleStore<server::MarkedTypes<S>>>
+                for Marked<S::$ity, $ity>
+            {
+                fn encode(self, w: &mut Writer, s: &mut HandleStore<server::MarkedTypes<S>>) {
+                    s.$ity.alloc(self).encode(w, s);
+                }
+            }
+
+            impl<S> DecodeMut<'_, '_, S> for $ity {
+                fn decode(r: &mut Reader, s: &mut S) -> Self {
+                    $ity(handle::Handle::decode(r, s))
+                }
+            }
+        )*
+    }
+}
+define_handles! {
+    'owned:
+    TokenStream,
+    TokenStreamBuilder,
+    TokenStreamIter,
+    Group,
+    Literal,
+    SourceFile,
+    MultiSpan,
+    Diagnostic,
+
+    'interned:
+    Punct,
+    Ident,
+    Span,
+}
+
+// FIXME(eddyb) generate these impls by pattern-matching on the
+// names of methods - also could use the presence of `fn drop`
+// to distinguish between 'owned and 'interned, above.
+// Alternatively, special 'modes" could be listed of types in with_api
+// instead of pattern matching on methods, here and in server decl.
+
+impl Clone for TokenStream {
+    fn clone(&self) -> Self {
+        self.clone()
+    }
+}
+
+impl Clone for TokenStreamIter {
+    fn clone(&self) -> Self {
+        self.clone()
+    }
+}
+
+impl Clone for Group {
+    fn clone(&self) -> Self {
+        self.clone()
+    }
+}
+
+impl Clone for Literal {
+    fn clone(&self) -> Self {
+        self.clone()
+    }
+}
+
+// FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
+impl fmt::Debug for Literal {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.write_str(&self.debug())
+    }
+}
+
+impl Clone for SourceFile {
+    fn clone(&self) -> Self {
+        self.clone()
+    }
+}
+
+impl fmt::Debug for Span {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.write_str(&self.debug())
+    }
+}
+
+macro_rules! define_client_side {
+    ($($name:ident {
+        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)*) $(-> $ret_ty:ty)*;)*
+    }),* $(,)*) => {
+        $(impl $name {
+            $(pub(crate) fn $method($($arg: $arg_ty),*) $(-> $ret_ty)* {
+                Bridge::with(|bridge| {
+                    let mut b = bridge.cached_buffer.take();
+
+                    b.clear();
+                    api_tags::Method::$name(api_tags::$name::$method).encode(&mut b, &mut ());
+                    reverse_encode!(b; $($arg),*);
+
+                    b = bridge.dispatch.call(b);
+
+                    let r = Result::<_, PanicMessage>::decode(&mut &b[..], &mut ());
+
+                    bridge.cached_buffer = b;
+
+                    r.unwrap_or_else(|e| panic::resume_unwind(e.into()))
+                })
+            })*
+        })*
+    }
+}
+with_api!(self, self, define_client_side);
+
+enum BridgeState<'a> {
+    /// No server is currently connected to this client.
+    NotConnected,
+
+    /// A server is connected and available for requests.
+    Connected(Bridge<'a>),
+
+    /// Access to the bridge is being exclusively acquired
+    /// (e.g. during `BridgeState::with`).
+    InUse,
+}
+
+enum BridgeStateL {}
+
+impl<'a> scoped_cell::ApplyL<'a> for BridgeStateL {
+    type Out = BridgeState<'a>;
+}
+
+thread_local! {
+    static BRIDGE_STATE: scoped_cell::ScopedCell<BridgeStateL> =
+        scoped_cell::ScopedCell::new(BridgeState::NotConnected);
+}
+
+impl BridgeState<'_> {
+    /// Take exclusive control of the thread-local
+    /// `BridgeState`, and pass it to `f`, mutably.
+    /// The state will be restored after `f` exits, even
+    /// by panic, including modifications made to it by `f`.
+    ///
+    /// NB: while `f` is running, the thread-local state
+    /// is `BridgeState::InUse`.
+    fn with<R>(f: impl FnOnce(&mut BridgeState) -> R) -> R {
+        BRIDGE_STATE.with(|state| {
+            state.replace(BridgeState::InUse, |mut state| {
+                // FIXME(#52812) pass `f` directly to `replace` when `RefMutL` is gone
+                f(&mut *state)
+            })
+        })
+    }
+}
+
+impl Bridge<'_> {
+    fn enter<R>(self, f: impl FnOnce() -> R) -> R {
+        // Hide the default panic output within `proc_macro` expansions.
+        // NB. the server can't do this because it may use a different libstd.
+        static HIDE_PANICS_DURING_EXPANSION: Once = Once::new();
+        HIDE_PANICS_DURING_EXPANSION.call_once(|| {
+            let prev = panic::take_hook();
+            panic::set_hook(Box::new(move |info| {
+                let hide = BridgeState::with(|state| match state {
+                    BridgeState::NotConnected => false,
+                    BridgeState::Connected(_) | BridgeState::InUse => true,
+                });
+                if !hide {
+                    prev(info)
+                }
+            }));
+        });
+
+        BRIDGE_STATE.with(|state| state.set(BridgeState::Connected(self), f))
+    }
+
+    fn with<R>(f: impl FnOnce(&mut Bridge) -> R) -> R {
+        BridgeState::with(|state| match state {
+            BridgeState::NotConnected => {
+                panic!("procedural macro API is used outside of a procedural macro");
+            }
+            BridgeState::InUse => {
+                panic!("procedural macro API is used while it's already in use");
+            }
+            BridgeState::Connected(bridge) => f(bridge),
+        })
+    }
+}
+
+/// A client-side "global object" (usually a function pointer),
+/// which may be using a different `proc_macro` from the one
+/// used by the server, but can be interacted with compatibly.
+///
+/// NB: `F` must have FFI-friendly memory layout (e.g. a pointer).
+/// The call ABI of function pointers used for `F` doesn't
+/// need to match between server and client, since it's only
+/// passed between them and (eventually) called by the client.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct Client<F> {
+    pub(super) get_handle_counters: extern "C" fn() -> &'static HandleCounters,
+    pub(super) run: extern "C" fn(Bridge, F) -> Buffer<u8>,
+    pub(super) f: F,
+}
+
+// FIXME(#53451) public to work around `Cannot create local mono-item` ICE,
+// affecting not only the function itself, but also the `BridgeState` `thread_local!`.
+pub extern "C" fn __run_expand1(
+    mut bridge: Bridge,
+    f: fn(::TokenStream) -> ::TokenStream,
+) -> Buffer<u8> {
+    // The initial `cached_buffer` contains the input.
+    let mut b = bridge.cached_buffer.take();
+
+    panic::catch_unwind(panic::AssertUnwindSafe(|| {
+        bridge.enter(|| {
+            let reader = &mut &b[..];
+            let input = TokenStream::decode(reader, &mut ());
+
+            // Put the `cached_buffer` back in the `Bridge`, for requests.
+            Bridge::with(|bridge| bridge.cached_buffer = b.take());
+
+            let output = f(::TokenStream(input)).0;
+
+            // Take the `cached_buffer` back out, for the output value.
+            b = Bridge::with(|bridge| bridge.cached_buffer.take());
+
+            // HACK(eddyb) Separate encoding a success value (`Ok(output)`)
+            // from encoding a panic (`Err(e: PanicMessage)`) to avoid
+            // having handles outside the `bridge.enter(|| ...)` scope, and
+            // to catch panics that could happen while encoding the success.
+            //
+            // Note that panics should be impossible beyond this point, but
+            // this is defensively trying to avoid any accidental panicking
+            // reaching the `extern "C"` (which should `abort` but may not
+            // at the moment, so this is also potentially preventing UB).
+            b.clear();
+            Ok::<_, ()>(output).encode(&mut b, &mut ());
+        })
+    }))
+    .map_err(PanicMessage::from)
+    .unwrap_or_else(|e| {
+        b.clear();
+        Err::<(), _>(e).encode(&mut b, &mut ());
+    });
+    b
+}
+
+impl Client<fn(::TokenStream) -> ::TokenStream> {
+    pub const fn expand1(f: fn(::TokenStream) -> ::TokenStream) -> Self {
+        Client {
+            get_handle_counters: HandleCounters::get,
+            run: __run_expand1,
+            f,
+        }
+    }
+}
+
+// FIXME(#53451) public to work around `Cannot create local mono-item` ICE,
+// affecting not only the function itself, but also the `BridgeState` `thread_local!`.
+pub extern "C" fn __run_expand2(
+    mut bridge: Bridge,
+    f: fn(::TokenStream, ::TokenStream) -> ::TokenStream,
+) -> Buffer<u8> {
+    // The initial `cached_buffer` contains the input.
+    let mut b = bridge.cached_buffer.take();
+
+    panic::catch_unwind(panic::AssertUnwindSafe(|| {
+        bridge.enter(|| {
+            let reader = &mut &b[..];
+            let input = TokenStream::decode(reader, &mut ());
+            let input2 = TokenStream::decode(reader, &mut ());
+
+            // Put the `cached_buffer` back in the `Bridge`, for requests.
+            Bridge::with(|bridge| bridge.cached_buffer = b.take());
+
+            let output = f(::TokenStream(input), ::TokenStream(input2)).0;
+
+            // Take the `cached_buffer` back out, for the output value.
+            b = Bridge::with(|bridge| bridge.cached_buffer.take());
+
+            // HACK(eddyb) Separate encoding a success value (`Ok(output)`)
+            // from encoding a panic (`Err(e: PanicMessage)`) to avoid
+            // having handles outside the `bridge.enter(|| ...)` scope, and
+            // to catch panics that could happen while encoding the success.
+            //
+            // Note that panics should be impossible beyond this point, but
+            // this is defensively trying to avoid any accidental panicking
+            // reaching the `extern "C"` (which should `abort` but may not
+            // at the moment, so this is also potentially preventing UB).
+            b.clear();
+            Ok::<_, ()>(output).encode(&mut b, &mut ());
+        })
+    }))
+    .map_err(PanicMessage::from)
+    .unwrap_or_else(|e| {
+        b.clear();
+        Err::<(), _>(e).encode(&mut b, &mut ());
+    });
+    b
+}
+
+impl Client<fn(::TokenStream, ::TokenStream) -> ::TokenStream> {
+    pub const fn expand2(f: fn(::TokenStream, ::TokenStream) -> ::TokenStream) -> Self {
+        Client {
+            get_handle_counters: HandleCounters::get,
+            run: __run_expand2,
+            f,
+        }
+    }
+}
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub enum ProcMacro {
+    CustomDerive {
+        trait_name: &'static str,
+        attributes: &'static [&'static str],
+        client: Client<fn(::TokenStream) -> ::TokenStream>,
+    },
+
+    Attr {
+        name: &'static str,
+        client: Client<fn(::TokenStream, ::TokenStream) -> ::TokenStream>,
+    },
+
+    Bang {
+        name: &'static str,
+        client: Client<fn(::TokenStream) -> ::TokenStream>,
+    },
+}
+
+impl ProcMacro {
+    pub const fn custom_derive(
+        trait_name: &'static str,
+        attributes: &'static [&'static str],
+        expand: fn(::TokenStream) -> ::TokenStream,
+    ) -> Self {
+        ProcMacro::CustomDerive {
+            trait_name,
+            attributes,
+            client: Client::expand1(expand),
+        }
+    }
+
+    pub const fn attr(
+        name: &'static str,
+        expand: fn(::TokenStream, ::TokenStream) -> ::TokenStream,
+    ) -> Self {
+        ProcMacro::Attr {
+            name,
+            client: Client::expand2(expand),
+        }
+    }
+
+    pub const fn bang(name: &'static str, expand: fn(::TokenStream) -> ::TokenStream) -> Self {
+        ProcMacro::Bang {
+            name,
+            client: Client::expand1(expand),
+        }
+    }
+}
diff --git a/src/libproc_macro/bridge/closure.rs b/src/libproc_macro/bridge/closure.rs
new file mode 100644
index 0000000..92fe7ba
--- /dev/null
+++ b/src/libproc_macro/bridge/closure.rs
@@ -0,0 +1,42 @@
+// 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.
+
+//! Closure type (equivalent to `&mut dyn FnMut(A) -> R`) that's `repr(C)`.
+
+#[repr(C)]
+pub struct Closure<'a, A, R> {
+    call: unsafe extern "C" fn(&mut Env, A) -> R,
+    env: &'a mut Env,
+}
+
+extern "C" {
+    type Env;
+}
+
+impl<'a, A, R> !Sync for Closure<'a, A, R> {}
+impl<'a, A, R> !Send for Closure<'a, A, R> {}
+
+impl<'a, A, R, F: FnMut(A) -> R> From<&'a mut F> for Closure<'a, A, R> {
+    fn from(f: &'a mut F) -> Self {
+        unsafe extern "C" fn call<A, R, F: FnMut(A) -> R>(env: &mut Env, arg: A) -> R {
+            (*(env as *mut _ as *mut F))(arg)
+        }
+        Closure {
+            call: call::<A, R, F>,
+            env: unsafe { &mut *(f as *mut _ as *mut Env) },
+        }
+    }
+}
+
+impl<'a, A, R> Closure<'a, A, R> {
+    pub fn call(&mut self, arg: A) -> R {
+        unsafe { (self.call)(self.env, arg) }
+    }
+}
diff --git a/src/libproc_macro/bridge/handle.rs b/src/libproc_macro/bridge/handle.rs
new file mode 100644
index 0000000..5c91a14
--- /dev/null
+++ b/src/libproc_macro/bridge/handle.rs
@@ -0,0 +1,92 @@
+// 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.
+
+//! Server-side handles and storage for per-handle data.
+
+use std::collections::{BTreeMap, HashMap};
+use std::hash::Hash;
+use std::num::NonZeroU32;
+use std::ops::{Index, IndexMut};
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+pub(super) type Handle = NonZeroU32;
+
+pub(super) struct OwnedStore<T: 'static> {
+    counter: &'static AtomicUsize,
+    data: BTreeMap<Handle, T>,
+}
+
+impl<T> OwnedStore<T> {
+    pub(super) fn new(counter: &'static AtomicUsize) -> Self {
+        // Ensure the handle counter isn't 0, which would panic later,
+        // when `NonZeroU32::new` (aka `Handle::new`) is called in `alloc`.
+        assert_ne!(counter.load(Ordering::SeqCst), 0);
+
+        OwnedStore {
+            counter,
+            data: BTreeMap::new(),
+        }
+    }
+}
+
+impl<T> OwnedStore<T> {
+    pub(super) fn alloc(&mut self, x: T) -> Handle {
+        let counter = self.counter.fetch_add(1, Ordering::SeqCst);
+        let handle = Handle::new(counter as u32).expect("`proc_macro` handle counter overflowed");
+        assert!(self.data.insert(handle, x).is_none());
+        handle
+    }
+
+    pub(super) fn take(&mut self, h: Handle) -> T {
+        self.data
+            .remove(&h)
+            .expect("use-after-free in `proc_macro` handle")
+    }
+}
+
+impl<T> Index<Handle> for OwnedStore<T> {
+    type Output = T;
+    fn index(&self, h: Handle) -> &T {
+        self.data
+            .get(&h)
+            .expect("use-after-free in `proc_macro` handle")
+    }
+}
+
+impl<T> IndexMut<Handle> for OwnedStore<T> {
+    fn index_mut(&mut self, h: Handle) -> &mut T {
+        self.data
+            .get_mut(&h)
+            .expect("use-after-free in `proc_macro` handle")
+    }
+}
+
+pub(super) struct InternedStore<T: 'static> {
+    owned: OwnedStore<T>,
+    interner: HashMap<T, Handle>,
+}
+
+impl<T: Copy + Eq + Hash> InternedStore<T> {
+    pub(super) fn new(counter: &'static AtomicUsize) -> Self {
+        InternedStore {
+            owned: OwnedStore::new(counter),
+            interner: HashMap::new(),
+        }
+    }
+
+    pub(super) fn alloc(&mut self, x: T) -> Handle {
+        let owned = &mut self.owned;
+        *self.interner.entry(x).or_insert_with(|| owned.alloc(x))
+    }
+
+    pub(super) fn copy(&mut self, h: Handle) -> T {
+        self.owned[h]
+    }
+}
diff --git a/src/libproc_macro/bridge/mod.rs b/src/libproc_macro/bridge/mod.rs
new file mode 100644
index 0000000..f03c63f
--- /dev/null
+++ b/src/libproc_macro/bridge/mod.rs
@@ -0,0 +1,413 @@
+// 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.
+
+//! Internal interface for communicating between a `proc_macro` client
+//! (a proc macro crate) and a `proc_macro` server (a compiler front-end).
+//!
+//! Serialization (with C ABI buffers) and unique integer handles are employed
+//! to allow safely interfacing between two copies of `proc_macro` built
+//! (from the same source) by different compilers with potentially mismatching
+//! Rust ABIs (e.g. stage0/bin/rustc vs stage1/bin/rustc during bootstrap).
+
+#![deny(unsafe_code)]
+
+use std::fmt;
+use std::hash::Hash;
+use std::marker;
+use std::mem;
+use std::ops::Bound;
+use std::panic;
+use std::sync::atomic::AtomicUsize;
+use std::sync::Once;
+use std::thread;
+use {Delimiter, Level, LineColumn, Spacing};
+
+/// Higher-order macro describing the server RPC API, allowing automatic
+/// generation of type-safe Rust APIs, both client-side and server-side.
+///
+/// `with_api!(MySelf, my_self, my_macro)` expands to:
+/// ```rust,ignore (pseudo-code)
+/// my_macro! {
+///     // ...
+///     Literal {
+///         // ...
+///         fn character(ch: char) -> MySelf::Literal;
+///         // ...
+///         fn span(my_self: &MySelf::Literal) -> MySelf::Span;
+///         fn set_span(my_self: &mut MySelf::Literal, span: MySelf::Span);
+///     },
+///     // ...
+/// }
+/// ```
+///
+/// The first two arguments serve to customize the arguments names
+/// and argument/return types, to enable several different usecases:
+///
+/// If `my_self` is just `self`, then each `fn` signature can be used
+/// as-is for a method. If it's anything else (`self_` in practice),
+/// then the signatures don't have a special `self` argument, and
+/// can, therefore, have a different one introduced.
+///
+/// If `MySelf` is just `Self`, then the types are only valid inside
+/// a trait or a trait impl, where the trait has associated types
+/// for each of the API types. If non-associated types are desired,
+/// a module name (`self` in practice) can be used instead of `Self`.
+macro_rules! with_api {
+    ($S:ident, $self:ident, $m:ident) => {
+        $m! {
+            TokenStream {
+                fn drop($self: $S::TokenStream);
+                fn clone($self: &$S::TokenStream) -> $S::TokenStream;
+                fn new() -> $S::TokenStream;
+                fn is_empty($self: &$S::TokenStream) -> bool;
+                fn from_str(src: &str) -> $S::TokenStream;
+                fn to_string($self: &$S::TokenStream) -> String;
+                fn from_token_tree(
+                    tree: TokenTree<$S::Group, $S::Punct, $S::Ident, $S::Literal>,
+                ) -> $S::TokenStream;
+                fn into_iter($self: $S::TokenStream) -> $S::TokenStreamIter;
+            },
+            TokenStreamBuilder {
+                fn drop($self: $S::TokenStreamBuilder);
+                fn new() -> $S::TokenStreamBuilder;
+                fn push($self: &mut $S::TokenStreamBuilder, stream: $S::TokenStream);
+                fn build($self: $S::TokenStreamBuilder) -> $S::TokenStream;
+            },
+            TokenStreamIter {
+                fn drop($self: $S::TokenStreamIter);
+                fn clone($self: &$S::TokenStreamIter) -> $S::TokenStreamIter;
+                fn next(
+                    $self: &mut $S::TokenStreamIter,
+                ) -> Option<TokenTree<$S::Group, $S::Punct, $S::Ident, $S::Literal>>;
+            },
+            Group {
+                fn drop($self: $S::Group);
+                fn clone($self: &$S::Group) -> $S::Group;
+                fn new(delimiter: Delimiter, stream: $S::TokenStream) -> $S::Group;
+                fn delimiter($self: &$S::Group) -> Delimiter;
+                fn stream($self: &$S::Group) -> $S::TokenStream;
+                fn span($self: &$S::Group) -> $S::Span;
+                fn span_open($self: &$S::Group) -> $S::Span;
+                fn span_close($self: &$S::Group) -> $S::Span;
+                fn set_span($self: &mut $S::Group, span: $S::Span);
+            },
+            Punct {
+                fn new(ch: char, spacing: Spacing) -> $S::Punct;
+                fn as_char($self: $S::Punct) -> char;
+                fn spacing($self: $S::Punct) -> Spacing;
+                fn span($self: $S::Punct) -> $S::Span;
+                fn with_span($self: $S::Punct, span: $S::Span) -> $S::Punct;
+            },
+            Ident {
+                fn new(string: &str, span: $S::Span, is_raw: bool) -> $S::Ident;
+                fn span($self: $S::Ident) -> $S::Span;
+                fn with_span($self: $S::Ident, span: $S::Span) -> $S::Ident;
+            },
+            Literal {
+                fn drop($self: $S::Literal);
+                fn clone($self: &$S::Literal) -> $S::Literal;
+                // FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
+                fn debug($self: &$S::Literal) -> String;
+                fn integer(n: &str) -> $S::Literal;
+                fn typed_integer(n: &str, kind: &str) -> $S::Literal;
+                fn float(n: &str) -> $S::Literal;
+                fn f32(n: &str) -> $S::Literal;
+                fn f64(n: &str) -> $S::Literal;
+                fn string(string: &str) -> $S::Literal;
+                fn character(ch: char) -> $S::Literal;
+                fn byte_string(bytes: &[u8]) -> $S::Literal;
+                fn span($self: &$S::Literal) -> $S::Span;
+                fn set_span($self: &mut $S::Literal, span: $S::Span);
+                fn subspan(
+                    $self: &$S::Literal,
+                    start: Bound<usize>,
+                    end: Bound<usize>,
+                ) -> Option<$S::Span>;
+            },
+            SourceFile {
+                fn drop($self: $S::SourceFile);
+                fn clone($self: &$S::SourceFile) -> $S::SourceFile;
+                fn eq($self: &$S::SourceFile, other: &$S::SourceFile) -> bool;
+                fn path($self: &$S::SourceFile) -> String;
+                fn is_real($self: &$S::SourceFile) -> bool;
+            },
+            MultiSpan {
+                fn drop($self: $S::MultiSpan);
+                fn new() -> $S::MultiSpan;
+                fn push($self: &mut $S::MultiSpan, span: $S::Span);
+            },
+            Diagnostic {
+                fn drop($self: $S::Diagnostic);
+                fn new(level: Level, msg: &str, span: $S::MultiSpan) -> $S::Diagnostic;
+                fn sub(
+                    $self: &mut $S::Diagnostic,
+                    level: Level,
+                    msg: &str,
+                    span: $S::MultiSpan,
+                );
+                fn emit($self: $S::Diagnostic);
+            },
+            Span {
+                fn debug($self: $S::Span) -> String;
+                fn def_site() -> $S::Span;
+                fn call_site() -> $S::Span;
+                fn source_file($self: $S::Span) -> $S::SourceFile;
+                fn parent($self: $S::Span) -> Option<$S::Span>;
+                fn source($self: $S::Span) -> $S::Span;
+                fn start($self: $S::Span) -> LineColumn;
+                fn end($self: $S::Span) -> LineColumn;
+                fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
+                fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
+            },
+        }
+    };
+}
+
+// FIXME(eddyb) this calls `encode` for each argument, but in reverse,
+// to avoid borrow conflicts from borrows started by `&mut` arguments.
+macro_rules! reverse_encode {
+    ($writer:ident;) => {};
+    ($writer:ident; $first:ident $(, $rest:ident)*) => {
+        reverse_encode!($writer; $($rest),*);
+        $first.encode(&mut $writer, &mut ());
+    }
+}
+
+// FIXME(eddyb) this calls `decode` for each argument, but in reverse,
+// to avoid borrow conflicts from borrows started by `&mut` arguments.
+macro_rules! reverse_decode {
+    ($reader:ident, $s:ident;) => {};
+    ($reader:ident, $s:ident; $first:ident: $first_ty:ty $(, $rest:ident: $rest_ty:ty)*) => {
+        reverse_decode!($reader, $s; $($rest: $rest_ty),*);
+        let $first = <$first_ty>::decode(&mut $reader, $s);
+    }
+}
+
+#[allow(unsafe_code)]
+mod buffer;
+#[forbid(unsafe_code)]
+pub mod client;
+#[allow(unsafe_code)]
+mod closure;
+#[forbid(unsafe_code)]
+mod handle;
+#[macro_use]
+#[forbid(unsafe_code)]
+mod rpc;
+#[allow(unsafe_code)]
+mod scoped_cell;
+#[forbid(unsafe_code)]
+pub mod server;
+
+use self::buffer::Buffer;
+pub use self::rpc::PanicMessage;
+use self::rpc::{Decode, DecodeMut, Encode, Reader, Writer};
+
+/// An active connection between a server and a client.
+/// The server creates the bridge (`Bridge::run_server` in `server.rs`),
+/// then passes it to the client through the function pointer in the `run`
+/// field of `client::Client`. The client holds its copy of the `Bridge`
+/// in TLS during its execution (`Bridge::{enter, with}` in `client.rs`).
+#[repr(C)]
+pub struct Bridge<'a> {
+    /// Reusable buffer (only `clear`-ed, never shrunk), primarily
+    /// used for making requests, but also for passing input to client.
+    cached_buffer: Buffer<u8>,
+
+    /// Server-side function that the client uses to make requests.
+    dispatch: closure::Closure<'a, Buffer<u8>, Buffer<u8>>,
+}
+
+impl<'a> !Sync for Bridge<'a> {}
+impl<'a> !Send for Bridge<'a> {}
+
+#[forbid(unsafe_code)]
+#[allow(non_camel_case_types)]
+mod api_tags {
+    use super::rpc::{DecodeMut, Encode, Reader, Writer};
+
+    macro_rules! declare_tags {
+        ($($name:ident {
+            $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)*) $(-> $ret_ty:ty)*;)*
+        }),* $(,)*) => {
+            $(
+                pub(super) enum $name {
+                    $($method),*
+                }
+                rpc_encode_decode!(enum $name { $($method),* });
+            )*
+
+
+            pub(super) enum Method {
+                $($name($name)),*
+            }
+            rpc_encode_decode!(enum Method { $($name(m)),* });
+        }
+    }
+    with_api!(self, self, declare_tags);
+}
+
+/// Helper to wrap associated types to allow trait impl dispatch.
+/// That is, normally a pair of impls for `T::Foo` and `T::Bar`
+/// can overlap, but if the impls are, instead, on types like
+/// `Marked<T::Foo, Foo>` and `Marked<T::Bar, Bar>`, they can't.
+trait Mark {
+    type Unmarked;
+    fn mark(unmarked: Self::Unmarked) -> Self;
+}
+
+/// Unwrap types wrapped by `Mark::mark` (see `Mark` for details).
+trait Unmark {
+    type Unmarked;
+    fn unmark(self) -> Self::Unmarked;
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+struct Marked<T, M> {
+    value: T,
+    _marker: marker::PhantomData<M>,
+}
+
+impl<T, M> Mark for Marked<T, M> {
+    type Unmarked = T;
+    fn mark(unmarked: Self::Unmarked) -> Self {
+        Marked {
+            value: unmarked,
+            _marker: marker::PhantomData,
+        }
+    }
+}
+impl<T, M> Unmark for Marked<T, M> {
+    type Unmarked = T;
+    fn unmark(self) -> Self::Unmarked {
+        self.value
+    }
+}
+impl<T, M> Unmark for &'a Marked<T, M> {
+    type Unmarked = &'a T;
+    fn unmark(self) -> Self::Unmarked {
+        &self.value
+    }
+}
+impl<T, M> Unmark for &'a mut Marked<T, M> {
+    type Unmarked = &'a mut T;
+    fn unmark(self) -> Self::Unmarked {
+        &mut self.value
+    }
+}
+
+impl<T: Mark> Mark for Option<T> {
+    type Unmarked = Option<T::Unmarked>;
+    fn mark(unmarked: Self::Unmarked) -> Self {
+        unmarked.map(T::mark)
+    }
+}
+impl<T: Unmark> Unmark for Option<T> {
+    type Unmarked = Option<T::Unmarked>;
+    fn unmark(self) -> Self::Unmarked {
+        self.map(T::unmark)
+    }
+}
+
+macro_rules! mark_noop {
+    ($($ty:ty),* $(,)*) => {
+        $(
+            impl Mark for $ty {
+                type Unmarked = Self;
+                fn mark(unmarked: Self::Unmarked) -> Self {
+                    unmarked
+                }
+            }
+            impl Unmark for $ty {
+                type Unmarked = Self;
+                fn unmark(self) -> Self::Unmarked {
+                    self
+                }
+            }
+        )*
+    }
+}
+mark_noop! {
+    (),
+    bool,
+    char,
+    &'a [u8],
+    &'a str,
+    String,
+    Delimiter,
+    Level,
+    LineColumn,
+    Spacing,
+    Bound<usize>,
+}
+
+rpc_encode_decode!(
+    enum Delimiter {
+        Parenthesis,
+        Brace,
+        Bracket,
+        None,
+    }
+);
+rpc_encode_decode!(
+    enum Level {
+        Error,
+        Warning,
+        Note,
+        Help,
+    }
+);
+rpc_encode_decode!(struct LineColumn { line, column });
+rpc_encode_decode!(
+    enum Spacing {
+        Alone,
+        Joint,
+    }
+);
+
+#[derive(Clone)]
+pub enum TokenTree<G, P, I, L> {
+    Group(G),
+    Punct(P),
+    Ident(I),
+    Literal(L),
+}
+
+impl<G: Mark, P: Mark, I: Mark, L: Mark> Mark for TokenTree<G, P, I, L> {
+    type Unmarked = TokenTree<G::Unmarked, P::Unmarked, I::Unmarked, L::Unmarked>;
+    fn mark(unmarked: Self::Unmarked) -> Self {
+        match unmarked {
+            TokenTree::Group(tt) => TokenTree::Group(G::mark(tt)),
+            TokenTree::Punct(tt) => TokenTree::Punct(P::mark(tt)),
+            TokenTree::Ident(tt) => TokenTree::Ident(I::mark(tt)),
+            TokenTree::Literal(tt) => TokenTree::Literal(L::mark(tt)),
+        }
+    }
+}
+impl<G: Unmark, P: Unmark, I: Unmark, L: Unmark> Unmark for TokenTree<G, P, I, L> {
+    type Unmarked = TokenTree<G::Unmarked, P::Unmarked, I::Unmarked, L::Unmarked>;
+    fn unmark(self) -> Self::Unmarked {
+        match self {
+            TokenTree::Group(tt) => TokenTree::Group(tt.unmark()),
+            TokenTree::Punct(tt) => TokenTree::Punct(tt.unmark()),
+            TokenTree::Ident(tt) => TokenTree::Ident(tt.unmark()),
+            TokenTree::Literal(tt) => TokenTree::Literal(tt.unmark()),
+        }
+    }
+}
+
+rpc_encode_decode!(
+    enum TokenTree<G, P, I, L> {
+        Group(tt),
+        Punct(tt),
+        Ident(tt),
+        Literal(tt),
+    }
+);
diff --git a/src/libproc_macro/bridge/rpc.rs b/src/libproc_macro/bridge/rpc.rs
new file mode 100644
index 0000000..fafc3d0
--- /dev/null
+++ b/src/libproc_macro/bridge/rpc.rs
@@ -0,0 +1,319 @@
+// 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.
+
+//! Serialization for client<->server communication.
+
+use std::any::Any;
+use std::char;
+use std::io::Write;
+use std::num::NonZeroU32;
+use std::ops::Bound;
+use std::str;
+
+pub(super) type Writer = super::buffer::Buffer<u8>;
+
+pub(super) trait Encode<S>: Sized {
+    fn encode(self, w: &mut Writer, s: &mut S);
+}
+
+pub(super) type Reader<'a> = &'a [u8];
+
+pub(super) trait Decode<'a, 's, S>: Sized {
+    fn decode(r: &mut Reader<'a>, s: &'s S) -> Self;
+}
+
+pub(super) trait DecodeMut<'a, 's, S>: Sized {
+    fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
+}
+
+macro_rules! rpc_encode_decode {
+    (uleb128 $ty:ty) => {
+        impl<S> Encode<S> for $ty {
+            fn encode(mut self, w: &mut Writer, s: &mut S) {
+                let mut byte = 0x80;
+                while byte & 0x80 != 0 {
+                    byte = (self & 0x7f) as u8;
+                    self >>= 7;
+                    if self != 0 {
+                        byte |= 0x80;
+                    }
+                    byte.encode(w, s);
+                }
+            }
+        }
+
+        impl<S> DecodeMut<'_, '_, S> for $ty {
+            fn decode(r: &mut Reader, s: &mut S) -> Self {
+                let mut byte = 0x80;
+                let mut v = 0;
+                let mut shift = 0;
+                while byte & 0x80 != 0 {
+                    byte = u8::decode(r, s);
+                    v |= ((byte & 0x7f) as Self) << shift;
+                    shift += 7;
+                }
+                v
+            }
+        }
+    };
+    (struct $name:ident { $($field:ident),* $(,)* }) => {
+        impl<S> Encode<S> for $name {
+            fn encode(self, w: &mut Writer, s: &mut S) {
+                $(self.$field.encode(w, s);)*
+            }
+        }
+
+        impl<S> DecodeMut<'_, '_, S> for $name {
+            fn decode(r: &mut Reader, s: &mut S) -> Self {
+                $name {
+                    $($field: DecodeMut::decode(r, s)),*
+                }
+            }
+        }
+    };
+    (enum $name:ident $(<$($T:ident),+>)* { $($variant:ident $(($field:ident))*),* $(,)* }) => {
+        impl<S, $($($T: Encode<S>),+)*> Encode<S> for $name $(<$($T),+>)* {
+            fn encode(self, w: &mut Writer, s: &mut S) {
+                // HACK(eddyb) `Tag` enum duplicated between the
+                // two impls as there's no other place to stash it.
+                #[repr(u8)] enum Tag { $($variant),* }
+                #[allow(non_upper_case_globals)]
+                impl Tag { $(const $variant: u8 = Tag::$variant as u8;)* }
+
+                match self {
+                    $($name::$variant $(($field))* => {
+                        <Tag>::$variant.encode(w, s);
+                        $($field.encode(w, s);)*
+                    })*
+                }
+            }
+        }
+
+        impl<S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)*> DecodeMut<'a, '_, S>
+            for $name $(<$($T),+>)*
+        {
+            fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
+                // HACK(eddyb) `Tag` enum duplicated between the
+                // two impls as there's no other place to stash it.
+                #[repr(u8)] enum Tag { $($variant),* }
+                #[allow(non_upper_case_globals)]
+                impl Tag { $(const $variant: u8 = Tag::$variant as u8;)* }
+
+                match u8::decode(r, s) {
+                    $(<Tag>::$variant => {
+                        $(let $field = DecodeMut::decode(r, s);)*
+                        $name::$variant $(($field))*
+                    })*
+                    _ => unreachable!(),
+                }
+            }
+        }
+    }
+}
+
+impl<S> Encode<S> for () {
+    fn encode(self, _: &mut Writer, _: &mut S) {}
+}
+
+impl<S> DecodeMut<'_, '_, S> for () {
+    fn decode(_: &mut Reader, _: &mut S) -> Self {}
+}
+
+impl<S> Encode<S> for u8 {
+    fn encode(self, w: &mut Writer, _: &mut S) {
+        w.write_all(&[self]).unwrap();
+    }
+}
+
+impl<S> DecodeMut<'_, '_, S> for u8 {
+    fn decode(r: &mut Reader, _: &mut S) -> Self {
+        let x = r[0];
+        *r = &r[1..];
+        x
+    }
+}
+
+rpc_encode_decode!(uleb128 u32);
+rpc_encode_decode!(uleb128 usize);
+
+impl<S> Encode<S> for bool {
+    fn encode(self, w: &mut Writer, s: &mut S) {
+        (self as u8).encode(w, s);
+    }
+}
+
+impl<S> DecodeMut<'_, '_, S> for bool {
+    fn decode(r: &mut Reader, s: &mut S) -> Self {
+        match u8::decode(r, s) {
+            0 => false,
+            1 => true,
+            _ => unreachable!(),
+        }
+    }
+}
+
+impl<S> Encode<S> for char {
+    fn encode(self, w: &mut Writer, s: &mut S) {
+        (self as u32).encode(w, s);
+    }
+}
+
+impl<S> DecodeMut<'_, '_, S> for char {
+    fn decode(r: &mut Reader, s: &mut S) -> Self {
+        char::from_u32(u32::decode(r, s)).unwrap()
+    }
+}
+
+impl<S> Encode<S> for NonZeroU32 {
+    fn encode(self, w: &mut Writer, s: &mut S) {
+        self.get().encode(w, s);
+    }
+}
+
+impl<S> DecodeMut<'_, '_, S> for NonZeroU32 {
+    fn decode(r: &mut Reader, s: &mut S) -> Self {
+        Self::new(u32::decode(r, s)).unwrap()
+    }
+}
+
+impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
+    fn encode(self, w: &mut Writer, s: &mut S) {
+        self.0.encode(w, s);
+        self.1.encode(w, s);
+    }
+}
+
+impl<S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
+    for (A, B)
+{
+    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
+        (DecodeMut::decode(r, s), DecodeMut::decode(r, s))
+    }
+}
+
+rpc_encode_decode!(
+    enum Bound<T> {
+        Included(x),
+        Excluded(x),
+        Unbounded,
+    }
+);
+
+rpc_encode_decode!(
+    enum Option<T> {
+        None,
+        Some(x),
+    }
+);
+
+rpc_encode_decode!(
+    enum Result<T, E> {
+        Ok(x),
+        Err(e),
+    }
+);
+
+impl<S> Encode<S> for &[u8] {
+    fn encode(self, w: &mut Writer, s: &mut S) {
+        self.len().encode(w, s);
+        w.write_all(self).unwrap();
+    }
+}
+
+impl<S> DecodeMut<'a, '_, S> for &'a [u8] {
+    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
+        let len = usize::decode(r, s);
+        let xs = &r[..len];
+        *r = &r[len..];
+        xs
+    }
+}
+
+impl<S> Encode<S> for &str {
+    fn encode(self, w: &mut Writer, s: &mut S) {
+        self.as_bytes().encode(w, s);
+    }
+}
+
+impl<S> DecodeMut<'a, '_, S> for &'a str {
+    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
+        str::from_utf8(<&[u8]>::decode(r, s)).unwrap()
+    }
+}
+
+impl<S> Encode<S> for String {
+    fn encode(self, w: &mut Writer, s: &mut S) {
+        self[..].encode(w, s);
+    }
+}
+
+impl<S> DecodeMut<'_, '_, S> for String {
+    fn decode(r: &mut Reader, s: &mut S) -> Self {
+        <&str>::decode(r, s).to_string()
+    }
+}
+
+/// Simplied version of panic payloads, ignoring
+/// types other than `&'static str` and `String`.
+pub enum PanicMessage {
+    StaticStr(&'static str),
+    String(String),
+    Unknown,
+}
+
+impl From<Box<dyn Any + Send>> for PanicMessage {
+    fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
+        if let Some(s) = payload.downcast_ref::<&'static str>() {
+            return PanicMessage::StaticStr(s);
+        }
+        if let Ok(s) = payload.downcast::<String>() {
+            return PanicMessage::String(*s);
+        }
+        PanicMessage::Unknown
+    }
+}
+
+impl Into<Box<dyn Any + Send>> for PanicMessage {
+    fn into(self) -> Box<dyn Any + Send> {
+        match self {
+            PanicMessage::StaticStr(s) => Box::new(s),
+            PanicMessage::String(s) => Box::new(s),
+            PanicMessage::Unknown => {
+                struct UnknownPanicMessage;
+                Box::new(UnknownPanicMessage)
+            }
+        }
+    }
+}
+
+impl PanicMessage {
+    pub fn as_str(&self) -> Option<&str> {
+        match self {
+            PanicMessage::StaticStr(s) => Some(s),
+            PanicMessage::String(s) => Some(s),
+            PanicMessage::Unknown => None,
+        }
+    }
+}
+
+impl<S> Encode<S> for PanicMessage {
+    fn encode(self, w: &mut Writer, s: &mut S) {
+        self.as_str().encode(w, s);
+    }
+}
+
+impl<S> DecodeMut<'_, '_, S> for PanicMessage {
+    fn decode(r: &mut Reader, s: &mut S) -> Self {
+        match Option::<String>::decode(r, s) {
+            Some(s) => PanicMessage::String(s),
+            None => PanicMessage::Unknown,
+        }
+    }
+}
diff --git a/src/libproc_macro/bridge/scoped_cell.rs b/src/libproc_macro/bridge/scoped_cell.rs
new file mode 100644
index 0000000..51d1fec
--- /dev/null
+++ b/src/libproc_macro/bridge/scoped_cell.rs
@@ -0,0 +1,90 @@
+// 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.
+
+//! `Cell` variant for (scoped) existential lifetimes.
+
+use std::cell::Cell;
+use std::mem;
+use std::ops::{Deref, DerefMut};
+
+/// Type lambda application, with a lifetime.
+pub trait ApplyL<'a> {
+    type Out;
+}
+
+/// Type lambda taking a lifetime, i.e. `Lifetime -> Type`.
+pub trait LambdaL: for<'a> ApplyL<'a> {}
+
+impl<T: for<'a> ApplyL<'a>> LambdaL for T {}
+
+// HACK(eddyb) work around projection limitations with a newtype
+// FIXME(#52812) replace with `&'a mut <T as ApplyL<'b>>::Out`
+pub struct RefMutL<'a, 'b, T: LambdaL>(&'a mut <T as ApplyL<'b>>::Out);
+
+impl<'a, 'b, T: LambdaL> Deref for RefMutL<'a, 'b, T> {
+    type Target = <T as ApplyL<'b>>::Out;
+    fn deref(&self) -> &Self::Target {
+        self.0
+    }
+}
+
+impl<'a, 'b, T: LambdaL> DerefMut for RefMutL<'a, 'b, T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        self.0
+    }
+}
+
+pub struct ScopedCell<T: LambdaL>(Cell<<T as ApplyL<'static>>::Out>);
+
+impl<T: LambdaL> ScopedCell<T> {
+    pub const fn new(value: <T as ApplyL<'static>>::Out) -> Self {
+        ScopedCell(Cell::new(value))
+    }
+
+    /// Set the value in `self` to `replacement` while
+    /// running `f`, which gets the old value, mutably.
+    /// The old value will be restored after `f` exits, even
+    /// by panic, including modifications made to it by `f`.
+    pub fn replace<'a, R>(
+        &self,
+        replacement: <T as ApplyL<'a>>::Out,
+        f: impl for<'b, 'c> FnOnce(RefMutL<'b, 'c, T>) -> R,
+    ) -> R {
+        /// Wrapper that ensures that the cell always gets filled
+        /// (with the original state, optionally changed by `f`),
+        /// even if `f` had panicked.
+        struct PutBackOnDrop<'a, T: LambdaL> {
+            cell: &'a ScopedCell<T>,
+            value: Option<<T as ApplyL<'static>>::Out>,
+        }
+
+        impl<'a, T: LambdaL> Drop for PutBackOnDrop<'a, T> {
+            fn drop(&mut self) {
+                self.cell.0.set(self.value.take().unwrap());
+            }
+        }
+
+        let mut put_back_on_drop = PutBackOnDrop {
+            cell: self,
+            value: Some(self.0.replace(unsafe {
+                let erased = mem::transmute_copy(&replacement);
+                mem::forget(replacement);
+                erased
+            })),
+        };
+
+        f(RefMutL(put_back_on_drop.value.as_mut().unwrap()))
+    }
+
+    /// Set the value in `self` to `value` while running `f`.
+    pub fn set<'a, R>(&self, value: <T as ApplyL<'a>>::Out, f: impl FnOnce() -> R) -> R {
+        self.replace(value, |_| f())
+    }
+}
diff --git a/src/libproc_macro/bridge/server.rs b/src/libproc_macro/bridge/server.rs
new file mode 100644
index 0000000..f500b17
--- /dev/null
+++ b/src/libproc_macro/bridge/server.rs
@@ -0,0 +1,352 @@
+// 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.
+
+//! Server-side traits.
+
+use super::*;
+
+// FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
+use super::client::HandleStore;
+
+/// Declare an associated item of one of the traits below, optionally
+/// adjusting it (i.e. adding bounds to types and default bodies to methods).
+macro_rules! associated_item {
+    (type TokenStream) =>
+        (type TokenStream: 'static + Clone;);
+    (type TokenStreamBuilder) =>
+        (type TokenStreamBuilder: 'static;);
+    (type TokenStreamIter) =>
+        (type TokenStreamIter: 'static + Clone;);
+    (type Group) =>
+        (type Group: 'static + Clone;);
+    (type Punct) =>
+        (type Punct: 'static + Copy + Eq + Hash;);
+    (type Ident) =>
+        (type Ident: 'static + Copy + Eq + Hash;);
+    (type Literal) =>
+        (type Literal: 'static + Clone;);
+    (type SourceFile) =>
+        (type SourceFile: 'static + Clone;);
+    (type MultiSpan) =>
+        (type MultiSpan: 'static;);
+    (type Diagnostic) =>
+        (type Diagnostic: 'static;);
+    (type Span) =>
+        (type Span: 'static + Copy + Eq + Hash;);
+    (fn drop(&mut self, $arg:ident: $arg_ty:ty)) =>
+        (fn drop(&mut self, $arg: $arg_ty) { mem::drop($arg) });
+    (fn clone(&mut self, $arg:ident: $arg_ty:ty) -> $ret_ty:ty) =>
+        (fn clone(&mut self, $arg: $arg_ty) -> $ret_ty { $arg.clone() });
+    ($($item:tt)*) => ($($item)*;)
+}
+
+macro_rules! declare_server_traits {
+    ($($name:ident {
+        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)*) $(-> $ret_ty:ty)*;)*
+    }),* $(,)*) => {
+        pub trait Types {
+            $(associated_item!(type $name);)*
+        }
+
+        $(pub trait $name: Types {
+            $(associated_item!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)*);)*
+        })*
+
+        pub trait Server: Types $(+ $name)* {}
+        impl<S: Types $(+ $name)*> Server for S {}
+    }
+}
+with_api!(Self, self_, declare_server_traits);
+
+pub(super) struct MarkedTypes<S: Types>(S);
+
+macro_rules! define_mark_types_impls {
+    ($($name:ident {
+        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)*) $(-> $ret_ty:ty)*;)*
+    }),* $(,)*) => {
+        impl<S: Types> Types for MarkedTypes<S> {
+            $(type $name = Marked<S::$name, client::$name>;)*
+        }
+
+        $(impl<S: $name> $name for MarkedTypes<S> {
+            $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)* {
+                <_>::mark($name::$method(&mut self.0, $($arg.unmark()),*))
+            })*
+        })*
+    }
+}
+with_api!(Self, self_, define_mark_types_impls);
+
+struct Dispatcher<S: Types> {
+    handle_store: HandleStore<S>,
+    server: S,
+}
+
+macro_rules! define_dispatcher_impl {
+    ($($name:ident {
+        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)*) $(-> $ret_ty:ty)*;)*
+    }),* $(,)*) => {
+        // FIXME(eddyb) `pub` only for `ExecutionStrategy` below.
+        pub trait DispatcherTrait {
+            // HACK(eddyb) these are here to allow `Self::$name` to work below.
+            $(type $name;)*
+            fn dispatch(&mut self, b: Buffer<u8>) -> Buffer<u8>;
+        }
+
+        impl<S: Server> DispatcherTrait for Dispatcher<MarkedTypes<S>> {
+            $(type $name = <MarkedTypes<S> as Types>::$name;)*
+            fn dispatch(&mut self, mut b: Buffer<u8>) -> Buffer<u8> {
+                let Dispatcher { handle_store, server } = self;
+
+                let mut reader = &b[..];
+                match api_tags::Method::decode(&mut reader, &mut ()) {
+                    $(api_tags::Method::$name(m) => match m {
+                        $(api_tags::$name::$method => {
+                            let mut call_method = || {
+                                reverse_decode!(reader, handle_store; $($arg: $arg_ty),*);
+                                $name::$method(server, $($arg),*)
+                            };
+                            // HACK(eddyb) don't use `panic::catch_unwind` in a panic.
+                            // If client and server happen to use the same `libstd`,
+                            // `catch_unwind` asserts that the panic counter was 0,
+                            // even when the closure passed to it didn't panic.
+                            let r = if thread::panicking() {
+                                Ok(call_method())
+                            } else {
+                                panic::catch_unwind(panic::AssertUnwindSafe(call_method))
+                                    .map_err(PanicMessage::from)
+                            };
+
+                            b.clear();
+                            r.encode(&mut b, handle_store);
+                        })*
+                    }),*
+                }
+                b
+            }
+        }
+    }
+}
+with_api!(Self, self_, define_dispatcher_impl);
+
+pub trait ExecutionStrategy {
+    fn run_bridge_and_client<D: Copy + Send + 'static>(
+        &self,
+        dispatcher: &mut impl DispatcherTrait,
+        input: Buffer<u8>,
+        run_client: extern "C" fn(Bridge, D) -> Buffer<u8>,
+        client_data: D,
+    ) -> Buffer<u8>;
+}
+
+pub struct SameThread;
+
+impl ExecutionStrategy for SameThread {
+    fn run_bridge_and_client<D: Copy + Send + 'static>(
+        &self,
+        dispatcher: &mut impl DispatcherTrait,
+        input: Buffer<u8>,
+        run_client: extern "C" fn(Bridge, D) -> Buffer<u8>,
+        client_data: D,
+    ) -> Buffer<u8> {
+        let mut dispatch = |b| dispatcher.dispatch(b);
+
+        run_client(
+            Bridge {
+                cached_buffer: input,
+                dispatch: (&mut dispatch).into(),
+            },
+            client_data,
+        )
+    }
+}
+
+// NOTE(eddyb) Two implementations are provided, the second one is a bit
+// faster but neither is anywhere near as fast as same-thread execution.
+
+pub struct CrossThread1;
+
+impl ExecutionStrategy for CrossThread1 {
+    fn run_bridge_and_client<D: Copy + Send + 'static>(
+        &self,
+        dispatcher: &mut impl DispatcherTrait,
+        input: Buffer<u8>,
+        run_client: extern "C" fn(Bridge, D) -> Buffer<u8>,
+        client_data: D,
+    ) -> Buffer<u8> {
+        use std::sync::mpsc::channel;
+
+        let (req_tx, req_rx) = channel();
+        let (res_tx, res_rx) = channel();
+
+        let join_handle = thread::spawn(move || {
+            let mut dispatch = |b| {
+                req_tx.send(b).unwrap();
+                res_rx.recv().unwrap()
+            };
+
+            run_client(
+                Bridge {
+                    cached_buffer: input,
+                    dispatch: (&mut dispatch).into(),
+                },
+                client_data,
+            )
+        });
+
+        for b in req_rx {
+            res_tx.send(dispatcher.dispatch(b)).unwrap();
+        }
+
+        join_handle.join().unwrap()
+    }
+}
+
+pub struct CrossThread2;
+
+impl ExecutionStrategy for CrossThread2 {
+    fn run_bridge_and_client<D: Copy + Send + 'static>(
+        &self,
+        dispatcher: &mut impl DispatcherTrait,
+        input: Buffer<u8>,
+        run_client: extern "C" fn(Bridge, D) -> Buffer<u8>,
+        client_data: D,
+    ) -> Buffer<u8> {
+        use std::sync::{Arc, Mutex};
+
+        enum State<T> {
+            Req(T),
+            Res(T),
+        }
+
+        let mut state = Arc::new(Mutex::new(State::Res(Buffer::new())));
+
+        let server_thread = thread::current();
+        let state2 = state.clone();
+        let join_handle = thread::spawn(move || {
+            let mut dispatch = |b| {
+                *state2.lock().unwrap() = State::Req(b);
+                server_thread.unpark();
+                loop {
+                    thread::park();
+                    if let State::Res(b) = &mut *state2.lock().unwrap() {
+                        break b.take();
+                    }
+                }
+            };
+
+            let r = run_client(
+                Bridge {
+                    cached_buffer: input,
+                    dispatch: (&mut dispatch).into(),
+                },
+                client_data,
+            );
+
+            // Wake up the server so it can exit the dispatch loop.
+            drop(state2);
+            server_thread.unpark();
+
+            r
+        });
+
+        // Check whether `state2` was dropped, to know when to stop.
+        while Arc::get_mut(&mut state).is_none() {
+            thread::park();
+            let mut b = match &mut *state.lock().unwrap() {
+                State::Req(b) => b.take(),
+                _ => continue,
+            };
+            b = dispatcher.dispatch(b.take());
+            *state.lock().unwrap() = State::Res(b);
+            join_handle.thread().unpark();
+        }
+
+        join_handle.join().unwrap()
+    }
+}
+
+fn run_server<
+    S: Server,
+    I: Encode<HandleStore<MarkedTypes<S>>>,
+    O: for<'a, 's> DecodeMut<'a, 's, HandleStore<MarkedTypes<S>>>,
+    D: Copy + Send + 'static,
+>(
+    strategy: &impl ExecutionStrategy,
+    handle_counters: &'static client::HandleCounters,
+    server: S,
+    input: I,
+    run_client: extern "C" fn(Bridge, D) -> Buffer<u8>,
+    client_data: D,
+) -> Result<O, PanicMessage> {
+    let mut dispatcher = Dispatcher {
+        handle_store: HandleStore::new(handle_counters),
+        server: MarkedTypes(server),
+    };
+
+    let mut b = Buffer::new();
+    input.encode(&mut b, &mut dispatcher.handle_store);
+
+    b = strategy.run_bridge_and_client(&mut dispatcher, b, run_client, client_data);
+
+    Result::decode(&mut &b[..], &mut dispatcher.handle_store)
+}
+
+impl client::Client<fn(::TokenStream) -> ::TokenStream> {
+    pub fn run<S: Server>(
+        &self,
+        strategy: &impl ExecutionStrategy,
+        server: S,
+        input: S::TokenStream,
+    ) -> Result<S::TokenStream, PanicMessage> {
+        let client::Client {
+            get_handle_counters,
+            run,
+            f,
+        } = *self;
+        run_server(
+            strategy,
+            get_handle_counters(),
+            server,
+            <MarkedTypes<S> as Types>::TokenStream::mark(input),
+            run,
+            f,
+        )
+        .map(<MarkedTypes<S> as Types>::TokenStream::unmark)
+    }
+}
+
+impl client::Client<fn(::TokenStream, ::TokenStream) -> ::TokenStream> {
+    pub fn run<S: Server>(
+        &self,
+        strategy: &impl ExecutionStrategy,
+        server: S,
+        input: S::TokenStream,
+        input2: S::TokenStream,
+    ) -> Result<S::TokenStream, PanicMessage> {
+        let client::Client {
+            get_handle_counters,
+            run,
+            f,
+        } = *self;
+        run_server(
+            strategy,
+            get_handle_counters(),
+            server,
+            (
+                <MarkedTypes<S> as Types>::TokenStream::mark(input),
+                <MarkedTypes<S> as Types>::TokenStream::mark(input2),
+            ),
+            run,
+            f,
+        )
+        .map(<MarkedTypes<S> as Types>::TokenStream::unmark)
+    }
+}
diff --git a/src/libproc_macro/diagnostic.rs b/src/libproc_macro/diagnostic.rs
index bf23de3..4234f0b 100644
--- a/src/libproc_macro/diagnostic.rs
+++ b/src/libproc_macro/diagnostic.rs
@@ -10,8 +10,6 @@
 
 use Span;
 
-use rustc_errors as errors;
-
 /// An enum representing a diagnostic level.
 #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
 #[derive(Copy, Clone, Debug)]
@@ -180,22 +178,22 @@
     /// Emit the diagnostic.
     #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
     pub fn emit(self) {
-        fn to_internal(spans: Vec<Span>) -> ::syntax_pos::MultiSpan {
-            let spans: Vec<_> = spans.into_iter().map(|s| s.0).collect();
-            ::syntax_pos::MultiSpan::from_spans(spans)
+        fn to_internal(spans: Vec<Span>) -> ::bridge::client::MultiSpan {
+            let mut multi_span = ::bridge::client::MultiSpan::new();
+            for span in spans {
+                multi_span.push(span.0);
+            }
+            multi_span
         }
 
-        let level = self.level.to_internal();
-        let mut diag = errors::Diagnostic::new(level, &*self.message);
-        diag.set_span(to_internal(self.spans));
-
-        for child in self.children {
-            let level = child.level.to_internal();
-            diag.sub(level, &*child.message, to_internal(child.spans), None);
+        let mut diag = ::bridge::client::Diagnostic::new(
+            self.level,
+            &self.message[..],
+            to_internal(self.spans),
+        );
+        for c in self.children {
+            diag.sub(c.level, &c.message[..], to_internal(c.spans));
         }
-
-        ::__internal::with_sess(move |sess, _| {
-            errors::DiagnosticBuilder::new_diagnostic(&sess.span_diagnostic, diag).emit();
-        });
+        diag.emit();
     }
 }
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index e9d2d97..32c8130 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -28,40 +28,30 @@
        test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
 
 #![feature(nll)]
-#![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(lang_items)]
+#![feature(const_fn)]
+#![feature(extern_types)]
+#![feature(in_band_lifetimes)]
 #![feature(optin_builtin_traits)]
 #![feature(non_exhaustive)]
+#![feature(specialization)]
 
 #![recursion_limit="256"]
 
-extern crate syntax;
-extern crate syntax_pos;
-extern crate rustc_errors;
-extern crate rustc_data_structures;
-
 #[unstable(feature = "proc_macro_internals", issue = "27812")]
 #[doc(hidden)]
-pub mod rustc;
+pub mod bridge;
 
 mod diagnostic;
 
 #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
 pub use diagnostic::{Diagnostic, Level, MultiSpan};
 
+use std::{fmt, iter, mem};
 use std::ops::{Bound, RangeBounds};
-use std::{ascii, fmt, iter};
 use std::path::PathBuf;
-use rustc_data_structures::sync::Lrc;
 use std::str::FromStr;
 
-use syntax::errors::DiagnosticBuilder;
-use syntax::parse::{self, token};
-use syntax::symbol::Symbol;
-use syntax::tokenstream::{self, DelimSpan};
-use syntax_pos::{Pos, FileName, BytePos};
-
 /// The main type provided by this crate, representing an abstract stream of
 /// tokens, or, more specifically, a sequence of token trees.
 /// The type provide interfaces for iterating over those token trees and, conversely,
@@ -71,7 +61,7 @@
 /// and `#[proc_macro_derive]` definitions.
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
 #[derive(Clone)]
-pub struct TokenStream(tokenstream::TokenStream);
+pub struct TokenStream(bridge::client::TokenStream);
 
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
 impl !Send for TokenStream {}
@@ -94,7 +84,7 @@
     /// Returns an empty `TokenStream` containing no token trees.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn new() -> TokenStream {
-        TokenStream(tokenstream::TokenStream::empty())
+        TokenStream(bridge::client::TokenStream::new())
     }
 
     /// Checks if this `TokenStream` is empty.
@@ -116,11 +106,16 @@
     type Err = LexError;
 
     fn from_str(src: &str) -> Result<TokenStream, LexError> {
-        __internal::with_sess(|sess, data| {
-            Ok(__internal::token_stream_wrap(parse::parse_stream_from_source_str(
-                FileName::ProcMacroSourceCode, src.to_string(), sess, Some(data.call_site.0)
-            )))
-        })
+        Ok(TokenStream(bridge::client::TokenStream::from_str(src)))
+    }
+}
+
+// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for TokenStream {
+    fn to_string(&self) -> String {
+        self.0.to_string()
     }
 }
 
@@ -130,7 +125,7 @@
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
 impl fmt::Display for TokenStream {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.fmt(f)
+        f.write_str(&self.to_string())
     }
 }
 
@@ -150,7 +145,12 @@
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl From<TokenTree> for TokenStream {
     fn from(tree: TokenTree) -> TokenStream {
-        TokenStream(tree.to_internal())
+        TokenStream(bridge::client::TokenStream::from_token_tree(match tree {
+            TokenTree::Group(tt) => bridge::TokenTree::Group(tt.0),
+            TokenTree::Punct(tt) => bridge::TokenTree::Punct(tt.0),
+            TokenTree::Ident(tt) => bridge::TokenTree::Ident(tt.0),
+            TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0)
+        }))
     }
 }
 
@@ -167,7 +167,7 @@
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
 impl iter::FromIterator<TokenStream> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
-        let mut builder = tokenstream::TokenStreamBuilder::new();
+        let mut builder = bridge::client::TokenStreamBuilder::new();
         for stream in streams {
             builder.push(stream.0);
         }
@@ -185,52 +185,34 @@
 #[stable(feature = "token_stream_extend", since = "1.30.0")]
 impl Extend<TokenStream> for TokenStream {
     fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
-        self.0.extend(streams.into_iter().map(|stream| stream.0));
+        // FIXME(eddyb) Use an optimized implementation if/when possible.
+        *self = iter::once(mem::replace(self, Self::new())).chain(streams).collect();
     }
 }
 
 /// Public implementation details for the `TokenStream` type, such as iterators.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 pub mod token_stream {
-    use syntax::tokenstream;
-    use {TokenTree, TokenStream, Delimiter};
+    use {bridge, Group, Ident, Literal, Punct, TokenTree, TokenStream};
 
     /// An iterator over `TokenStream`'s `TokenTree`s.
     /// The iteration is "shallow", e.g. the iterator doesn't recurse into delimited groups,
     /// and returns whole groups as token trees.
     #[derive(Clone)]
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-    pub struct IntoIter {
-        cursor: tokenstream::Cursor,
-        stack: Vec<TokenTree>,
-    }
+    pub struct IntoIter(bridge::client::TokenStreamIter);
 
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     impl Iterator for IntoIter {
         type Item = TokenTree;
 
         fn next(&mut self) -> Option<TokenTree> {
-            loop {
-                let tree = self.stack.pop().or_else(|| {
-                    let next = self.cursor.next_as_stream()?;
-                    Some(TokenTree::from_internal(next, &mut self.stack))
-                })?;
-                // HACK: The condition "dummy span + group with empty delimiter" represents an AST
-                // fragment approximately converted into a token stream. This may happen, for
-                // example, with inputs to proc macro attributes, including derives. Such "groups"
-                // need to flattened during iteration over stream's token trees.
-                // Eventually this needs to be removed in favor of keeping original token trees
-                // and not doing the roundtrip through AST.
-                if tree.span().0.is_dummy() {
-                    if let TokenTree::Group(ref group) = tree {
-                        if group.delimiter() == Delimiter::None {
-                            self.cursor.insert(group.stream.clone().0);
-                            continue
-                        }
-                    }
-                }
-                return Some(tree);
-            }
+            self.0.next().map(|tree| match tree {
+                bridge::TokenTree::Group(tt) => TokenTree::Group(Group(tt)),
+                bridge::TokenTree::Punct(tt) => TokenTree::Punct(Punct(tt)),
+                bridge::TokenTree::Ident(tt) => TokenTree::Ident(Ident(tt)),
+                bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)),
+            })
         }
     }
 
@@ -240,7 +222,7 @@
         type IntoIter = IntoIter;
 
         fn into_iter(self) -> IntoIter {
-            IntoIter { cursor: self.0.trees(), stack: Vec::new() }
+            IntoIter(self.0.into_iter())
         }
     }
 }
@@ -264,7 +246,7 @@
 /// A region of source code, along with macro expansion information.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 #[derive(Copy, Clone)]
-pub struct Span(syntax_pos::Span);
+pub struct Span(bridge::client::Span);
 
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl !Send for Span {}
@@ -286,7 +268,7 @@
     /// A span that resolves at the macro definition site.
     #[unstable(feature = "proc_macro_def_site", issue = "54724")]
     pub fn def_site() -> Span {
-        ::__internal::with_sess(|_, data| data.def_site)
+        Span(bridge::client::Span::def_site())
     }
 
     /// The span of the invocation of the current procedural macro.
@@ -295,15 +277,13 @@
     /// at the macro call site will be able to refer to them as well.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn call_site() -> Span {
-        ::__internal::with_sess(|_, data| data.call_site)
+        Span(bridge::client::Span::call_site())
     }
 
     /// The original source file into which this span points.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn source_file(&self) -> SourceFile {
-        SourceFile {
-            source_file: __internal::lookup_char_pos(self.0.lo()).file,
-        }
+        SourceFile(self.0.source_file())
     }
 
     /// The `Span` for the tokens in the previous macro expansion from which
@@ -318,27 +298,19 @@
     /// value is the same as `*self`.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn source(&self) -> Span {
-        Span(self.0.source_callsite())
+        Span(self.0.source())
     }
 
     /// Get the starting line/column in the source file for this span.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn start(&self) -> LineColumn {
-        let loc = __internal::lookup_char_pos(self.0.lo());
-        LineColumn {
-            line: loc.line,
-            column: loc.col.to_usize()
-        }
+        self.0.start()
     }
 
     /// Get the ending line/column in the source file for this span.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn end(&self) -> LineColumn {
-        let loc = __internal::lookup_char_pos(self.0.hi());
-        LineColumn {
-            line: loc.line,
-            column: loc.col.to_usize()
-        }
+        self.0.end()
     }
 
     /// Create a new span encompassing `self` and `other`.
@@ -346,19 +318,14 @@
     /// Returns `None` if `self` and `other` are from different files.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn join(&self, other: Span) -> Option<Span> {
-        let self_loc = __internal::lookup_char_pos(self.0.lo());
-        let other_loc = __internal::lookup_char_pos(other.0.lo());
-
-        if self_loc.file.name != other_loc.file.name { return None }
-
-        Some(Span(self.0.to(other.0)))
+        self.0.join(other.0).map(Span)
     }
 
     /// Creates a new span with the same line/column information as `self` but
     /// that resolves symbols as though it were at `other`.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn resolved_at(&self, other: Span) -> Span {
-        Span(self.0.with_ctxt(other.0.ctxt()))
+        Span(self.0.resolved_at(other.0))
     }
 
     /// Creates a new span with the same name resolution behavior as `self` but
@@ -384,10 +351,7 @@
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Debug for Span {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{:?} bytes({}..{})",
-               self.0.ctxt(),
-               self.0.lo().0,
-               self.0.hi().0)
+        self.0.fmt(f)
     }
 }
 
@@ -412,14 +376,7 @@
 /// The source file of a given `Span`.
 #[unstable(feature = "proc_macro_span", issue = "54725")]
 #[derive(Clone)]
-pub struct SourceFile {
-    source_file: Lrc<syntax_pos::SourceFile>,
-}
-
-#[unstable(feature = "proc_macro_span", issue = "54725")]
-impl !Send for SourceFile {}
-#[unstable(feature = "proc_macro_span", issue = "54725")]
-impl !Sync for SourceFile {}
+pub struct SourceFile(bridge::client::SourceFile);
 
 impl SourceFile {
     /// Get the path to this source file.
@@ -434,10 +391,7 @@
     /// [`is_real`]: #method.is_real
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn path(&self) -> PathBuf {
-        match self.source_file.name {
-            FileName::Real(ref path) => path.clone(),
-            _ => PathBuf::from(self.source_file.name.to_string())
-        }
+        PathBuf::from(self.0.path())
     }
 
     /// Returns `true` if this source file is a real source file, and not generated by an external
@@ -447,7 +401,7 @@
         // This is a hack until intercrate spans are implemented and we can have real source files
         // for spans generated in external macros.
         // https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368
-        self.source_file.is_real_file()
+        self.0.is_real()
     }
 }
 
@@ -465,7 +419,7 @@
 #[unstable(feature = "proc_macro_span", issue = "54725")]
 impl PartialEq for SourceFile {
     fn eq(&self, other: &Self) -> bool {
-        Lrc::ptr_eq(&self.source_file, &other.source_file)
+        self.0.eq(&other.0)
     }
 }
 
@@ -579,18 +533,27 @@
     }
 }
 
+// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for TokenTree {
+    fn to_string(&self) -> String {
+        match *self {
+            TokenTree::Group(ref t) => t.to_string(),
+            TokenTree::Ident(ref t) => t.to_string(),
+            TokenTree::Punct(ref t) => t.to_string(),
+            TokenTree::Literal(ref t) => t.to_string(),
+        }
+    }
+}
+
 /// Prints the token tree as a string that is supposed to be losslessly convertible back
 /// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
 /// with `Delimiter::None` delimiters and negative numeric literals.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for TokenTree {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            TokenTree::Group(ref t) => t.fmt(f),
-            TokenTree::Ident(ref t) => t.fmt(f),
-            TokenTree::Punct(ref t) => t.fmt(f),
-            TokenTree::Literal(ref t) => t.fmt(f),
-        }
+        f.write_str(&self.to_string())
     }
 }
 
@@ -599,11 +562,7 @@
 /// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
 #[derive(Clone)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-pub struct Group {
-    delimiter: Delimiter,
-    stream: TokenStream,
-    span: DelimSpan,
-}
+pub struct Group(bridge::client::Group);
 
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl !Send for Group {}
@@ -640,17 +599,13 @@
     /// method below.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
-        Group {
-            delimiter: delimiter,
-            stream: stream,
-            span: DelimSpan::from_single(Span::call_site().0),
-        }
+        Group(bridge::client::Group::new(delimiter, stream.0))
     }
 
     /// Returns the delimiter of this `Group`
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn delimiter(&self) -> Delimiter {
-        self.delimiter
+        self.0.delimiter()
     }
 
     /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
@@ -659,7 +614,7 @@
     /// returned above.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn stream(&self) -> TokenStream {
-        self.stream.clone()
+        TokenStream(self.0.stream())
     }
 
     /// Returns the span for the delimiters of this token stream, spanning the
@@ -671,7 +626,7 @@
     /// ```
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        Span(self.span.entire())
+        Span(self.0.span())
     }
 
     /// Returns the span pointing to the opening delimiter of this group.
@@ -682,7 +637,7 @@
     /// ```
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn span_open(&self) -> Span {
-        Span(self.span.open)
+        Span(self.0.span_open())
     }
 
     /// Returns the span pointing to the closing delimiter of this group.
@@ -693,7 +648,7 @@
     /// ```
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn span_close(&self) -> Span {
-        Span(self.span.close)
+        Span(self.0.span_close())
     }
 
     /// Configures the span for this `Group`'s delimiters, but not its internal
@@ -704,7 +659,16 @@
     /// tokens at the level of the `Group`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn set_span(&mut self, span: Span) {
-        self.span = DelimSpan::from_single(span.0);
+        self.0.set_span(span.0);
+    }
+}
+
+// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for Group {
+    fn to_string(&self) -> String {
+        TokenStream::from(TokenTree::from(self.clone())).to_string()
     }
 }
 
@@ -714,7 +678,7 @@
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for Group {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        TokenStream::from(TokenTree::from(self.clone())).fmt(f)
+        f.write_str(&self.to_string())
     }
 }
 
@@ -735,11 +699,7 @@
 /// forms of `Spacing` returned.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 #[derive(Clone)]
-pub struct Punct {
-    ch: char,
-    spacing: Spacing,
-    span: Span,
-}
+pub struct Punct(bridge::client::Punct);
 
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl !Send for Punct {}
@@ -774,17 +734,13 @@
         if !LEGAL_CHARS.contains(&ch) {
             panic!("unsupported character `{:?}`", ch)
         }
-        Punct {
-            ch: ch,
-            spacing: spacing,
-            span: Span::call_site(),
-        }
+        Punct(bridge::client::Punct::new(ch, spacing))
     }
 
     /// Returns the value of this punctuation character as `char`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn as_char(&self) -> char {
-        self.ch
+        self.0.as_char()
     }
 
     /// Returns the spacing of this punctuation character, indicating whether it's immediately
@@ -793,19 +749,28 @@
     /// (`Alone`) so the operator has certainly ended.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn spacing(&self) -> Spacing {
-        self.spacing
+        self.0.spacing()
     }
 
     /// Returns the span for this punctuation character.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        self.span
+        Span(self.0.span())
     }
 
     /// Configure the span for this punctuation character.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn set_span(&mut self, span: Span) {
-        self.span = span;
+        self.0 = self.0.with_span(span.0);
+    }
+}
+
+// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for Punct {
+    fn to_string(&self) -> String {
+        TokenStream::from(TokenTree::from(self.clone())).to_string()
     }
 }
 
@@ -814,7 +779,7 @@
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for Punct {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        TokenStream::from(TokenTree::from(self.clone())).fmt(f)
+        f.write_str(&self.to_string())
     }
 }
 
@@ -832,16 +797,7 @@
 /// An identifier (`ident`).
 #[derive(Clone)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-pub struct Ident {
-    sym: Symbol,
-    span: Span,
-    is_raw: bool,
-}
-
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl !Send for Ident {}
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl !Sync for Ident {}
+pub struct Ident(bridge::client::Ident);
 
 impl Ident {
     fn is_valid(string: &str) -> bool {
@@ -878,7 +834,7 @@
         if !Ident::is_valid(string) {
             panic!("`{:?}` is not a valid identifier", string)
         }
-        Ident::new_maybe_raw(string, span, false)
+        Ident(bridge::client::Ident::new(string, span.0, false))
     }
 
     /// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
@@ -887,20 +843,29 @@
         if !Ident::is_valid(string) {
             panic!("`{:?}` is not a valid identifier", string)
         }
-        Ident::new_maybe_raw(string, span, true)
+        Ident(bridge::client::Ident::new(string, span.0, true))
     }
 
     /// Returns the span of this `Ident`, encompassing the entire string returned
     /// by `as_str`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        self.span
+        Span(self.0.span())
     }
 
     /// Configures the span of this `Ident`, possibly changing its hygiene context.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn set_span(&mut self, span: Span) {
-        self.span = span;
+        self.0 = self.0.with_span(span.0);
+    }
+}
+
+// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for Ident {
+    fn to_string(&self) -> String {
+        TokenStream::from(TokenTree::from(self.clone())).to_string()
     }
 }
 
@@ -909,7 +874,7 @@
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for Ident {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        TokenStream::from(TokenTree::from(self.clone())).fmt(f)
+        f.write_str(&self.to_string())
     }
 }
 
@@ -927,19 +892,9 @@
 /// character (`'a'`), byte character (`b'a'`), an integer or floating point number
 /// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
 /// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
-// FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
-#[derive(Clone, Debug)]
+#[derive(Clone)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-pub struct Literal {
-    lit: token::Lit,
-    suffix: Option<Symbol>,
-    span: Span,
-}
-
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl !Send for Literal {}
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl !Sync for Literal {}
+pub struct Literal(bridge::client::Literal);
 
 macro_rules! suffixed_int_literals {
     ($($name:ident => $kind:ident,)*) => ($(
@@ -956,11 +911,7 @@
         /// below.
         #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
         pub fn $name(n: $kind) -> Literal {
-            Literal {
-                lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
-                suffix: Some(Symbol::intern(stringify!($kind))),
-                span: Span::call_site(),
-            }
+            Literal(bridge::client::Literal::typed_integer(&n.to_string(), stringify!($kind)))
         }
     )*)
 }
@@ -982,11 +933,7 @@
         /// below.
         #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
         pub fn $name(n: $kind) -> Literal {
-            Literal {
-                lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
-                suffix: None,
-                span: Span::call_site(),
-            }
+            Literal(bridge::client::Literal::integer(&n.to_string()))
         }
     )*)
 }
@@ -1039,11 +986,7 @@
         if !n.is_finite() {
             panic!("Invalid float literal {}", n);
         }
-        Literal {
-            lit: token::Lit::Float(Symbol::intern(&n.to_string())),
-            suffix: None,
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::float(&n.to_string()))
     }
 
     /// Creates a new suffixed floating-point literal.
@@ -1064,11 +1007,7 @@
         if !n.is_finite() {
             panic!("Invalid float literal {}", n);
         }
-        Literal {
-            lit: token::Lit::Float(Symbol::intern(&n.to_string())),
-            suffix: Some(Symbol::intern("f32")),
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::f32(&n.to_string()))
     }
 
     /// Creates a new unsuffixed floating-point literal.
@@ -1088,11 +1027,7 @@
         if !n.is_finite() {
             panic!("Invalid float literal {}", n);
         }
-        Literal {
-            lit: token::Lit::Float(Symbol::intern(&n.to_string())),
-            suffix: None,
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::float(&n.to_string()))
     }
 
     /// Creates a new suffixed floating-point literal.
@@ -1113,61 +1048,37 @@
         if !n.is_finite() {
             panic!("Invalid float literal {}", n);
         }
-        Literal {
-            lit: token::Lit::Float(Symbol::intern(&n.to_string())),
-            suffix: Some(Symbol::intern("f64")),
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::f64(&n.to_string()))
     }
 
     /// String literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn string(string: &str) -> Literal {
-        let mut escaped = String::new();
-        for ch in string.chars() {
-            escaped.extend(ch.escape_debug());
-        }
-        Literal {
-            lit: token::Lit::Str_(Symbol::intern(&escaped)),
-            suffix: None,
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::string(string))
     }
 
     /// Character literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn character(ch: char) -> Literal {
-        let mut escaped = String::new();
-        escaped.extend(ch.escape_unicode());
-        Literal {
-            lit: token::Lit::Char(Symbol::intern(&escaped)),
-            suffix: None,
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::character(ch))
     }
 
     /// Byte string literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn byte_string(bytes: &[u8]) -> Literal {
-        let string = bytes.iter().cloned().flat_map(ascii::escape_default)
-            .map(Into::<char>::into).collect::<String>();
-        Literal {
-            lit: token::Lit::ByteStr(Symbol::intern(&string)),
-            suffix: None,
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::byte_string(bytes))
     }
 
     /// Returns the span encompassing this literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        self.span
+        Span(self.0.span())
     }
 
     /// Configures the span associated for this literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn set_span(&mut self, span: Span) {
-        self.span = span;
+        self.0.set_span(span.0);
     }
 
     /// Returns a `Span` that is a subset of `self.span()` containing only the
@@ -1183,35 +1094,28 @@
     // was 'c' or whether it was '\u{63}'.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
-        let inner = self.span().0;
-        let length = inner.hi().to_usize() - inner.lo().to_usize();
-
-        let start = match range.start_bound() {
-            Bound::Included(&lo) => lo,
-            Bound::Excluded(&lo) => lo + 1,
-            Bound::Unbounded => 0,
-        };
-
-        let end = match range.end_bound() {
-            Bound::Included(&hi) => hi + 1,
-            Bound::Excluded(&hi) => hi,
-            Bound::Unbounded => length,
-        };
-
-        // Bounds check the values, preventing addition overflow and OOB spans.
-        if start > u32::max_value() as usize
-            || end > u32::max_value() as usize
-            || (u32::max_value() - start as u32) < inner.lo().to_u32()
-            || (u32::max_value() - end as u32) < inner.lo().to_u32()
-            || start >= end
-            || end > length
-        {
-            return None;
+        // HACK(eddyb) something akin to `Option::cloned`, but for `Bound<&T>`.
+        fn cloned_bound<T: Clone>(bound: Bound<&T>) -> Bound<T> {
+            match bound {
+                Bound::Included(x) => Bound::Included(x.clone()),
+                Bound::Excluded(x) => Bound::Excluded(x.clone()),
+                Bound::Unbounded => Bound::Unbounded,
+            }
         }
 
-        let new_lo = inner.lo() + BytePos::from_usize(start);
-        let new_hi = inner.lo() + BytePos::from_usize(end);
-        Some(Span(inner.with_lo(new_lo).with_hi(new_hi)))
+        self.0.subspan(
+            cloned_bound(range.start_bound()),
+            cloned_bound(range.end_bound()),
+        ).map(Span)
+    }
+}
+
+// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for Literal {
+    fn to_string(&self) -> String {
+        TokenStream::from(TokenTree::from(self.clone())).to_string()
     }
 }
 
@@ -1220,149 +1124,14 @@
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for Literal {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        TokenStream::from(TokenTree::from(self.clone())).fmt(f)
+        f.write_str(&self.to_string())
     }
 }
 
-/// Permanently unstable internal implementation details of this crate. This
-/// should not be used.
-///
-/// These methods are used by the rest of the compiler to generate instances of
-/// `TokenStream` to hand to macro definitions, as well as consume the output.
-///
-/// Note that this module is also intentionally separate from the rest of the
-/// crate. This allows the `#[unstable]` directive below to naturally apply to
-/// all of the contents.
-#[unstable(feature = "proc_macro_internals", issue = "27812")]
-#[doc(hidden)]
-pub mod __internal {
-    use std::cell::Cell;
-    use std::ptr;
-
-    use syntax::ast;
-    use syntax::ext::base::ExtCtxt;
-    use syntax::ptr::P;
-    use syntax::parse::{self, ParseSess};
-    use syntax::parse::token::{self, Token};
-    use syntax::tokenstream;
-    use syntax_pos::{BytePos, Loc, DUMMY_SP};
-    use syntax_pos::hygiene::{SyntaxContext, Transparency};
-
-    use super::{TokenStream, LexError, Span};
-
-    pub fn lookup_char_pos(pos: BytePos) -> Loc {
-        with_sess(|sess, _| sess.source_map().lookup_char_pos(pos))
+#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
+impl fmt::Debug for Literal {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
+        self.0.fmt(f)
     }
-
-    pub fn new_token_stream(item: P<ast::Item>) -> TokenStream {
-        let token = Token::interpolated(token::NtItem(item));
-        TokenStream(tokenstream::TokenTree::Token(DUMMY_SP, token).into())
-    }
-
-    pub fn token_stream_wrap(inner: tokenstream::TokenStream) -> TokenStream {
-        TokenStream(inner)
-    }
-
-    pub fn token_stream_parse_items(stream: TokenStream) -> Result<Vec<P<ast::Item>>, LexError> {
-        with_sess(move |sess, _| {
-            let mut parser = parse::stream_to_parser(sess, stream.0);
-            let mut items = Vec::new();
-
-            while let Some(item) = try!(parser.parse_item().map_err(super::parse_to_lex_err)) {
-                items.push(item)
-            }
-
-            Ok(items)
-        })
-    }
-
-    pub fn token_stream_inner(stream: TokenStream) -> tokenstream::TokenStream {
-        stream.0
-    }
-
-    pub trait Registry {
-        fn register_custom_derive(&mut self,
-                                  trait_name: &str,
-                                  expand: fn(TokenStream) -> TokenStream,
-                                  attributes: &[&'static str]);
-
-        fn register_attr_proc_macro(&mut self,
-                                    name: &str,
-                                    expand: fn(TokenStream, TokenStream) -> TokenStream);
-
-        fn register_bang_proc_macro(&mut self,
-                                    name: &str,
-                                    expand: fn(TokenStream) -> TokenStream);
-    }
-
-    #[derive(Clone, Copy)]
-    pub struct ProcMacroData {
-        pub def_site: Span,
-        pub call_site: Span,
-    }
-
-    #[derive(Clone, Copy)]
-    struct ProcMacroSess {
-        parse_sess: *const ParseSess,
-        data: ProcMacroData,
-    }
-
-    // Emulate scoped_thread_local!() here essentially
-    thread_local! {
-        static CURRENT_SESS: Cell<ProcMacroSess> = Cell::new(ProcMacroSess {
-            parse_sess: ptr::null(),
-            data: ProcMacroData { def_site: Span(DUMMY_SP), call_site: Span(DUMMY_SP) },
-        });
-    }
-
-    pub fn set_sess<F, R>(cx: &ExtCtxt, f: F) -> R
-        where F: FnOnce() -> R
-    {
-        struct Reset { prev: ProcMacroSess }
-
-        impl Drop for Reset {
-            fn drop(&mut self) {
-                CURRENT_SESS.with(|p| p.set(self.prev));
-            }
-        }
-
-        CURRENT_SESS.with(|p| {
-            let _reset = Reset { prev: p.get() };
-
-            // No way to determine def location for a proc macro right now, so use call location.
-            let location = cx.current_expansion.mark.expn_info().unwrap().call_site;
-            let to_span = |transparency| Span(location.with_ctxt(
-                SyntaxContext::empty().apply_mark_with_transparency(cx.current_expansion.mark,
-                                                                    transparency))
-            );
-            p.set(ProcMacroSess {
-                parse_sess: cx.parse_sess,
-                data: ProcMacroData {
-                    def_site: to_span(Transparency::Opaque),
-                    call_site: to_span(Transparency::Transparent),
-                },
-            });
-            f()
-        })
-    }
-
-    pub fn in_sess() -> bool
-    {
-        !CURRENT_SESS.with(|sess| sess.get()).parse_sess.is_null()
-    }
-
-    pub fn with_sess<F, R>(f: F) -> R
-        where F: FnOnce(&ParseSess, &ProcMacroData) -> R
-    {
-        let sess = CURRENT_SESS.with(|sess| sess.get());
-        if sess.parse_sess.is_null() {
-            panic!("procedural macro API is used outside of a procedural macro");
-        }
-        f(unsafe { &*sess.parse_sess }, &sess.data)
-    }
-}
-
-fn parse_to_lex_err(mut err: DiagnosticBuilder) -> LexError {
-    err.cancel();
-    LexError { _inner: () }
 }
diff --git a/src/libproc_macro/rustc.rs b/src/libproc_macro/rustc.rs
deleted file mode 100644
index 3ce02d1a..0000000
--- a/src/libproc_macro/rustc.rs
+++ /dev/null
@@ -1,283 +0,0 @@
-// 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 {Delimiter, Level, Spacing, Span, __internal};
-use {Group, Ident, Literal, Punct, TokenTree};
-
-use rustc_errors as errors;
-use syntax::ast;
-use syntax::parse::lexer::comments;
-use syntax::parse::token;
-use syntax::tokenstream;
-use syntax_pos::symbol::{keywords, Symbol};
-
-impl Ident {
-    pub(crate) fn new_maybe_raw(string: &str, span: Span, is_raw: bool) -> Ident {
-        let sym = Symbol::intern(string);
-        if is_raw
-            && (sym == keywords::Underscore.name()
-                || ast::Ident::with_empty_ctxt(sym).is_path_segment_keyword())
-        {
-            panic!("`{:?}` is not a valid raw identifier", string)
-        }
-        Ident { sym, span, is_raw }
-    }
-}
-
-impl Delimiter {
-    pub(crate) fn from_internal(delim: token::DelimToken) -> Delimiter {
-        match delim {
-            token::Paren => Delimiter::Parenthesis,
-            token::Brace => Delimiter::Brace,
-            token::Bracket => Delimiter::Bracket,
-            token::NoDelim => Delimiter::None,
-        }
-    }
-
-    pub(crate) fn to_internal(self) -> token::DelimToken {
-        match self {
-            Delimiter::Parenthesis => token::Paren,
-            Delimiter::Brace => token::Brace,
-            Delimiter::Bracket => token::Bracket,
-            Delimiter::None => token::NoDelim,
-        }
-    }
-}
-
-impl TokenTree {
-    pub(crate) fn from_internal(
-        stream: tokenstream::TokenStream,
-        stack: &mut Vec<TokenTree>,
-    ) -> TokenTree {
-        use syntax::parse::token::*;
-
-        let (tree, is_joint) = stream.as_tree();
-        let (span, token) = match tree {
-            tokenstream::TokenTree::Token(span, token) => (span, token),
-            tokenstream::TokenTree::Delimited(span, delimed) => {
-                let delimiter = Delimiter::from_internal(delimed.delim);
-                let mut g = Group::new(delimiter, ::TokenStream(delimed.tts.into()));
-                g.span = span;
-                return g.into();
-            }
-        };
-
-        let op_kind = if is_joint {
-            Spacing::Joint
-        } else {
-            Spacing::Alone
-        };
-        macro_rules! tt {
-            ($e:expr) => {{
-                let mut x = TokenTree::from($e);
-                x.set_span(Span(span));
-                x
-            }};
-        }
-        macro_rules! op {
-            ($a:expr) => {
-                tt!(Punct::new($a, op_kind))
-            };
-            ($a:expr, $b:expr) => {{
-                stack.push(tt!(Punct::new($b, op_kind)));
-                tt!(Punct::new($a, Spacing::Joint))
-            }};
-            ($a:expr, $b:expr, $c:expr) => {{
-                stack.push(tt!(Punct::new($c, op_kind)));
-                stack.push(tt!(Punct::new($b, Spacing::Joint)));
-                tt!(Punct::new($a, Spacing::Joint))
-            }};
-        }
-
-        match token {
-            Eq => op!('='),
-            Lt => op!('<'),
-            Le => op!('<', '='),
-            EqEq => op!('=', '='),
-            Ne => op!('!', '='),
-            Ge => op!('>', '='),
-            Gt => op!('>'),
-            AndAnd => op!('&', '&'),
-            OrOr => op!('|', '|'),
-            Not => op!('!'),
-            Tilde => op!('~'),
-            BinOp(Plus) => op!('+'),
-            BinOp(Minus) => op!('-'),
-            BinOp(Star) => op!('*'),
-            BinOp(Slash) => op!('/'),
-            BinOp(Percent) => op!('%'),
-            BinOp(Caret) => op!('^'),
-            BinOp(And) => op!('&'),
-            BinOp(Or) => op!('|'),
-            BinOp(Shl) => op!('<', '<'),
-            BinOp(Shr) => op!('>', '>'),
-            BinOpEq(Plus) => op!('+', '='),
-            BinOpEq(Minus) => op!('-', '='),
-            BinOpEq(Star) => op!('*', '='),
-            BinOpEq(Slash) => op!('/', '='),
-            BinOpEq(Percent) => op!('%', '='),
-            BinOpEq(Caret) => op!('^', '='),
-            BinOpEq(And) => op!('&', '='),
-            BinOpEq(Or) => op!('|', '='),
-            BinOpEq(Shl) => op!('<', '<', '='),
-            BinOpEq(Shr) => op!('>', '>', '='),
-            At => op!('@'),
-            Dot => op!('.'),
-            DotDot => op!('.', '.'),
-            DotDotDot => op!('.', '.', '.'),
-            DotDotEq => op!('.', '.', '='),
-            Comma => op!(','),
-            Semi => op!(';'),
-            Colon => op!(':'),
-            ModSep => op!(':', ':'),
-            RArrow => op!('-', '>'),
-            LArrow => op!('<', '-'),
-            FatArrow => op!('=', '>'),
-            Pound => op!('#'),
-            Dollar => op!('$'),
-            Question => op!('?'),
-            SingleQuote => op!('\''),
-
-            Ident(ident, false) => tt!(self::Ident::new(&ident.as_str(), Span(span))),
-            Ident(ident, true) => tt!(self::Ident::new_raw(&ident.as_str(), Span(span))),
-            Lifetime(ident) => {
-                let ident = ident.without_first_quote();
-                stack.push(tt!(self::Ident::new(&ident.as_str(), Span(span))));
-                tt!(Punct::new('\'', Spacing::Joint))
-            }
-            Literal(lit, suffix) => tt!(self::Literal {
-                lit,
-                suffix,
-                span: Span(span)
-            }),
-            DocComment(c) => {
-                let style = comments::doc_comment_style(&c.as_str());
-                let stripped = comments::strip_doc_comment_decoration(&c.as_str());
-                let stream = vec![
-                    tt!(self::Ident::new("doc", Span(span))),
-                    tt!(Punct::new('=', Spacing::Alone)),
-                    tt!(self::Literal::string(&stripped)),
-                ].into_iter()
-                    .collect();
-                stack.push(tt!(Group::new(Delimiter::Bracket, stream)));
-                if style == ast::AttrStyle::Inner {
-                    stack.push(tt!(Punct::new('!', Spacing::Alone)));
-                }
-                tt!(Punct::new('#', Spacing::Alone))
-            }
-
-            Interpolated(_) => __internal::with_sess(|sess, _| {
-                let tts = token.interpolated_to_tokenstream(sess, span);
-                tt!(Group::new(Delimiter::None, ::TokenStream(tts)))
-            }),
-
-            DotEq => op!('.', '='),
-            OpenDelim(..) | CloseDelim(..) => unreachable!(),
-            Whitespace | Comment | Shebang(..) | Eof => unreachable!(),
-        }
-    }
-
-    pub(crate) fn to_internal(self) -> tokenstream::TokenStream {
-        use syntax::parse::token::*;
-        use syntax::tokenstream::{Delimited, TokenTree};
-
-        let (ch, kind, span) = match self {
-            self::TokenTree::Punct(tt) => (tt.as_char(), tt.spacing(), tt.span()),
-            self::TokenTree::Group(tt) => {
-                return TokenTree::Delimited(
-                    tt.span,
-                    Delimited {
-                        delim: tt.delimiter.to_internal(),
-                        tts: tt.stream.0.into(),
-                    },
-                ).into();
-            }
-            self::TokenTree::Ident(tt) => {
-                let token = Ident(ast::Ident::new(tt.sym, tt.span.0), tt.is_raw);
-                return TokenTree::Token(tt.span.0, token).into();
-            }
-            self::TokenTree::Literal(self::Literal {
-                lit: Lit::Integer(ref a),
-                suffix,
-                span,
-            })
-                if a.as_str().starts_with("-") =>
-            {
-                let minus = BinOp(BinOpToken::Minus);
-                let integer = Symbol::intern(&a.as_str()[1..]);
-                let integer = Literal(Lit::Integer(integer), suffix);
-                let a = TokenTree::Token(span.0, minus);
-                let b = TokenTree::Token(span.0, integer);
-                return vec![a, b].into_iter().collect();
-            }
-            self::TokenTree::Literal(self::Literal {
-                lit: Lit::Float(ref a),
-                suffix,
-                span,
-            })
-                if a.as_str().starts_with("-") =>
-            {
-                let minus = BinOp(BinOpToken::Minus);
-                let float = Symbol::intern(&a.as_str()[1..]);
-                let float = Literal(Lit::Float(float), suffix);
-                let a = TokenTree::Token(span.0, minus);
-                let b = TokenTree::Token(span.0, float);
-                return vec![a, b].into_iter().collect();
-            }
-            self::TokenTree::Literal(tt) => {
-                let token = Literal(tt.lit, tt.suffix);
-                return TokenTree::Token(tt.span.0, token).into();
-            }
-        };
-
-        let token = match ch {
-            '=' => Eq,
-            '<' => Lt,
-            '>' => Gt,
-            '!' => Not,
-            '~' => Tilde,
-            '+' => BinOp(Plus),
-            '-' => BinOp(Minus),
-            '*' => BinOp(Star),
-            '/' => BinOp(Slash),
-            '%' => BinOp(Percent),
-            '^' => BinOp(Caret),
-            '&' => BinOp(And),
-            '|' => BinOp(Or),
-            '@' => At,
-            '.' => Dot,
-            ',' => Comma,
-            ';' => Semi,
-            ':' => Colon,
-            '#' => Pound,
-            '$' => Dollar,
-            '?' => Question,
-            '\'' => SingleQuote,
-            _ => unreachable!(),
-        };
-
-        let tree = TokenTree::Token(span.0, token);
-        match kind {
-            Spacing::Alone => tree.into(),
-            Spacing::Joint => tree.joint(),
-        }
-    }
-}
-
-impl Level {
-    pub(crate) fn to_internal(self) -> errors::Level {
-        match self {
-            Level::Error => errors::Level::Error,
-            Level::Warning => errors::Level::Warning,
-            Level::Note => errors::Level::Note,
-            Level::Help => errors::Level::Help,
-        }
-    }
-}
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index d0ec864..3316735 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -18,7 +18,6 @@
 scoped-tls = { version = "0.1.1", features = ["nightly"] }
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
 polonius-engine = "0.5.0"
-proc_macro = { path = "../libproc_macro" }
 rustc-rayon = "0.1.1"
 rustc-rayon-core = "0.1.1"
 rustc_apfloat = { path = "../librustc_apfloat" }
diff --git a/src/librustc/README.md b/src/librustc/README.md
index 9909ff9..c0e5c54 100644
--- a/src/librustc/README.md
+++ b/src/librustc/README.md
@@ -1,3 +1,3 @@
 For more information about how rustc works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
+[rustc guide]: https://rust-lang.github.io/rustc-guide/
diff --git a/src/librustc/dep_graph/README.md b/src/librustc/dep_graph/README.md
index f1f383d..91a06e4 100644
--- a/src/librustc/dep_graph/README.md
+++ b/src/librustc/dep_graph/README.md
@@ -1,4 +1,4 @@
 To learn more about how dependency tracking works in rustc, see the [rustc
 guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/query.html
+[rustc guide]: https://rust-lang.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 3ff2545..a20d049 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -381,7 +381,7 @@
         #[allow(dead_code, non_upper_case_globals)]
         pub mod label_strs {
            $(
-                pub const $variant: &'static str = stringify!($variant);
+                pub const $variant: &str = stringify!($variant);
             )*
         }
     );
@@ -596,7 +596,7 @@
     [] ReachableNonGenerics(CrateNum),
     [] NativeLibraries(CrateNum),
     [] PluginRegistrarFn(CrateNum),
-    [] DeriveRegistrarFn(CrateNum),
+    [] ProcMacroDeclsStatic(CrateNum),
     [input] CrateDisambiguator(CrateNum),
     [input] CrateHash(CrateNum),
     [input] OriginalCrateName(CrateNum),
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 63b749c..4c94c99 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -195,7 +195,7 @@
     /// - If you need 3+ arguments, use a tuple for the
     ///   `arg` parameter.
     ///
-    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/incremental-compilation.html
+    /// [rustc guide]: https://rust-lang.github.io/rustc-guide/incremental-compilation.html
     pub fn with_task<'gcx, C, A, R>(&self,
                                    key: DepNode,
                                    cx: C,
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index b3ba296..a485af0 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -67,7 +67,6 @@
 use syntax::ast::*;
 use syntax::errors;
 use syntax::ext::hygiene::{Mark, SyntaxContext};
-use syntax::feature_gate::{emit_feature_err, GateIssue};
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::source_map::{self, respan, CompilerDesugaringKind, Spanned};
@@ -1202,7 +1201,7 @@
                 None,
                 P(hir::Path {
                     def: self.expect_full_def(t.id),
-                    segments: hir_vec![hir::PathSegment::from_ident(keywords::SelfType.ident())],
+                    segments: hir_vec![hir::PathSegment::from_ident(keywords::SelfUpper.ident())],
                     span: t.span,
                 }),
             )),
@@ -2426,7 +2425,7 @@
                 // Don't expose `Self` (recovered "keyword used as ident" parse error).
                 // `rustc::ty` expects `Self` to be only used for a trait's `Self`.
                 // Instead, use gensym("Self") to create a distinct name that looks the same.
-                let ident = if param.ident.name == keywords::SelfType.name() {
+                let ident = if param.ident.name == keywords::SelfUpper.name() {
                     param.ident.gensym()
                 } else {
                     param.ident
@@ -2982,7 +2981,7 @@
 
                 // Correctly resolve `self` imports
                 if path.segments.len() > 1
-                    && path.segments.last().unwrap().ident.name == keywords::SelfValue.name()
+                    && path.segments.last().unwrap().ident.name == keywords::SelfLower.name()
                 {
                     let _ = path.segments.pop();
                     if rename.is_none() {
@@ -3628,7 +3627,6 @@
                     ParamMode::Optional,
                     ImplTraitContext::disallowed(),
                 );
-                self.check_self_struct_ctor_feature(&qpath);
                 hir::PatKind::TupleStruct(
                     qpath,
                     pats.iter().map(|x| self.lower_pat(x)).collect(),
@@ -3643,7 +3641,6 @@
                     ParamMode::Optional,
                     ImplTraitContext::disallowed(),
                 );
-                self.check_self_struct_ctor_feature(&qpath);
                 hir::PatKind::Path(qpath)
             }
             PatKind::Struct(ref path, ref fields, etc) => {
@@ -4039,7 +4036,6 @@
                     ParamMode::Optional,
                     ImplTraitContext::disallowed(),
                 );
-                self.check_self_struct_ctor_feature(&qpath);
                 hir::ExprKind::Path(qpath)
             }
             ExprKind::Break(opt_label, ref opt_expr) => {
@@ -5102,18 +5098,6 @@
                                             ThinVec::new()));
         P(self.expr_call(e.span, from_err, hir_vec![e]))
     }
-
-    fn check_self_struct_ctor_feature(&self, qp: &hir::QPath) {
-        if let hir::QPath::Resolved(_, ref p) = qp {
-            if p.segments.len() == 1 &&
-               p.segments[0].ident.name == keywords::SelfType.name() &&
-               !self.sess.features_untracked().self_struct_ctor {
-                emit_feature_err(&self.sess.parse_sess, "self_struct_ctor",
-                                 p.span, GateIssue::Language,
-                                 "`Self` struct constructors are unstable");
-            }
-        }
-    }
 }
 
 fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index ef777ab..4ac07d7 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -475,7 +475,7 @@
 
     pub fn ty_param_name(&self, id: NodeId) -> Name {
         match self.get(id) {
-            Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfType.name(),
+            Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfUpper.name(),
             Node::GenericParam(param) => param.name.ident().name,
             _ => bug!("ty_param_name: {} not a type parameter", self.node_to_string(id)),
         }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index e28193b..85bf257 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -311,7 +311,7 @@
 
 impl Path {
     pub fn is_global(&self) -> bool {
-        !self.segments.is_empty() && self.segments[0].ident.name == keywords::CrateRoot.name()
+        !self.segments.is_empty() && self.segments[0].ident.name == keywords::PathRoot.name()
     }
 }
 
@@ -689,7 +689,7 @@
 ///
 /// For more details, see the [rustc guide].
 ///
-/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/hir.html
+/// [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Crate {
     pub module: Mod,
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index e69d32a..484722f 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -25,6 +25,7 @@
 use hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd};
 use hir::{GenericParam, GenericParamKind, GenericArg};
 
+use std::borrow::Cow;
 use std::cell::Cell;
 use std::io::{self, Write, Read};
 use std::iter::Peekable;
@@ -64,7 +65,7 @@
 
 pub struct NoAnn;
 impl PpAnn for NoAnn {}
-pub const NO_ANN: &'static dyn PpAnn = &NoAnn;
+pub const NO_ANN: &dyn PpAnn = &NoAnn;
 
 impl PpAnn for hir::Crate {
     fn try_fetch_item(&self, item: ast::NodeId) -> Option<&hir::Item> {
@@ -209,7 +210,7 @@
     String::from_utf8(wr).unwrap()
 }
 
-pub fn visibility_qualified(vis: &hir::Visibility, w: &str) -> String {
+pub fn visibility_qualified<S: Into<Cow<'static, str>>>(vis: &hir::Visibility, w: S) -> String {
     to_string(NO_ANN, |s| {
         s.print_visibility(vis)?;
         s.s.word(w)
@@ -226,12 +227,13 @@
         self.s.word(" ")
     }
 
-    pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> {
+    pub fn word_nbsp<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
         self.s.word(w)?;
         self.nbsp()
     }
 
-    pub fn head(&mut self, w: &str) -> io::Result<()> {
+    pub fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
+        let w = w.into();
         // outer-box is consistent
         self.cbox(indent_unit)?;
         // head-box is inconsistent
@@ -303,7 +305,7 @@
     pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
         self.s.word("/*")?;
         self.s.space()?;
-        self.s.word(&text[..])?;
+        self.s.word(text)?;
         self.s.space()?;
         self.s.word("*/")
     }
@@ -468,7 +470,7 @@
                 self.end() // end the outer fn box
             }
             hir::ForeignItemKind::Static(ref t, m) => {
-                self.head(&visibility_qualified(&item.vis, "static"))?;
+                self.head(visibility_qualified(&item.vis, "static"))?;
                 if m {
                     self.word_space("mut")?;
                 }
@@ -480,7 +482,7 @@
                 self.end() // end the outer cbox
             }
             hir::ForeignItemKind::Type => {
-                self.head(&visibility_qualified(&item.vis, "type"))?;
+                self.head(visibility_qualified(&item.vis, "type"))?;
                 self.print_name(item.name)?;
                 self.s.word(";")?;
                 self.end()?; // end the head-ibox
@@ -495,7 +497,7 @@
                               default: Option<hir::BodyId>,
                               vis: &hir::Visibility)
                               -> io::Result<()> {
-        self.s.word(&visibility_qualified(vis, ""))?;
+        self.s.word(visibility_qualified(vis, ""))?;
         self.word_space("const")?;
         self.print_ident(ident)?;
         self.word_space(":")?;
@@ -534,7 +536,7 @@
         self.ann.pre(self, AnnNode::Item(item))?;
         match item.node {
             hir::ItemKind::ExternCrate(orig_name) => {
-                self.head(&visibility_qualified(&item.vis, "extern crate"))?;
+                self.head(visibility_qualified(&item.vis, "extern crate"))?;
                 if let Some(orig_name) = orig_name {
                     self.print_name(orig_name)?;
                     self.s.space()?;
@@ -547,7 +549,7 @@
                 self.end()?; // end outer head-block
             }
             hir::ItemKind::Use(ref path, kind) => {
-                self.head(&visibility_qualified(&item.vis, "use"))?;
+                self.head(visibility_qualified(&item.vis, "use"))?;
                 self.print_path(path, false)?;
 
                 match kind {
@@ -566,7 +568,7 @@
                 self.end()?; // end outer head-block
             }
             hir::ItemKind::Static(ref ty, m, expr) => {
-                self.head(&visibility_qualified(&item.vis, "static"))?;
+                self.head(visibility_qualified(&item.vis, "static"))?;
                 if m == hir::MutMutable {
                     self.word_space("mut")?;
                 }
@@ -582,7 +584,7 @@
                 self.end()?; // end the outer cbox
             }
             hir::ItemKind::Const(ref ty, expr) => {
-                self.head(&visibility_qualified(&item.vis, "const"))?;
+                self.head(visibility_qualified(&item.vis, "const"))?;
                 self.print_name(item.name)?;
                 self.word_space(":")?;
                 self.print_type(&ty)?;
@@ -609,7 +611,7 @@
                 self.ann.nested(self, Nested::Body(body))?;
             }
             hir::ItemKind::Mod(ref _mod) => {
-                self.head(&visibility_qualified(&item.vis, "mod"))?;
+                self.head(visibility_qualified(&item.vis, "mod"))?;
                 self.print_name(item.name)?;
                 self.nbsp()?;
                 self.bopen()?;
@@ -618,18 +620,18 @@
             }
             hir::ItemKind::ForeignMod(ref nmod) => {
                 self.head("extern")?;
-                self.word_nbsp(&nmod.abi.to_string())?;
+                self.word_nbsp(nmod.abi.to_string())?;
                 self.bopen()?;
                 self.print_foreign_mod(nmod, &item.attrs)?;
                 self.bclose(item.span)?;
             }
             hir::ItemKind::GlobalAsm(ref ga) => {
-                self.head(&visibility_qualified(&item.vis, "global asm"))?;
-                self.s.word(&ga.asm.as_str())?;
+                self.head(visibility_qualified(&item.vis, "global asm"))?;
+                self.s.word(ga.asm.as_str().get())?;
                 self.end()?
             }
             hir::ItemKind::Ty(ref ty, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "type"))?;
+                self.head(visibility_qualified(&item.vis, "type"))?;
                 self.print_name(item.name)?;
                 self.print_generic_params(&generics.params)?;
                 self.end()?; // end the inner ibox
@@ -642,7 +644,7 @@
                 self.end()?; // end the outer ibox
             }
             hir::ItemKind::Existential(ref exist) => {
-                self.head(&visibility_qualified(&item.vis, "existential type"))?;
+                self.head(visibility_qualified(&item.vis, "existential type"))?;
                 self.print_name(item.name)?;
                 self.print_generic_params(&exist.generics.params)?;
                 self.end()?; // end the inner ibox
@@ -668,11 +670,11 @@
                 self.print_enum_def(enum_definition, params, item.name, item.span, &item.vis)?;
             }
             hir::ItemKind::Struct(ref struct_def, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "struct"))?;
+                self.head(visibility_qualified(&item.vis, "struct"))?;
                 self.print_struct(struct_def, generics, item.name, item.span, true)?;
             }
             hir::ItemKind::Union(ref struct_def, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "union"))?;
+                self.head(visibility_qualified(&item.vis, "union"))?;
                 self.print_struct(struct_def, generics, item.name, item.span, true)?;
             }
             hir::ItemKind::Impl(unsafety,
@@ -795,7 +797,7 @@
                           span: syntax_pos::Span,
                           visibility: &hir::Visibility)
                           -> io::Result<()> {
-        self.head(&visibility_qualified(visibility, "enum"))?;
+        self.head(visibility_qualified(visibility, "enum"))?;
         self.print_name(name)?;
         self.print_generic_params(&generics.params)?;
         self.print_where_clause(&generics.where_clause)?;
@@ -1587,14 +1589,14 @@
     }
 
     pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
-        self.s.word(&i.to_string())
+        self.s.word(i.to_string())
     }
 
     pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
         if ident.is_raw_guess() {
-            self.s.word(&format!("r#{}", ident.name))?;
+            self.s.word(format!("r#{}", ident.name))?;
         } else {
-            self.s.word(&ident.as_str())?;
+            self.s.word(ident.as_str().get())?;
         }
         self.ann.post(self, AnnNode::Name(&ident.name))
     }
@@ -1620,7 +1622,7 @@
             if i > 0 {
                 self.s.word("::")?
             }
-            if segment.ident.name != keywords::CrateRoot.name() &&
+            if segment.ident.name != keywords::PathRoot.name() &&
                segment.ident.name != keywords::DollarCrate.name() {
                self.print_ident(segment.ident)?;
                segment.with_generic_args(|generic_args| {
@@ -1634,7 +1636,7 @@
     }
 
     pub fn print_path_segment(&mut self, segment: &hir::PathSegment) -> io::Result<()> {
-        if segment.ident.name != keywords::CrateRoot.name() &&
+        if segment.ident.name != keywords::PathRoot.name() &&
            segment.ident.name != keywords::DollarCrate.name() {
            self.print_ident(segment.ident)?;
            segment.with_generic_args(|generic_args| {
@@ -1662,7 +1664,7 @@
                     if i > 0 {
                         self.s.word("::")?
                     }
-                    if segment.ident.name != keywords::CrateRoot.name() &&
+                    if segment.ident.name != keywords::PathRoot.name() &&
                        segment.ident.name != keywords::DollarCrate.name() {
                         self.print_ident(segment.ident)?;
                         segment.with_generic_args(|generic_args| {
@@ -2010,7 +2012,7 @@
         self.commasep(Inconsistent, &decl.inputs, |s, ty| {
             s.ibox(indent_unit)?;
             if let Some(arg_name) = arg_names.get(i) {
-                s.s.word(&arg_name.as_str())?;
+                s.s.word(arg_name.as_str().get())?;
                 s.s.word(":")?;
                 s.s.space()?;
             } else if let Some(body_id) = body_id {
@@ -2073,7 +2075,8 @@
         }
     }
 
-    pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::GenericBound]) -> io::Result<()> {
+    pub fn print_bounds(&mut self, prefix: &'static str, bounds: &[hir::GenericBound])
+                        -> io::Result<()> {
         if !bounds.is_empty() {
             self.s.word(prefix)?;
             let mut first = true;
@@ -2322,7 +2325,7 @@
             Some(Abi::Rust) => Ok(()),
             Some(abi) => {
                 self.word_nbsp("extern")?;
-                self.word_nbsp(&abi.to_string())
+                self.word_nbsp(abi.to_string())
             }
             None => Ok(()),
         }
@@ -2332,7 +2335,7 @@
         match opt_abi {
             Some(abi) => {
                 self.word_nbsp("extern")?;
-                self.word_nbsp(&abi.to_string())
+                self.word_nbsp(abi.to_string())
             }
             None => Ok(()),
         }
@@ -2342,7 +2345,7 @@
                                 header: hir::FnHeader,
                                 vis: &hir::Visibility)
                                 -> io::Result<()> {
-        self.s.word(&visibility_qualified(vis, ""))?;
+        self.s.word(visibility_qualified(vis, ""))?;
 
         match header.constness {
             hir::Constness::NotConst => {}
@@ -2358,7 +2361,7 @@
 
         if header.abi != Abi::Rust {
             self.word_nbsp("extern")?;
-            self.word_nbsp(&header.abi.to_string())?;
+            self.word_nbsp(header.abi.to_string())?;
         }
 
         self.s.word("fn")
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index d98bb82..c728871 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -46,7 +46,8 @@
 
 impl_stable_hash_for!(enum mir::UnsafetyViolationKind {
     General,
-    MinConstFn,
+    GeneralAndConstFn,
+    GatedConstFnCall,
     ExternStatic(lint_node_id),
     BorrowPacked(lint_node_id),
 });
@@ -193,51 +194,18 @@
 
 impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for mir::StatementKind<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            mir::StatementKind::Assign(ref place, ref rvalue) => {
-                place.hash_stable(hcx, hasher);
-                rvalue.hash_stable(hcx, hasher);
-            }
-            mir::StatementKind::FakeRead(ref cause, ref place) => {
-                cause.hash_stable(hcx, hasher);
-                place.hash_stable(hcx, hasher);
-            }
-            mir::StatementKind::SetDiscriminant { ref place, variant_index } => {
-                place.hash_stable(hcx, hasher);
-                variant_index.hash_stable(hcx, hasher);
-            }
-            mir::StatementKind::StorageLive(ref place) |
-            mir::StatementKind::StorageDead(ref place) => {
-                place.hash_stable(hcx, hasher);
-            }
-            mir::StatementKind::EscapeToRaw(ref place) => {
-                place.hash_stable(hcx, hasher);
-            }
-            mir::StatementKind::Retag { fn_entry, ref place } => {
-                fn_entry.hash_stable(hcx, hasher);
-                place.hash_stable(hcx, hasher);
-            }
-            mir::StatementKind::AscribeUserType(ref place, ref variance, ref c_ty) => {
-                place.hash_stable(hcx, hasher);
-                variance.hash_stable(hcx, hasher);
-                c_ty.hash_stable(hcx, hasher);
-            }
-            mir::StatementKind::Nop => {}
-            mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
-                asm.hash_stable(hcx, hasher);
-                outputs.hash_stable(hcx, hasher);
-                inputs.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
+impl_stable_hash_for!(impl<'gcx> for enum mir::StatementKind<'gcx> [ mir::StatementKind ] {
+    Assign(place, rvalue),
+    FakeRead(cause, place),
+    SetDiscriminant { place, variant_index },
+    StorageLive(place),
+    StorageDead(place),
+    EscapeToRaw(place),
+    Retag { fn_entry, two_phase, place },
+    AscribeUserType(place, variance, c_ty),
+    Nop,
+    InlineAsm { asm, outputs, inputs },
+});
 
 impl_stable_hash_for!(enum mir::FakeReadCause { ForMatchGuard, ForMatchedPlace, ForLet });
 
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 4be467c..db643e4 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -134,14 +134,10 @@
     const_stability
 });
 
-impl<'a> HashStable<StableHashingContext<'a>>
-for ::syntax::edition::Edition {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-    }
-}
+impl_stable_hash_for!(enum ::syntax::edition::Edition {
+    Edition2015,
+    Edition2018,
+});
 
 impl<'a> HashStable<StableHashingContext<'a>>
 for ::syntax::attr::StabilityLevel {
@@ -314,7 +310,6 @@
         token::Token::DotDot |
         token::Token::DotDotDot |
         token::Token::DotDotEq |
-        token::Token::DotEq |
         token::Token::Comma |
         token::Token::Semi |
         token::Token::Colon |
@@ -418,13 +413,14 @@
 impl_stable_hash_for!(enum ::syntax_pos::FileName {
     Real(pb),
     Macros(s),
-    QuoteExpansion,
-    Anon,
-    MacroExpansion,
-    ProcMacroSourceCode,
-    CliCrateAttr,
-    CfgSpec,
-    Custom(s)
+    QuoteExpansion(s),
+    Anon(s),
+    MacroExpansion(s),
+    ProcMacroSourceCode(s),
+    CliCrateAttr(s),
+    CfgSpec(s),
+    Custom(s),
+    DocTest(pb, line),
 });
 
 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs
index 9751c56..fc2f1ee 100644
--- a/src/librustc/ich/mod.rs
+++ b/src/librustc/ich/mod.rs
@@ -24,15 +24,15 @@
 mod impls_ty;
 mod impls_syntax;
 
-pub const ATTR_DIRTY: &'static str = "rustc_dirty";
-pub const ATTR_CLEAN: &'static str = "rustc_clean";
-pub const ATTR_IF_THIS_CHANGED: &'static str = "rustc_if_this_changed";
-pub const ATTR_THEN_THIS_WOULD_NEED: &'static str = "rustc_then_this_would_need";
-pub const ATTR_PARTITION_REUSED: &'static str = "rustc_partition_reused";
-pub const ATTR_PARTITION_CODEGENED: &'static str = "rustc_partition_codegened";
-pub const ATTR_EXPECTED_CGU_REUSE: &'static str = "rustc_expected_cgu_reuse";
+pub const ATTR_DIRTY: &str = "rustc_dirty";
+pub const ATTR_CLEAN: &str = "rustc_clean";
+pub const ATTR_IF_THIS_CHANGED: &str = "rustc_if_this_changed";
+pub const ATTR_THEN_THIS_WOULD_NEED: &str = "rustc_then_this_would_need";
+pub const ATTR_PARTITION_REUSED: &str = "rustc_partition_reused";
+pub const ATTR_PARTITION_CODEGENED: &str = "rustc_partition_codegened";
+pub const ATTR_EXPECTED_CGU_REUSE: &str = "rustc_expected_cgu_reuse";
 
-pub const IGNORED_ATTRIBUTES: &'static [&'static str] = &[
+pub const IGNORED_ATTRIBUTES: &[&str] = &[
     "cfg",
     ATTR_IF_THIS_CHANGED,
     ATTR_THEN_THIS_WOULD_NEED,
diff --git a/src/librustc/infer/at.rs b/src/librustc/infer/at.rs
index 0e4c94a..70e922c 100644
--- a/src/librustc/infer/at.rs
+++ b/src/librustc/infer/at.rs
@@ -52,6 +52,7 @@
 }
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+    #[inline]
     pub fn at(&'a self,
               cause: &'a ObligationCause<'tcx>,
               param_env: ty::ParamEnv<'tcx>)
diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs
index 406a36e..54bfe90 100644
--- a/src/librustc/infer/canonical/canonicalizer.rs
+++ b/src/librustc/infer/canonical/canonicalizer.rs
@@ -13,7 +13,7 @@
 //! For an overview of what canonicalization is and how it fits into
 //! rustc, check out the [chapter in the rustc guide][c].
 //!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
+//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 
 use infer::canonical::{
     Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Canonicalized,
@@ -44,7 +44,7 @@
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query
+    /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query
     pub fn canonicalize_query<V>(
         &self,
         value: &V,
@@ -92,7 +92,7 @@
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
+    /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
     pub fn canonicalize_response<V>(&self, value: &V) -> Canonicalized<'gcx, V>
     where
         V: TypeFoldable<'tcx> + Lift<'gcx>,
diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs
index 230f895..6b0fa79 100644
--- a/src/librustc/infer/canonical/mod.rs
+++ b/src/librustc/infer/canonical/mod.rs
@@ -29,7 +29,7 @@
 //! For a more detailed look at what is happening here, check
 //! out the [chapter in the rustc guide][c].
 //!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
+//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 
 use infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin};
 use rustc_data_structures::indexed_vec::IndexVec;
diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs
index d32594e..8d2b1d7 100644
--- a/src/librustc/infer/canonical/query_response.rs
+++ b/src/librustc/infer/canonical/query_response.rs
@@ -15,7 +15,7 @@
 //! For an overview of what canonicaliation is and how it fits into
 //! rustc, check out the [chapter in the rustc guide][c].
 //!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
+//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 
 use infer::canonical::substitute::substitute_value;
 use infer::canonical::{
@@ -184,7 +184,7 @@
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
+    /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
     pub fn instantiate_query_response_and_region_obligations<R>(
         &self,
         cause: &ObligationCause<'tcx>,
diff --git a/src/librustc/infer/canonical/substitute.rs b/src/librustc/infer/canonical/substitute.rs
index e2110e1..ab57588 100644
--- a/src/librustc/infer/canonical/substitute.rs
+++ b/src/librustc/infer/canonical/substitute.rs
@@ -14,7 +14,7 @@
 //! For an overview of what canonicalization is and how it fits into
 //! rustc, check out the [chapter in the rustc guide][c].
 //!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
+//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 
 use infer::canonical::{Canonical, CanonicalVarValues};
 use ty::fold::TypeFoldable;
diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs
index 16140e7..cf91b85 100644
--- a/src/librustc/infer/higher_ranked/mod.rs
+++ b/src/librustc/infer/higher_ranked/mod.rs
@@ -329,7 +329,7 @@
     /// For more information about how placeholders and HRTBs work, see
     /// the [rustc guide].
     ///
-    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
+    /// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html
     pub fn replace_bound_vars_with_placeholders<T>(
         &self,
         binder: &ty::Binder<T>
diff --git a/src/librustc/infer/lexical_region_resolve/README.md b/src/librustc/infer/lexical_region_resolve/README.md
index 6e1c419..4483e52 100644
--- a/src/librustc/infer/lexical_region_resolve/README.md
+++ b/src/librustc/infer/lexical_region_resolve/README.md
@@ -3,7 +3,7 @@
 > 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
+[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
 
 ## Terminology
 
diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs
index 9bdbf77..972ba16 100644
--- a/src/librustc/infer/nll_relate/mod.rs
+++ b/src/librustc/infer/nll_relate/mod.rs
@@ -11,30 +11,41 @@
 //! This code is kind of an alternate way of doing subtyping,
 //! supertyping, and type equating, distinct from the `combine.rs`
 //! code but very similar in its effect and design. Eventually the two
-//! ought to be merged. This code is intended for use in NLL.
+//! ought to be merged. This code is intended for use in NLL and chalk.
 //!
 //! Here are the key differences:
 //!
-//! - This code generally assumes that there are no unbound type
-//!   inferences variables, because at NLL
-//!   time types are fully inferred up-to regions.
-//!   - Actually, to support user-given type annotations like
-//!     `Vec<_>`, we do have some measure of support for type
-//!     inference variables, but we impose some simplifying
-//!     assumptions on them that would not be suitable for the infer
-//!     code more generally. This could be fixed.
+//! - This code may choose to bypass some checks (e.g. the occurs check)
+//!   in the case where we know that there are no unbound type inference
+//!   variables. This is the case for NLL, because at NLL time types are fully
+//!   inferred up-to regions.
 //! - This code uses "universes" to handle higher-ranked regions and
 //!   not the leak-check. This is "more correct" than what rustc does
 //!   and we are generally migrating in this direction, but NLL had to
 //!   get there first.
+//!
+//! Also, this code assumes that there are no bound types at all, not even
+//! free ones. This is ok because:
+//! - we are not relating anything quantified over some type variable
+//! - we will have instantiated all the bound type vars already (the one
+//!   thing we relate in chalk are basically domain goals and their
+//!   constituents)
 
 use crate::infer::InferCtxt;
 use crate::ty::fold::{TypeFoldable, TypeVisitor};
 use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
 use crate::ty::subst::Kind;
 use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::error::TypeError;
+use crate::traits::DomainGoal;
 use rustc_data_structures::fx::FxHashMap;
 
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+pub enum NormalizationStrategy {
+    Lazy,
+    Eager,
+}
+
 pub struct TypeRelating<'me, 'gcx: 'tcx, 'tcx: 'me, D>
 where
     D: TypeRelatingDelegate<'tcx>,
@@ -75,6 +86,10 @@
     /// delegate.
     fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>);
 
+    /// Push a domain goal that will need to be proved for the two types to
+    /// be related. Used for lazy normalization.
+    fn push_domain_goal(&mut self, domain_goal: DomainGoal<'tcx>);
+
     /// Creates a new universe index. Used when instantiating placeholders.
     fn create_next_universe(&mut self) -> ty::UniverseIndex;
 
@@ -105,6 +120,13 @@
     /// relate `Foo<'?0>` with `Foo<'a>` (and probably add an outlives
     /// relation stating that `'?0: 'a`).
     fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>;
+
+    /// Define the normalization strategy to use, eager or lazy.
+    fn normalization() -> NormalizationStrategy;
+
+    /// Enable some optimizations if we do not expect inference variables
+    /// in the RHS of the relation.
+    fn forbid_inference_vars() -> bool;
 }
 
 #[derive(Clone, Debug)]
@@ -242,15 +264,79 @@
         self.delegate.push_outlives(sup, sub);
     }
 
-    /// When we encounter a canonical variable `var` in the output,
-    /// equate it with `kind`. If the variable has been previously
-    /// equated, then equate it again.
-    fn relate_var(&mut self, var_ty: Ty<'tcx>, value_ty: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
-        debug!("equate_var(var_ty={:?}, value_ty={:?})", var_ty, value_ty);
+    /// Relate a projection type and some value type lazily. This will always
+    /// succeed, but we push an additional `ProjectionEq` goal depending
+    /// on the value type:
+    /// - if the value type is any type `T` which is not a projection, we push
+    ///   `ProjectionEq(projection = T)`.
+    /// - if the value type is another projection `other_projection`, we create
+    ///   a new inference variable `?U` and push the two goals
+    ///   `ProjectionEq(projection = ?U)`, `ProjectionEq(other_projection = ?U)`.
+    fn relate_projection_ty(
+        &mut self,
+        projection_ty: ty::ProjectionTy<'tcx>,
+        value_ty: ty::Ty<'tcx>
+    ) -> Ty<'tcx> {
+        use crate::infer::type_variable::TypeVariableOrigin;
+        use crate::traits::WhereClause;
+        use syntax_pos::DUMMY_SP;
 
-        let generalized_ty = self.generalize_value(value_ty);
-        self.infcx
-            .force_instantiate_unchecked(var_ty, generalized_ty);
+        match value_ty.sty {
+            ty::Projection(other_projection_ty) => {
+                let var = self.infcx.next_ty_var(TypeVariableOrigin::MiscVariable(DUMMY_SP));
+                self.relate_projection_ty(projection_ty, var);
+                self.relate_projection_ty(other_projection_ty, var);
+                var
+            }
+
+            _ => {
+                let projection = ty::ProjectionPredicate {
+                    projection_ty,
+                    ty: value_ty,
+                };
+                self.delegate.push_domain_goal(
+                    DomainGoal::Holds(WhereClause::ProjectionEq(projection))
+                );
+                value_ty
+            }
+        }
+    }
+
+    /// Relate a type inference variable with a value type.
+    fn relate_ty_var(
+        &mut self,
+        vid: ty::TyVid,
+        value_ty: Ty<'tcx>
+    ) -> RelateResult<'tcx, Ty<'tcx>> {
+        debug!("relate_ty_var(vid={:?}, value_ty={:?})", vid, value_ty);
+
+        match value_ty.sty {
+            ty::Infer(ty::TyVar(value_vid)) => {
+                // Two type variables: just equate them.
+                self.infcx.type_variables.borrow_mut().equate(vid, value_vid);
+                return Ok(value_ty);
+            }
+
+            ty::Projection(projection_ty)
+                if D::normalization() == NormalizationStrategy::Lazy =>
+            {
+                return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_var(vid)));
+            }
+
+            _ => (),
+        }
+
+        let generalized_ty = self.generalize_value(value_ty, vid)?;
+        debug!("relate_ty_var: generalized_ty = {:?}", generalized_ty);
+
+        if D::forbid_inference_vars() {
+            // In NLL, we don't have type inference variables
+            // floating around, so we can do this rather imprecise
+            // variant of the occurs-check.
+            assert!(!generalized_ty.has_infer_types());
+        }
+
+        self.infcx.type_variables.borrow_mut().instantiate(vid, generalized_ty);
 
         // The generalized values we extract from `canonical_var_values` have
         // been fully instantiated and hence the set of scopes we have
@@ -264,22 +350,27 @@
         // Restore the old scopes now.
         self.a_scopes = old_a_scopes;
 
-        debug!("equate_var: complete, result = {:?}", result);
+        debug!("relate_ty_var: complete, result = {:?}", result);
         result
     }
 
-    fn generalize_value<T: Relate<'tcx>>(&mut self, value: T) -> T {
-        TypeGeneralizer {
-            tcx: self.infcx.tcx,
+    fn generalize_value<T: Relate<'tcx>>(
+        &mut self,
+        value: T,
+        for_vid: ty::TyVid
+    ) -> RelateResult<'tcx, T> {
+        let universe = self.infcx.probe_ty_var(for_vid).unwrap_err();
+
+        let mut generalizer = TypeGeneralizer {
+            infcx: self.infcx,
             delegate: &mut self.delegate,
             first_free_index: ty::INNERMOST,
             ambient_variance: self.ambient_variance,
+            for_vid_sub_root: self.infcx.type_variables.borrow_mut().sub_root_var(for_vid),
+            universe,
+        };
 
-            // These always correspond to an `_` or `'_` written by
-            // user, and those are always in the root universe.
-            universe: ty::UniverseIndex::ROOT,
-        }.relate(&value, &value)
-            .unwrap()
+        generalizer.relate(&value, &value)
     }
 }
 
@@ -327,11 +418,35 @@
         Ok(r)
     }
 
-    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+    fn tys(&mut self, a: Ty<'tcx>, mut b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         let a = self.infcx.shallow_resolve(a);
-        match a.sty {
-            ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) => {
-                self.relate_var(a.into(), b.into())
+
+        if !D::forbid_inference_vars() {
+            b = self.infcx.shallow_resolve(b);
+        }
+
+        match (&a.sty, &b.sty) {
+            (_, &ty::Infer(ty::TyVar(vid))) => {
+                if D::forbid_inference_vars() {
+                    // Forbid inference variables in the RHS.
+                    bug!("unexpected inference var {:?}", b)
+                } else {
+                    self.relate_ty_var(vid, a)
+                }
+            }
+
+            (&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var(vid, b),
+
+            (&ty::Projection(projection_ty), _)
+                if D::normalization() == NormalizationStrategy::Lazy =>
+            {
+                Ok(self.relate_projection_ty(projection_ty, b))
+            }
+
+            (_, &ty::Projection(projection_ty))
+                if D::normalization() == NormalizationStrategy::Lazy =>
+            {
+                Ok(self.relate_projection_ty(projection_ty, a))
             }
 
             _ => {
@@ -340,7 +455,8 @@
                     a, b, self.ambient_variance
                 );
 
-                relate::super_relate_tys(self, a, b)
+                // Will also handle unification of `IntVar` and `FloatVar`.
+                self.infcx.super_combine_tys(self, a, b)
             }
         }
     }
@@ -551,7 +667,7 @@
 where
     D: TypeRelatingDelegate<'tcx> + 'me,
 {
-    tcx: TyCtxt<'me, 'gcx, 'tcx>,
+    infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
 
     delegate: &'me mut D,
 
@@ -561,6 +677,14 @@
 
     first_free_index: ty::DebruijnIndex,
 
+    /// The vid of the type variable that is in the process of being
+    /// instantiated. If we find this within the value we are folding,
+    /// that means we would have created a cyclic value.
+    for_vid_sub_root: ty::TyVid,
+
+    /// The universe of the type variable that is in the process of being
+    /// instantiated. If we find anything that this universe cannot name,
+    /// we reject the relation.
     universe: ty::UniverseIndex,
 }
 
@@ -569,7 +693,7 @@
     D: TypeRelatingDelegate<'tcx>,
 {
     fn tcx(&self) -> TyCtxt<'me, 'gcx, 'tcx> {
-        self.tcx
+        self.infcx.tcx
     }
 
     fn tag(&self) -> &'static str {
@@ -609,17 +733,84 @@
     }
 
     fn tys(&mut self, a: Ty<'tcx>, _: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+        use crate::infer::type_variable::TypeVariableValue;
+
         debug!("TypeGeneralizer::tys(a={:?})", a,);
 
         match a.sty {
-            ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) => {
+            ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_))
+                if D::forbid_inference_vars() =>
+            {
                 bug!(
                     "unexpected inference variable encountered in NLL generalization: {:?}",
                     a
                 );
             }
 
-            _ => relate::super_relate_tys(self, a, a),
+            ty::Infer(ty::TyVar(vid)) => {
+                let mut variables = self.infcx.type_variables.borrow_mut();
+                let vid = variables.root_var(vid);
+                let sub_vid = variables.sub_root_var(vid);
+                if sub_vid == self.for_vid_sub_root {
+                    // If sub-roots are equal, then `for_vid` and
+                    // `vid` are related via subtyping.
+                    debug!("TypeGeneralizer::tys: occurs check failed");
+                    return Err(TypeError::Mismatch);
+                } else {
+                    match variables.probe(vid) {
+                        TypeVariableValue::Known { value: u } => {
+                            drop(variables);
+                            self.relate(&u, &u)
+                        }
+                        TypeVariableValue::Unknown { universe: _universe } => {
+                            if self.ambient_variance == ty::Bivariant {
+                                // FIXME: we may need a WF predicate (related to #54105).
+                            }
+
+                            let origin = *variables.var_origin(vid);
+
+                            // Replacing with a new variable in the universe `self.universe`,
+                            // it will be unified later with the original type variable in
+                            // the universe `_universe`.
+                            let new_var_id = variables.new_var(self.universe, false, origin);
+
+                            let u = self.tcx().mk_var(new_var_id);
+                            debug!(
+                                "generalize: replacing original vid={:?} with new={:?}",
+                                vid,
+                                u
+                            );
+                            return Ok(u);
+                        }
+                    }
+                }
+            }
+
+            ty::Infer(ty::IntVar(_)) |
+            ty::Infer(ty::FloatVar(_)) => {
+                // No matter what mode we are in,
+                // integer/floating-point types must be equal to be
+                // relatable.
+                Ok(a)
+            }
+
+            ty::Placeholder(placeholder) => {
+                if self.universe.cannot_name(placeholder.universe) {
+                    debug!(
+                        "TypeGeneralizer::tys: root universe {:?} cannot name\
+                        placeholder in universe {:?}",
+                        self.universe,
+                        placeholder.universe
+                    );
+                    Err(TypeError::Mismatch)
+                } else {
+                    Ok(a)
+                }
+            }
+
+            _ => {
+                relate::super_relate_tys(self, a, a)
+            }
         }
     }
 
@@ -673,64 +864,3 @@
         Ok(ty::Binder::bind(result))
     }
 }
-
-impl InferCtxt<'_, '_, 'tcx> {
-    /// A hacky sort of method used by the NLL type-relating code:
-    ///
-    /// - `var` must be some unbound type variable.
-    /// - `value` must be a suitable type to use as its value.
-    ///
-    /// `var` will then be equated with `value`. Note that this
-    /// sidesteps a number of important checks, such as the "occurs
-    /// check" that prevents cyclic types, so it is important not to
-    /// use this method during regular type-check.
-    fn force_instantiate_unchecked(&self, var: Ty<'tcx>, value: Ty<'tcx>) {
-        match (&var.sty, &value.sty) {
-            (&ty::Infer(ty::TyVar(vid)), _) => {
-                let mut type_variables = self.type_variables.borrow_mut();
-
-                // In NLL, we don't have type inference variables
-                // floating around, so we can do this rather imprecise
-                // variant of the occurs-check.
-                assert!(!value.has_infer_types());
-
-                type_variables.instantiate(vid, value);
-            }
-
-            (&ty::Infer(ty::IntVar(vid)), &ty::Int(value)) => {
-                let mut int_unification_table = self.int_unification_table.borrow_mut();
-                int_unification_table
-                    .unify_var_value(vid, Some(ty::IntVarValue::IntType(value)))
-                    .unwrap_or_else(|_| {
-                        bug!("failed to unify int var `{:?}` with `{:?}`", vid, value);
-                    });
-            }
-
-            (&ty::Infer(ty::IntVar(vid)), &ty::Uint(value)) => {
-                let mut int_unification_table = self.int_unification_table.borrow_mut();
-                int_unification_table
-                    .unify_var_value(vid, Some(ty::IntVarValue::UintType(value)))
-                    .unwrap_or_else(|_| {
-                        bug!("failed to unify int var `{:?}` with `{:?}`", vid, value);
-                    });
-            }
-
-            (&ty::Infer(ty::FloatVar(vid)), &ty::Float(value)) => {
-                let mut float_unification_table = self.float_unification_table.borrow_mut();
-                float_unification_table
-                    .unify_var_value(vid, Some(ty::FloatVarValue(value)))
-                    .unwrap_or_else(|_| {
-                        bug!("failed to unify float var `{:?}` with `{:?}`", vid, value)
-                    });
-            }
-
-            _ => {
-                bug!(
-                    "force_instantiate_unchecked invoked with bad combination: var={:?} value={:?}",
-                    var,
-                    value,
-                );
-            }
-        }
-    }
-}
diff --git a/src/librustc/infer/region_constraints/README.md b/src/librustc/infer/region_constraints/README.md
index 61603e6..775bbf9 100644
--- a/src/librustc/infer/region_constraints/README.md
+++ b/src/librustc/infer/region_constraints/README.md
@@ -3,7 +3,7 @@
 > 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
+[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
 
 ## Terminology
 
@@ -18,7 +18,7 @@
 processing a function, we process and solve the constraints all at
 once.
 
-[ti]: https://rust-lang-nursery.github.io/rustc-guide/type-inference.html
+[ti]: https://rust-lang.github.io/rustc-guide/type-inference.html
 
 The constraints are always of one of three possible forms:
 
diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs
index a0c310a..7a1ee85 100644
--- a/src/librustc/infer/resolve.rs
+++ b/src/librustc/infer/resolve.rs
@@ -25,6 +25,7 @@
 }
 
 impl<'a, 'gcx, 'tcx> OpportunisticTypeResolver<'a, 'gcx, 'tcx> {
+    #[inline]
     pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
         OpportunisticTypeResolver { infcx }
     }
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 0aa964a..ddb0c5b 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -30,7 +30,7 @@
 //!
 //! For more information about how rustc works, see the [rustc guide].
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/
 //!
 //! # Note
 //!
@@ -67,7 +67,6 @@
 #![feature(integer_atomics)]
 #![feature(test)]
 #![feature(in_band_lifetimes)]
-#![feature(macro_at_most_once_rep)]
 #![feature(crate_visibility_modifier)]
 #![feature(transpose_result)]
 
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 282b5d1..bb7a6a6 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -166,6 +166,7 @@
                     hir::ItemKind::Fn(..)
                     | hir::ItemKind::Ty(..)
                     | hir::ItemKind::Static(..)
+                    | hir::ItemKind::Existential(..)
                     | hir::ItemKind::Const(..) => {
                         intravisit::walk_item(self, &item);
                     }
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index 671f513..549a848 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -127,9 +127,8 @@
             sess.crt_static() => Linkage::Static,
         config::CrateType::Executable => Linkage::Dynamic,
 
-        // proc-macro crates are required to be dylibs, and they're currently
-        // required to link to libsyntax as well.
-        config::CrateType::ProcMacro => Linkage::Dynamic,
+        // proc-macro crates are mostly cdylibs, but we also need metadata.
+        config::CrateType::ProcMacro => Linkage::Static,
 
         // No linkage happens with rlibs, we just needed the metadata (which we
         // got long ago), so don't bother with anything.
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 55ffa50e..e7a8baf 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -297,6 +297,7 @@
     IndexMutTraitLangItem,       "index_mut",          index_mut_trait,         Target::Trait;
 
     UnsafeCellTypeLangItem,      "unsafe_cell",        unsafe_cell_type,        Target::Struct;
+    VaListTypeLangItem,          "va_list",            va_list,                 Target::Struct;
 
     DerefTraitLangItem,          "deref",              deref_trait,             Target::Trait;
     DerefMutTraitLangItem,       "deref_mut",          deref_mut_trait,         Target::Trait;
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 54a0192..b846a1c 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1575,7 +1575,7 @@
                 let sp = ident.span;
                 let var = self.variable(hir_id, sp);
                 // Ignore unused self.
-                if ident.name != keywords::SelfValue.name() {
+                if ident.name != keywords::SelfLower.name() {
                     if !self.warn_about_unused(sp, hir_id, entry_ln, var) {
                         if self.live_on_entry(entry_ln, var).is_none() {
                             self.report_dead_assign(hir_id, sp, var, true);
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 0009a51..ab0094d 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -117,8 +117,9 @@
                 self.reachable_symbols.insert(node_id);
             }
             Some(def) => {
-                let def_id = def.def_id();
-                if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
+                if let Some((node_id, def_id)) = def.opt_def_id().and_then(|def_id| {
+                    self.tcx.hir.as_local_node_id(def_id).map(|node_id| (node_id, def_id))
+                }) {
                     if self.def_id_represents_local_inlined_item(def_id) {
                         self.worklist.push(node_id);
                     } else {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index d00fbde..3c2551f 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -14,7 +14,7 @@
 //! 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
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
 
 use ich::{StableHashingContext, NodeIdHashingMode};
 use util::nodemap::{FxHashMap, FxHashSet};
@@ -592,10 +592,7 @@
                 return Some(scope.item_local_id());
             }
 
-            match self.opt_encl_scope(scope) {
-                None => return None,
-                Some(parent) => scope = parent,
-            }
+            scope = self.opt_encl_scope(scope)?;
         }
     }
 
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 6ff4505..07054ee 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -1573,7 +1573,7 @@
             .collect();
 
         // ensure that we issue lints in a repeatable order
-        def_ids.sort_by_key(|&def_id| self.tcx.def_path_hash(def_id));
+        def_ids.sort_by_cached_key(|&def_id| self.tcx.def_path_hash(def_id));
 
         for def_id in def_ids {
             debug!(
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 4bcba9d..500bd47 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -139,6 +139,14 @@
     }
 
     #[inline]
+    pub fn with_tag(self, new_tag: Tag) -> Self {
+        match self {
+            Scalar::Ptr(ptr) => Scalar::Ptr(Pointer { tag: new_tag, ..ptr }),
+            Scalar::Bits { bits, size } => Scalar::Bits { bits, size },
+        }
+    }
+
+    #[inline]
     pub fn ptr_null(cx: &impl HasDataLayout) -> Self {
         Scalar::Bits {
             bits: 0,
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index af1255c..9166355 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -10,7 +10,7 @@
 
 //! MIR datatypes and passes. See the [rustc guide] for more info.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/index.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html
 
 use hir::def::CtorKind;
 use hir::def_id::DefId;
@@ -25,7 +25,7 @@
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::sync::MappedReadGuard;
-use rustc_serialize as serialize;
+use rustc_serialize::{self as serialize};
 use smallvec::SmallVec;
 use std::borrow::Cow;
 use std::fmt::{self, Debug, Formatter, Write};
@@ -1778,6 +1778,10 @@
         /// `fn_entry` indicates whether this is the initial retag that happens in the
         /// function prolog.
         fn_entry: bool,
+        /// `two_phase` indicates whether this is just the reservation action of
+        /// a two-phase borrow.
+        two_phase: bool,
+        /// The place to retag
         place: Place<'tcx>,
     },
 
@@ -1841,8 +1845,12 @@
         match self.kind {
             Assign(ref place, ref rv) => write!(fmt, "{:?} = {:?}", place, rv),
             FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, place),
-            Retag { fn_entry, ref place } =>
-                write!(fmt, "Retag({}{:?})", if fn_entry { "[fn entry] " } else { "" }, place),
+            Retag { fn_entry, two_phase, ref place } =>
+                write!(fmt, "Retag({}{}{:?})",
+                    if fn_entry { "[fn entry] " } else { "" },
+                    if two_phase { "[2phase] " } else { "" },
+                    place,
+                ),
             EscapeToRaw(ref place) => write!(fmt, "EscapeToRaw({:?})", place),
             StorageLive(ref place) => write!(fmt, "StorageLive({:?})", place),
             StorageDead(ref place) => write!(fmt, "StorageDead({:?})", place),
@@ -2770,8 +2778,11 @@
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub enum UnsafetyViolationKind {
     General,
-    /// unsafety is not allowed at all in min const fn
-    MinConstFn,
+    /// Right now function calls to `const unsafe fn` are only permitted behind a feature gate
+    /// Also, even `const unsafe fn` need an `unsafe` block to do the allowed operations.
+    GatedConstFnCall,
+    /// Permitted in const fn and regular fns
+    GeneralAndConstFn,
     ExternStatic(ast::NodeId),
     BorrowPacked(ast::NodeId),
 }
@@ -3019,7 +3030,7 @@
         (StatementKind::StorageLive)(a),
         (StatementKind::StorageDead)(a),
         (StatementKind::InlineAsm) { asm, outputs, inputs },
-        (StatementKind::Retag) { fn_entry, place },
+        (StatementKind::Retag) { fn_entry, two_phase, place },
         (StatementKind::EscapeToRaw)(place),
         (StatementKind::AscribeUserType)(a, v, b),
         (StatementKind::Nop),
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 0c9b06a..d40d85a 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -154,9 +154,10 @@
 
             fn visit_retag(&mut self,
                            fn_entry: & $($mutability)* bool,
+                           two_phase: & $($mutability)* bool,
                            place: & $($mutability)* Place<'tcx>,
                            location: Location) {
-                self.super_retag(fn_entry, place, location);
+                self.super_retag(fn_entry, two_phase, place, location);
             }
 
             fn visit_place(&mut self,
@@ -417,8 +418,9 @@
                         }
                     }
                     StatementKind::Retag { ref $($mutability)* fn_entry,
+                                           ref $($mutability)* two_phase,
                                            ref $($mutability)* place } => {
-                        self.visit_retag(fn_entry, place, location);
+                        self.visit_retag(fn_entry, two_phase, place, location);
                     }
                     StatementKind::AscribeUserType(
                         ref $($mutability)* place,
@@ -724,6 +726,7 @@
 
             fn super_retag(&mut self,
                            _fn_entry: & $($mutability)* bool,
+                           _two_phase: & $($mutability)* bool,
                            place: & $($mutability)* Place<'tcx>,
                            location: Location) {
                 self.visit_place(
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 3fd2279..f1ddcda 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -780,43 +780,42 @@
     }
 
     pub type $setter_name = fn(&mut $struct_name, v: Option<&str>) -> bool;
-    pub const $stat: &'static [(&'static str, $setter_name,
-                                Option<&'static str>, &'static str)] =
+    pub const $stat: &[(&str, $setter_name, Option<&str>, &str)] =
         &[ $( (stringify!($opt), $mod_set::$opt, $mod_desc::$parse, $desc) ),* ];
 
     #[allow(non_upper_case_globals, dead_code)]
     mod $mod_desc {
-        pub const parse_bool: Option<&'static str> = None;
-        pub const parse_opt_bool: Option<&'static str> =
+        pub const parse_bool: Option<&str> = None;
+        pub const parse_opt_bool: Option<&str> =
             Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
-        pub const parse_string: Option<&'static str> = Some("a string");
-        pub const parse_string_push: Option<&'static str> = Some("a string");
-        pub const parse_pathbuf_push: Option<&'static str> = Some("a path");
-        pub const parse_opt_string: Option<&'static str> = Some("a string");
-        pub const parse_opt_pathbuf: Option<&'static str> = Some("a path");
-        pub const parse_list: Option<&'static str> = Some("a space-separated list of strings");
-        pub const parse_opt_list: Option<&'static str> = Some("a space-separated list of strings");
-        pub const parse_uint: Option<&'static str> = Some("a number");
-        pub const parse_passes: Option<&'static str> =
+        pub const parse_string: Option<&str> = Some("a string");
+        pub const parse_string_push: Option<&str> = Some("a string");
+        pub const parse_pathbuf_push: Option<&str> = Some("a path");
+        pub const parse_opt_string: Option<&str> = Some("a string");
+        pub const parse_opt_pathbuf: Option<&str> = Some("a path");
+        pub const parse_list: Option<&str> = Some("a space-separated list of strings");
+        pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings");
+        pub const parse_uint: Option<&str> = Some("a number");
+        pub const parse_passes: Option<&str> =
             Some("a space-separated list of passes, or `all`");
-        pub const parse_opt_uint: Option<&'static str> =
+        pub const parse_opt_uint: Option<&str> =
             Some("a number");
-        pub const parse_panic_strategy: Option<&'static str> =
+        pub const parse_panic_strategy: Option<&str> =
             Some("either `unwind` or `abort`");
-        pub const parse_relro_level: Option<&'static str> =
+        pub const parse_relro_level: Option<&str> =
             Some("one of: `full`, `partial`, or `off`");
-        pub const parse_sanitizer: Option<&'static str> =
+        pub const parse_sanitizer: Option<&str> =
             Some("one of: `address`, `leak`, `memory` or `thread`");
-        pub const parse_linker_flavor: Option<&'static str> =
+        pub const parse_linker_flavor: Option<&str> =
             Some(::rustc_target::spec::LinkerFlavor::one_of());
-        pub const parse_optimization_fuel: Option<&'static str> =
+        pub const parse_optimization_fuel: Option<&str> =
             Some("crate=integer");
-        pub const parse_unpretty: Option<&'static str> =
+        pub const parse_unpretty: Option<&str> =
             Some("`string` or `string=string`");
-        pub const parse_lto: Option<&'static str> =
+        pub const parse_lto: Option<&str> =
             Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
                   `fat`, or omitted");
-        pub const parse_cross_lang_lto: Option<&'static str> =
+        pub const parse_cross_lang_lto: Option<&str> =
             Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \
                   or the path to the linker plugin");
     }
@@ -1286,8 +1285,6 @@
         "print some performance-related statistics"),
     hir_stats: bool = (false, parse_bool, [UNTRACKED],
         "print some statistics about AST and HIR"),
-    mir_stats: bool = (false, parse_bool, [UNTRACKED],
-        "print some statistics about MIR"),
     always_encode_mir: bool = (false, parse_bool, [TRACKED],
         "encode MIR of all functions into the crate metadata"),
     osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
@@ -1758,8 +1755,8 @@
         .into_iter()
         .map(|s| {
             let sess = parse::ParseSess::new(FilePathMapping::empty());
-            let mut parser =
-                parse::new_parser_from_source_str(&sess, FileName::CfgSpec, s.to_string());
+            let filename = FileName::cfg_spec_source_code(&s);
+            let mut parser = parse::new_parser_from_source_str(&sess, filename, s.to_string());
 
             macro_rules! error {($reason: expr) => {
                 early_error(ErrorOutputType::default(),
diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs
index f410c27..e686a1d 100644
--- a/src/librustc/session/filesearch.rs
+++ b/src/librustc/session/filesearch.rs
@@ -179,12 +179,12 @@
     // "lib" (i.e. non-default), this value is used (see issue #16552).
 
     #[cfg(target_pointer_width = "64")]
-    const PRIMARY_LIB_DIR: &'static str = "lib64";
+    const PRIMARY_LIB_DIR: &str = "lib64";
 
     #[cfg(target_pointer_width = "32")]
-    const PRIMARY_LIB_DIR: &'static str = "lib32";
+    const PRIMARY_LIB_DIR: &str = "lib32";
 
-    const SECONDARY_LIB_DIR: &'static str = "lib";
+    const SECONDARY_LIB_DIR: &str = "lib";
 
     match option_env!("CFG_LIBDIR_RELATIVE") {
         Some(libdir) if libdir != "lib" => libdir.into(),
@@ -198,4 +198,4 @@
 
 // The name of rustc's own place to organize libraries.
 // Used to be "rustc", now the default is "rustlib"
-const RUST_LIB_DIR: &'static str = "rustlib";
+const RUST_LIB_DIR: &str = "rustlib";
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 1187c53..293cd0c 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -68,7 +68,7 @@
     /// For a library crate, this is always none
     pub entry_fn: Once<Option<(NodeId, Span, config::EntryFnType)>>,
     pub plugin_registrar_fn: Once<Option<ast::NodeId>>,
-    pub derive_registrar_fn: Once<Option<ast::NodeId>>,
+    pub proc_macro_decls_static: Once<Option<ast::NodeId>>,
     pub default_sysroot: Option<PathBuf>,
     /// The name of the root source file of the crate, in the local file system.
     /// `None` means that there is no source file.
@@ -687,9 +687,9 @@
         )
     }
 
-    pub fn generate_derive_registrar_symbol(&self, disambiguator: CrateDisambiguator) -> String {
+    pub fn generate_proc_macro_decls_symbol(&self, disambiguator: CrateDisambiguator) -> String {
         format!(
-            "__rustc_derive_registrar_{}__",
+            "__rustc_proc_macro_decls_{}__",
             disambiguator.to_fingerprint().to_hex()
         )
     }
@@ -826,7 +826,7 @@
     }
 
     pub fn profiler<F: FnOnce(&mut SelfProfiler) -> ()>(&self, f: F) {
-        if self.opts.debugging_opts.self_profile {
+        if self.opts.debugging_opts.self_profile || self.opts.debugging_opts.profile_json {
             let mut profiler = self.self_profiling.borrow_mut();
             f(&mut profiler);
         }
@@ -1146,7 +1146,7 @@
         // For a library crate, this is always none
         entry_fn: Once::new(),
         plugin_registrar_fn: Once::new(),
-        derive_registrar_fn: Once::new(),
+        proc_macro_decls_static: Once::new(),
         default_sysroot,
         local_crate_source_file,
         working_dir,
diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs
index 768d4f1..6b0a8a0 100644
--- a/src/librustc/session/search_paths.rs
+++ b/src/librustc/session/search_paths.rs
@@ -67,14 +67,13 @@
 
     fn next(&mut self) -> Option<(&'a Path, PathKind)> {
         loop {
-            match self.iter.next() {
-                Some(&(kind, ref p)) if self.kind == PathKind::All ||
-                                        kind == PathKind::All ||
-                                        kind == self.kind => {
+            match *self.iter.next()? {
+                (kind, ref p) if self.kind == PathKind::All ||
+                                  kind == PathKind::All ||
+                                  kind == self.kind => {
                     return Some((p, kind))
                 }
-                Some(..) => {}
-                None => return None,
+                _ => {}
             }
         }
     }
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index b7a84c9..4bf8ba0 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -11,8 +11,8 @@
 //! See rustc guide chapters on [trait-resolution] and [trait-specialization] for more info on how
 //! this works.
 //!
-//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
-//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
+//! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
+//! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
 
 use hir::def_id::{DefId, LOCAL_CRATE};
 use syntax_pos::DUMMY_SP;
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 8c3cd5e..ab2fa68 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -10,7 +10,7 @@
 
 //! Trait Resolution. See [rustc guide] for more info on how this works.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
 
 pub use self::SelectionError::*;
 pub use self::FulfillmentErrorCode::*;
@@ -1052,6 +1052,7 @@
 }
 
 impl<'tcx> ObligationCause<'tcx> {
+    #[inline]
     pub fn new(span: Span,
                body_id: ast::NodeId,
                code: ObligationCauseCode<'tcx>)
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index c79fa38..2909daf 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -409,7 +409,7 @@
             .collect::<Vec<_>>();
 
         // existential predicates need to be in a specific order
-        associated_types.sort_by_key(|item| self.def_path_hash(item.def_id));
+        associated_types.sort_by_cached_key(|item| self.def_path_hash(item.def_id));
 
         let projection_predicates = associated_types.into_iter().map(|item| {
             ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs
index d20d43c..f8f9650 100644
--- a/src/librustc/traits/query/type_op/mod.rs
+++ b/src/librustc/traits/query/type_op/mod.rs
@@ -53,7 +53,7 @@
 /// first canonicalize the key and then invoke the query on the tcx,
 /// which produces the resulting query region constraints.
 ///
-/// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
+/// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
     fmt::Debug + Sized + TypeFoldable<'tcx> + Lift<'gcx>
 {
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 0f59f47..fb4c9f3 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -10,7 +10,7 @@
 
 //! See [rustc guide] for more info on how this works.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#selection
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html#selection
 
 use self::EvaluationResult::*;
 use self::SelectionCandidate::*;
@@ -1173,7 +1173,7 @@
     // candidates. See [rustc guide] for more details.
     //
     // [rustc guide]:
-    // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#candidate-assembly
+    // https://rust-lang.github.io/rustc-guide/traits/resolution.html#candidate-assembly
 
     fn candidate_from_obligation<'o>(
         &mut self,
@@ -2720,7 +2720,7 @@
     // type error.  See [rustc guide] for more details.
     //
     // [rustc guide]:
-    // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#confirmation
+    // https://rust-lang.github.io/rustc-guide/traits/resolution.html#confirmation
 
     fn confirm_candidate(
         &mut self,
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index d3dc165..cb17246 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -17,7 +17,7 @@
 //! See the [rustc guide] for a bit more detail on how specialization
 //! fits together with the rest of the trait machinery.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
 
 use super::{SelectionContext, FulfillmentContext};
 use super::util::impl_trait_ref_and_oblig;
@@ -85,6 +85,8 @@
                                         source_substs: &'tcx Substs<'tcx>,
                                         target_node: specialization_graph::Node)
                                         -> &'tcx Substs<'tcx> {
+    debug!("translate_substs({:?}, {:?}, {:?}, {:?})",
+           param_env, source_impl, source_substs, target_node);
     let source_trait_ref = infcx.tcx
                                 .impl_trait_ref(source_impl)
                                 .unwrap()
@@ -119,10 +121,13 @@
 /// whichever applies.
 pub fn find_associated_item<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     item: &ty::AssociatedItem,
     substs: &'tcx Substs<'tcx>,
     impl_data: &super::VtableImplData<'tcx, ()>,
 ) -> (DefId, &'tcx Substs<'tcx>) {
+    debug!("find_associated_item({:?}, {:?}, {:?}, {:?})",
+           param_env, item, substs, impl_data);
     assert!(!substs.needs_infer());
 
     let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap();
@@ -132,7 +137,7 @@
     match ancestors.defs(tcx, item.ident, item.kind, trait_def_id).next() {
         Some(node_item) => {
             let substs = tcx.infer_ctxt().enter(|infcx| {
-                let param_env = ty::ParamEnv::reveal_all();
+                let param_env = param_env.with_reveal_all();
                 let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
                 let substs = translate_substs(&infcx, param_env, impl_data.impl_def_id,
                                               substs, node_item.node);
@@ -219,12 +224,17 @@
                                        source_trait_ref: ty::TraitRef<'tcx>,
                                        target_impl: DefId)
                                        -> Result<&'tcx Substs<'tcx>, ()> {
+    debug!("fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)",
+           param_env, source_trait_ref, target_impl);
+
     let selcx = &mut SelectionContext::new(&infcx);
     let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
     let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx,
                                                                        param_env,
                                                                        target_impl,
                                                                        target_substs);
+    debug!("fulfill_implication: target_trait_ref={:?}, obligations={:?}",
+           target_trait_ref, obligations);
 
     // do the impls unify? If not, no specialization.
     match infcx.at(&ObligationCause::dummy(), param_env)
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 36538ac..36e93cc 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -33,8 +33,8 @@
         if ty::tls::with(|tcx| tcx.sess.verbose()) {
             write!(
                 f,
-                "Obligation(predicate={:?},cause={:?},depth={})",
-                self.predicate, self.cause, self.recursion_depth
+                "Obligation(predicate={:?},cause={:?},param_env={:?},depth={})",
+                self.predicate, self.cause, self.param_env, self.recursion_depth
             )
         } else {
             write!(
diff --git a/src/librustc/ty/constness.rs b/src/librustc/ty/constness.rs
index 47aea7a..bc06167 100644
--- a/src/librustc/ty/constness.rs
+++ b/src/librustc/ty/constness.rs
@@ -5,7 +5,6 @@
 use syntax_pos::symbol::Symbol;
 use hir::map::blocks::FnLikeNode;
 use syntax::attr;
-use rustc_target::spec::abi;
 
 impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
     /// Whether the `def_id` counts as const fn in your current crate, considering all active
@@ -40,19 +39,12 @@
 
     /// Returns true if this function must conform to `min_const_fn`
     pub fn is_min_const_fn(self, def_id: DefId) -> bool {
+        // Bail out if the signature doesn't contain `const`
+        if !self.is_const_fn_raw(def_id) {
+            return false;
+        }
+
         if self.features().staged_api {
-            // some intrinsics are waved through if called inside the
-            // standard library. Users never need to call them directly
-            if let abi::Abi::RustIntrinsic = self.fn_sig(def_id).abi() {
-                assert!(!self.is_const_fn(def_id));
-                match &self.item_name(def_id).as_str()[..] {
-                    | "size_of"
-                    | "min_align_of"
-                    | "needs_drop"
-                    => return true,
-                    _ => {},
-                }
-            }
             // in order for a libstd function to be considered min_const_fn
             // it needs to be stable and have no `rustc_const_unstable` attribute
             match self.lookup_stability(def_id) {
@@ -66,7 +58,7 @@
             }
         } else {
             // users enabling the `const_fn` feature gate can do what they want
-            !self.sess.features_untracked().const_fn
+            !self.features().const_fn
         }
     }
 }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 5780fbe..f041192 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -53,6 +53,7 @@
 use ty::CanonicalPolyFnSig;
 use util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap};
 use util::nodemap::{FxHashMap, FxHashSet};
+use rustc_data_structures::interner::HashInterner;
 use smallvec::SmallVec;
 use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
                                            StableHasher, StableHasherResult,
@@ -113,7 +114,7 @@
     const_allocs: TypedArena<interpret::Allocation>,
 }
 
-type InternedSet<'tcx, T> = Lock<FxHashSet<Interned<'tcx, T>>>;
+type InternedSet<'tcx, T> = Lock<FxHashMap<Interned<'tcx, T>, ()>>;
 
 pub struct CtxtInterners<'tcx> {
     /// The arena that types, regions, etc are allocated from
@@ -155,6 +156,7 @@
     }
 
     /// Intern a type
+    #[inline(never)]
     fn intern_ty(
         local: &CtxtInterners<'tcx>,
         global: &CtxtInterners<'gcx>,
@@ -166,56 +168,45 @@
         // determine that all contents are in the global tcx.
         // See comments on Lift for why we can't use that.
         if flags.flags.intersects(ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
-            let mut interner = local.type_.borrow_mut();
-            if let Some(&Interned(ty)) = interner.get(&st) {
-                return ty;
-            }
+            local.type_.borrow_mut().intern(st, |st| {
+                let ty_struct = TyS {
+                    sty: st,
+                    flags: flags.flags,
+                    outer_exclusive_binder: flags.outer_exclusive_binder,
+                };
 
-            let ty_struct = TyS {
-                sty: st,
-                flags: flags.flags,
-                outer_exclusive_binder: flags.outer_exclusive_binder,
-            };
+                // Make sure we don't end up with inference
+                // types/regions in the global interner
+                if local as *const _ as usize == global as *const _ as usize {
+                    bug!("Attempted to intern `{:?}` which contains \
+                        inference types/regions in the global type context",
+                        &ty_struct);
+                }
 
-            // Make sure we don't end up with inference
-            // types/regions in the global interner
-            if local as *const _ as usize == global as *const _ as usize {
-                bug!("Attempted to intern `{:?}` which contains \
-                      inference types/regions in the global type context",
-                     &ty_struct);
-            }
-
-            // Don't be &mut TyS.
-            let ty: Ty<'tcx> = local.arena.alloc(ty_struct);
-            interner.insert(Interned(ty));
-            ty
+                Interned(local.arena.alloc(ty_struct))
+            }).0
         } else {
-            let mut interner = global.type_.borrow_mut();
-            if let Some(&Interned(ty)) = interner.get(&st) {
-                return ty;
-            }
+            global.type_.borrow_mut().intern(st, |st| {
+                let ty_struct = TyS {
+                    sty: st,
+                    flags: flags.flags,
+                    outer_exclusive_binder: flags.outer_exclusive_binder,
+                };
 
-            let ty_struct = TyS {
-                sty: st,
-                flags: flags.flags,
-                outer_exclusive_binder: flags.outer_exclusive_binder,
-            };
+                // This is safe because all the types the ty_struct can point to
+                // already is in the global arena
+                let ty_struct: TyS<'gcx> = unsafe {
+                    mem::transmute(ty_struct)
+                };
 
-            // This is safe because all the types the ty_struct can point to
-            // already is in the global arena
-            let ty_struct: TyS<'gcx> = unsafe {
-                mem::transmute(ty_struct)
-            };
-
-            // Don't be &mut TyS.
-            let ty: Ty<'gcx> = global.arena.alloc(ty_struct);
-            interner.insert(Interned(ty));
-            ty
+                Interned(global.arena.alloc(ty_struct))
+            }).0
         }
     }
 }
 
 pub struct CommonTypes<'tcx> {
+    pub unit: Ty<'tcx>,
     pub bool: Ty<'tcx>,
     pub char: Ty<'tcx>,
     pub isize: Ty<'tcx>,
@@ -825,14 +816,13 @@
     fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
         let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
         let mk_region = |r| {
-            if let Some(r) = interners.region.borrow().get(&r) {
-                return r.0;
-            }
-            let r = interners.arena.alloc(r);
-            interners.region.borrow_mut().insert(Interned(r));
-            &*r
+            interners.region.borrow_mut().intern(r, |r| {
+                Interned(interners.arena.alloc(r))
+            }).0
         };
+
         CommonTypes {
+            unit: mk(Tuple(List::empty())),
             bool: mk(Bool),
             char: mk(Char),
             never: mk(Never),
@@ -876,7 +866,7 @@
 /// various **compiler queries** that have been performed. See the
 /// [rustc guide] for more details.
 ///
-/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ty.html
+/// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html
 #[derive(Copy, Clone)]
 pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> {
     gcx: &'a GlobalCtxt<'gcx>,
@@ -885,6 +875,7 @@
 
 impl<'a, 'gcx, 'tcx> Deref for TyCtxt<'a, 'gcx, 'tcx> {
     type Target = &'a GlobalCtxt<'gcx>;
+    #[inline(always)]
     fn deref(&self) -> &Self::Target {
         &self.gcx
     }
@@ -950,14 +941,14 @@
     /// Data layout specification for the current target.
     pub data_layout: TargetDataLayout,
 
-    stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>,
+    stability_interner: Lock<FxHashMap<&'tcx attr::Stability, ()>>,
 
     /// Stores the value of constants (and deduplicates the actual memory)
-    allocation_interner: Lock<FxHashSet<&'tcx Allocation>>,
+    allocation_interner: Lock<FxHashMap<&'tcx Allocation, ()>>,
 
     pub alloc_map: Lock<interpret::AllocMap<'tcx, &'tcx Allocation>>,
 
-    layout_interner: Lock<FxHashSet<&'tcx LayoutDetails>>,
+    layout_interner: Lock<FxHashMap<&'tcx LayoutDetails, ()>>,
 
     /// A general purpose channel to throw data out the back towards LLVM worker
     /// threads.
@@ -1040,16 +1031,9 @@
         self,
         alloc: Allocation,
     ) -> &'gcx Allocation {
-        let allocs = &mut self.allocation_interner.borrow_mut();
-        if let Some(alloc) = allocs.get(&alloc) {
-            return alloc;
-        }
-
-        let interned = self.global_arenas.const_allocs.alloc(alloc);
-        if let Some(prev) = allocs.replace(interned) { // insert into interner
-            bug!("Tried to overwrite interned Allocation: {:#?}", prev)
-        }
-        interned
+        self.allocation_interner.borrow_mut().intern(alloc, |alloc| {
+            self.global_arenas.const_allocs.alloc(alloc)
+        })
     }
 
     /// Allocates a byte or string literal for `mir::interpret`, read-only
@@ -1061,29 +1045,15 @@
     }
 
     pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
-        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) = stability_interner.replace(interned) {
-            bug!("Tried to overwrite interned Stability: {:?}", prev)
-        }
-        interned
+        self.stability_interner.borrow_mut().intern(stab, |stab| {
+            self.global_interners.arena.alloc(stab)
+        })
     }
 
     pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails {
-        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) = layout_interner.replace(interned) {
-            bug!("Tried to overwrite interned Layout: {:?}", prev)
-        }
-        interned
+        self.layout_interner.borrow_mut().intern(layout, |layout| {
+            self.global_arenas.layout.alloc(layout)
+        })
     }
 
     /// Returns a range of the start/end indices specified with the
@@ -1523,12 +1493,6 @@
             BorrowckMode::Ast => match self.sess.edition() {
                 Edition::Edition2015 => BorrowckMode::Ast,
                 Edition::Edition2018 => BorrowckMode::Migrate,
-
-                // For now, future editions mean Migrate. (But it
-                // would make a lot of sense for it to be changed to
-                // `BorrowckMode::Mir`, depending on how we plan to
-                // time the forcing of full migration to NLL.)
-                _ => BorrowckMode::Migrate,
             },
         }
     }
@@ -2193,7 +2157,7 @@
                 };
                 $(let mut $variant = total;)*
 
-                for &Interned(t) in tcx.interners.type_.borrow().iter() {
+                for &Interned(t) in tcx.interners.type_.borrow().keys() {
                     let variant = match t.sty {
                         ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
                             ty::Float(..) | ty::Str | ty::Never => continue,
@@ -2252,6 +2216,13 @@
 /// An entry in an interner.
 struct Interned<'tcx, T: 'tcx+?Sized>(&'tcx T);
 
+impl<'tcx, T: 'tcx+?Sized> Clone for Interned<'tcx, T> {
+    fn clone(&self) -> Self {
+        Interned(self.0)
+    }
+}
+impl<'tcx, T: 'tcx+?Sized> Copy for Interned<'tcx, T> {}
+
 // NB: An Interned<Ty> compares and hashes as a sty.
 impl<'tcx> PartialEq for Interned<'tcx, TyS<'tcx>> {
     fn eq(&self, other: &Interned<'tcx, TyS<'tcx>>) -> bool {
@@ -2372,37 +2343,28 @@
                 // determine that all contents are in the global tcx.
                 // See comments on Lift for why we can't use that.
                 if ($keep_in_local_tcx)(&v) {
-                    let mut interner = self.interners.$name.borrow_mut();
-                    if let Some(&Interned(v)) = interner.get(key) {
-                        return v;
-                    }
+                    self.interners.$name.borrow_mut().intern_ref(key, || {
+                        // Make sure we don't end up with inference
+                        // types/regions in the global tcx.
+                        if self.is_global() {
+                            bug!("Attempted to intern `{:?}` which contains \
+                                inference types/regions in the global type context",
+                                v);
+                        }
 
-                    // Make sure we don't end up with inference
-                    // types/regions in the global tcx.
-                    if self.is_global() {
-                        bug!("Attempted to intern `{:?}` which contains \
-                              inference types/regions in the global type context",
-                             v);
-                    }
-
-                    let i = $alloc_method(&self.interners.arena, v);
-                    interner.insert(Interned(i));
-                    i
+                        Interned($alloc_method(&self.interners.arena, v))
+                    }).0
                 } else {
-                    let mut interner = self.global_interners.$name.borrow_mut();
-                    if let Some(&Interned(v)) = interner.get(key) {
-                        return v;
-                    }
-
-                    // This transmutes $alloc<'tcx> to $alloc<'gcx>
-                    let v = unsafe {
-                        mem::transmute(v)
-                    };
-                    let i: &$lt_tcx $ty = $alloc_method(&self.global_interners.arena, v);
-                    // Cast to 'gcx
-                    let i = unsafe { mem::transmute(i) };
-                    interner.insert(Interned(i));
-                    i
+                    self.global_interners.$name.borrow_mut().intern_ref(key, || {
+                        // This transmutes $alloc<'tcx> to $alloc<'gcx>
+                        let v = unsafe {
+                            mem::transmute(v)
+                        };
+                        let i: &$lt_tcx $ty = $alloc_method(&self.global_interners.arena, v);
+                        // Cast to 'gcx
+                        let i = unsafe { mem::transmute(i) };
+                        Interned(i)
+                    }).0
                 }
             }
         }
@@ -2515,6 +2477,7 @@
         self.mk_fn_ptr(converted_sig)
     }
 
+    #[inline]
     pub fn mk_ty(&self, st: TyKind<'tcx>) -> Ty<'tcx> {
         CtxtInterners::intern_ty(&self.interners, &self.global_interners, st)
     }
@@ -2548,19 +2511,23 @@
         }
     }
 
+    #[inline]
     pub fn mk_str(self) -> Ty<'tcx> {
         self.mk_ty(Str)
     }
 
+    #[inline]
     pub fn mk_static_str(self) -> Ty<'tcx> {
         self.mk_imm_ref(self.types.re_static, self.mk_str())
     }
 
+    #[inline]
     pub fn mk_adt(self, def: &'tcx AdtDef, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
         // take a copy of substs so that we own the vectors inside
         self.mk_ty(Adt(def, substs))
     }
 
+    #[inline]
     pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
         self.mk_ty(Foreign(def_id))
     }
@@ -2584,42 +2551,52 @@
         self.mk_ty(Adt(adt_def, substs))
     }
 
+    #[inline]
     pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
         self.mk_ty(RawPtr(tm))
     }
 
+    #[inline]
     pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
         self.mk_ty(Ref(r, tm.ty, tm.mutbl))
     }
 
+    #[inline]
     pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutMutable})
     }
 
+    #[inline]
     pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
     }
 
+    #[inline]
     pub fn mk_mut_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutMutable})
     }
 
+    #[inline]
     pub fn mk_imm_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
     }
 
+    #[inline]
     pub fn mk_nil_ptr(self) -> Ty<'tcx> {
         self.mk_imm_ptr(self.mk_unit())
     }
 
+    #[inline]
     pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
         self.mk_ty(Array(ty, ty::Const::from_usize(self, n)))
     }
 
+    #[inline]
     pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ty(Slice(ty))
     }
 
+    #[inline]
     pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
         self.mk_ty(Tuple(self.intern_type_list(ts)))
     }
@@ -2628,10 +2605,12 @@
         iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(ts))))
     }
 
+    #[inline]
     pub fn mk_unit(self) -> Ty<'tcx> {
-        self.intern_tup(&[])
+        self.types.unit
     }
 
+    #[inline]
     pub fn mk_diverging_default(self) -> Ty<'tcx> {
         if self.features().never_type {
             self.types.never
@@ -2640,19 +2619,23 @@
         }
     }
 
+    #[inline]
     pub fn mk_bool(self) -> Ty<'tcx> {
         self.mk_ty(Bool)
     }
 
+    #[inline]
     pub fn mk_fn_def(self, def_id: DefId,
                      substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
         self.mk_ty(FnDef(def_id, substs))
     }
 
+    #[inline]
     pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
         self.mk_ty(FnPtr(fty))
     }
 
+    #[inline]
     pub fn mk_dynamic(
         self,
         obj: ty::Binder<&'tcx List<ExistentialPredicate<'tcx>>>,
@@ -2661,6 +2644,7 @@
         self.mk_ty(Dynamic(obj, reg))
     }
 
+    #[inline]
     pub fn mk_projection(self,
                          item_def_id: DefId,
                          substs: &'tcx Substs<'tcx>)
@@ -2671,11 +2655,13 @@
             }))
         }
 
+    #[inline]
     pub fn mk_closure(self, closure_id: DefId, closure_substs: ClosureSubsts<'tcx>)
                       -> Ty<'tcx> {
         self.mk_ty(Closure(closure_id, closure_substs))
     }
 
+    #[inline]
     pub fn mk_generator(self,
                         id: DefId,
                         generator_substs: GeneratorSubsts<'tcx>,
@@ -2684,34 +2670,41 @@
         self.mk_ty(Generator(id, generator_substs, movability))
     }
 
+    #[inline]
     pub fn mk_generator_witness(self, types: ty::Binder<&'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
         self.mk_ty(GeneratorWitness(types))
     }
 
+    #[inline]
     pub fn mk_var(self, v: TyVid) -> Ty<'tcx> {
         self.mk_infer(TyVar(v))
     }
 
+    #[inline]
     pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
         self.mk_infer(IntVar(v))
     }
 
+    #[inline]
     pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
         self.mk_infer(FloatVar(v))
     }
 
+    #[inline]
     pub fn mk_infer(self, it: InferTy) -> Ty<'tcx> {
         self.mk_ty(Infer(it))
     }
 
+    #[inline]
     pub fn mk_ty_param(self,
                        index: u32,
                        name: InternedString) -> Ty<'tcx> {
         self.mk_ty(Param(ParamTy { idx: index, name: name }))
     }
 
+    #[inline]
     pub fn mk_self_type(self) -> Ty<'tcx> {
-        self.mk_ty_param(0, keywords::SelfType.name().as_interned_str())
+        self.mk_ty_param(0, keywords::SelfUpper.name().as_interned_str())
     }
 
     pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> Kind<'tcx> {
@@ -2723,6 +2716,7 @@
         }
     }
 
+    #[inline]
     pub fn mk_opaque(self, def_id: DefId, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
         self.mk_ty(Opaque(def_id, substs))
     }
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index 6f0e8d4..20f6459 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -374,6 +374,7 @@
 }
 
 impl<'a, 'gcx, 'tcx> RegionFolder<'a, 'gcx, 'tcx> {
+    #[inline]
     pub fn new(
         tcx: TyCtxt<'a, 'gcx, 'tcx>,
         skipped_regions: &'a mut bool,
@@ -679,24 +680,31 @@
 // vars. See comment on `shift_vars_through_binders` method in
 // `subst.rs` for more details.
 
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+enum Direction {
+    In,
+    Out,
+}
+
 struct Shifter<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
-
     current_index: ty::DebruijnIndex,
     amount: u32,
+    direction: Direction,
 }
 
 impl Shifter<'a, 'gcx, 'tcx> {
-    pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, amount: u32) -> Self {
+    pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, amount: u32, direction: Direction) -> Self {
         Shifter {
             tcx,
             current_index: ty::INNERMOST,
             amount,
+            direction,
         }
     }
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Shifter<'a, 'gcx, 'tcx> {
+impl TypeFolder<'gcx, 'tcx> for Shifter<'a, 'gcx, 'tcx> {
     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
 
     fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
@@ -712,7 +720,14 @@
                 if self.amount == 0 || debruijn < self.current_index {
                     r
                 } else {
-                    let shifted = ty::ReLateBound(debruijn.shifted_in(self.amount), br);
+                    let debruijn = match self.direction {
+                        Direction::In => debruijn.shifted_in(self.amount),
+                        Direction::Out => {
+                            assert!(debruijn.as_u32() >= self.amount);
+                            debruijn.shifted_out(self.amount)
+                        }
+                    };
+                    let shifted = ty::ReLateBound(debruijn, br);
                     self.tcx.mk_region(shifted)
                 }
             }
@@ -726,8 +741,15 @@
                 if self.amount == 0 || debruijn < self.current_index {
                     ty
                 } else {
+                    let debruijn = match self.direction {
+                        Direction::In => debruijn.shifted_in(self.amount),
+                        Direction::Out => {
+                            assert!(debruijn.as_u32() >= self.amount);
+                            debruijn.shifted_out(self.amount)
+                        }
+                    };
                     self.tcx.mk_ty(
-                        ty::Bound(debruijn.shifted_in(self.amount), bound_ty)
+                        ty::Bound(debruijn, bound_ty)
                     )
                 }
             }
@@ -760,7 +782,18 @@
     debug!("shift_vars(value={:?}, amount={})",
            value, amount);
 
-    value.fold_with(&mut Shifter::new(tcx, amount))
+    value.fold_with(&mut Shifter::new(tcx, amount, Direction::In))
+}
+
+pub fn shift_out_vars<'a, 'gcx, 'tcx, T>(
+    tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    value: &T,
+    amount: u32
+) -> T where T: TypeFoldable<'tcx> {
+    debug!("shift_out_vars(value={:?}, amount={})",
+           value, amount);
+
+    value.fold_with(&mut Shifter::new(tcx, amount, Direction::Out))
 }
 
 /// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs
index 56fe479..721d5e1 100644
--- a/src/librustc/ty/inhabitedness/mod.rs
+++ b/src/librustc/ty/inhabitedness/mod.rs
@@ -167,23 +167,16 @@
         substs: &'tcx Substs<'tcx>,
         adt_kind: AdtKind) -> DefIdForest
     {
-        match adt_kind {
-            AdtKind::Union => {
-                DefIdForest::intersection(tcx, self.fields.iter().map(|f| {
-                    f.uninhabited_from(visited, tcx, substs, false)
-                }))
-            },
-            AdtKind::Struct => {
-                DefIdForest::union(tcx, self.fields.iter().map(|f| {
-                    f.uninhabited_from(visited, tcx, substs, false)
-                }))
-            },
-            AdtKind::Enum => {
-                DefIdForest::union(tcx, self.fields.iter().map(|f| {
-                    f.uninhabited_from(visited, tcx, substs, true)
-                }))
-            },
-        }
+        let is_enum = match adt_kind {
+            // For now, `union`s are never considered uninhabited.
+            // The precise semantics of inhabitedness with respect to unions is currently undecided.
+            AdtKind::Union => return DefIdForest::empty(),
+            AdtKind::Enum => true,
+            AdtKind::Struct => false,
+        };
+        DefIdForest::union(tcx, self.fields.iter().map(|f| {
+            f.uninhabited_from(visited, tcx, substs, is_enum)
+        }))
     }
 }
 
@@ -194,8 +187,8 @@
         visited: &mut FxHashMap<DefId, FxHashSet<&'tcx Substs<'tcx>>>,
         tcx: TyCtxt<'a, 'gcx, 'tcx>,
         substs: &'tcx Substs<'tcx>,
-        is_enum: bool) -> DefIdForest
-    {
+        is_enum: bool,
+    ) -> DefIdForest {
         let mut data_uninhabitedness = move || {
             self.ty(tcx, substs).uninhabited_from(visited, tcx)
         };
@@ -253,14 +246,16 @@
                 let substs_set = visited.get_mut(&def.did).unwrap();
                 substs_set.remove(substs);
                 ret
-            },
+            }
 
             Never => DefIdForest::full(tcx),
+
             Tuple(ref tys) => {
                 DefIdForest::union(tcx, tys.iter().map(|ty| {
                     ty.uninhabited_from(visited, tcx)
                 }))
-            },
+            }
+
             Array(ty, len) => {
                 match len.assert_usize(tcx) {
                     // If the array is definitely non-empty, it's uninhabited if
@@ -269,9 +264,13 @@
                     _ => DefIdForest::empty()
                 }
             }
-            Ref(_, ty, _) => {
-                ty.uninhabited_from(visited, tcx)
-            }
+
+            // References to uninitialised memory is valid for any type, including
+            // uninhabited types, in unsafe code, so we treat all references as
+            // inhabited.
+            // The precise semantics of inhabitedness with respect to references is currently
+            // undecided.
+            Ref(..) => DefIdForest::empty(),
 
             _ => DefIdForest::empty(),
         }
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 411a6e7..a24920d 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -347,9 +347,10 @@
 ) -> Option<Instance<'tcx>> {
     let def_id = trait_item.def_id;
     debug!("resolve_associated_item(trait_item={:?}, \
+            param_env={:?}, \
             trait_id={:?}, \
             rcvr_substs={:?})",
-           def_id, trait_id, rcvr_substs);
+            def_id, param_env, trait_id, rcvr_substs);
 
     let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
     let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)));
@@ -359,7 +360,7 @@
     match vtbl {
         traits::VtableImpl(impl_data) => {
             let (def_id, substs) = traits::find_associated_item(
-                tcx, trait_item, rcvr_substs, &impl_data);
+                tcx, param_env, trait_item, rcvr_substs, &impl_data);
             let substs = tcx.erase_regions(&substs);
             Some(ty::Instance::new(def_id, substs))
         }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index b371f45..4633ab1 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1275,6 +1275,7 @@
         self.skip_binder().projection_ty.item_def_id
     }
 
+    #[inline]
     pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'_, '_, '_>) -> PolyTraitRef<'tcx> {
         // Note: unlike with `TraitRef::to_poly_trait_ref()`,
         // `self.0.trait_ref` is permitted to have escaping regions.
@@ -1633,6 +1634,7 @@
     /// there are no where clauses in scope. Hidden types (like `impl
     /// Trait`) are left hidden, so this is suitable for ordinary
     /// type-checking.
+    #[inline]
     pub fn empty() -> Self {
         Self::new(List::empty(), Reveal::UserFacing)
     }
@@ -1644,11 +1646,13 @@
     ///
     /// N.B. If you want to have predicates in scope, use `ParamEnv::new`,
     /// or invoke `param_env.with_reveal_all()`.
+    #[inline]
     pub fn reveal_all() -> Self {
         Self::new(List::empty(), Reveal::All)
     }
 
     /// Construct a trait environment with the given set of predicates.
+    #[inline]
     pub fn new(caller_bounds: &'tcx List<ty::Predicate<'tcx>>,
                reveal: Reveal)
                -> Self {
@@ -2148,6 +2152,7 @@
         }
     }
 
+    #[inline]
     pub fn variant_descr(&self) -> &'static str {
         match self.adt_kind() {
             AdtKind::Struct => "struct",
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index bb33def..5d12aae 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -591,7 +591,7 @@
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::derive_registrar_fn<'tcx> {
+impl<'tcx> QueryDescription<'tcx> for queries::proc_macro_decls_static<'tcx> {
     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
         "looking up the derive registrar for a crate".into()
     }
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index 22bd1e2..699c2d1 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -470,7 +470,7 @@
         [] 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 proc_macro_decls_static: ProcMacroDeclsStatic(CrateNum) -> Option<DefId>,
         [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator,
         [] fn crate_hash: CrateHash(CrateNum) -> Svh,
         [] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol,
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index efee39a..5f33d46 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -1200,7 +1200,7 @@
         DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); }
         DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
         DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
-        DepKind::DeriveRegistrarFn => { force!(derive_registrar_fn, krate!()); }
+        DepKind::ProcMacroDeclsStatic => { force!(proc_macro_decls_static, krate!()); }
         DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); }
         DepKind::CrateHash => { force!(crate_hash, krate!()); }
         DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); }
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 082c1bd..1b64a68 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -25,6 +25,7 @@
 use std::iter;
 use rustc_target::spec::abi;
 use hir as ast;
+use traits;
 
 pub type RelateResult<'tcx, T> = Result<T, TypeError<'tcx>>;
 
@@ -371,6 +372,10 @@
             bug!("var types encountered in super_relate_tys")
         }
 
+        (ty::Bound(..), _) | (_, ty::Bound(..)) => {
+            bug!("bound types encountered in super_relate_tys")
+        }
+
         (&ty::Error, _) | (_, &ty::Error) =>
         {
             Ok(tcx.types.err)
@@ -394,6 +399,10 @@
             Ok(a)
         }
 
+        (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => {
+            Ok(a)
+        }
+
         (&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs))
             if a_def == b_def =>
         {
@@ -556,8 +565,13 @@
             Ok(tcx.mk_fn_ptr(fty))
         }
 
-        (&ty::Projection(ref a_data), &ty::Projection(ref b_data)) =>
-        {
+        (ty::UnnormalizedProjection(a_data), ty::UnnormalizedProjection(b_data)) => {
+            let projection_ty = relation.relate(a_data, b_data)?;
+            Ok(tcx.mk_ty(ty::UnnormalizedProjection(projection_ty)))
+        }
+
+        // these two are already handled downstream in case of lazy normalization
+        (ty::Projection(a_data), ty::Projection(b_data)) => {
             let projection_ty = relation.relate(a_data, b_data)?;
             Ok(tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs))
         }
@@ -710,6 +724,283 @@
     }
 }
 
+impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &ty::TraitPredicate<'tcx>,
+        b: &ty::TraitPredicate<'tcx>
+    ) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        Ok(ty::TraitPredicate {
+            trait_ref: relation.relate(&a.trait_ref, &b.trait_ref)?,
+        })
+    }
+}
+
+impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &ty::ProjectionPredicate<'tcx>,
+        b: &ty::ProjectionPredicate<'tcx>,
+    ) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        Ok(ty::ProjectionPredicate {
+            projection_ty: relation.relate(&a.projection_ty, &b.projection_ty)?,
+            ty: relation.relate(&a.ty, &b.ty)?,
+        })
+    }
+}
+
+impl<'tcx> Relate<'tcx> for traits::WhereClause<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::WhereClause<'tcx>,
+        b: &traits::WhereClause<'tcx>
+    ) -> RelateResult<'tcx, traits::WhereClause<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        use traits::WhereClause::*;
+        match (a, b) {
+            (Implemented(a_pred), Implemented(b_pred)) => {
+                Ok(Implemented(relation.relate(a_pred, b_pred)?))
+            }
+
+            (ProjectionEq(a_pred), ProjectionEq(b_pred)) => {
+                Ok(ProjectionEq(relation.relate(a_pred, b_pred)?))
+            }
+
+            (RegionOutlives(a_pred), RegionOutlives(b_pred)) => {
+                Ok(RegionOutlives(ty::OutlivesPredicate(
+                    relation.relate(&a_pred.0, &b_pred.0)?,
+                    relation.relate(&a_pred.1, &b_pred.1)?,
+                )))
+            }
+
+            (TypeOutlives(a_pred), TypeOutlives(b_pred)) => {
+                Ok(TypeOutlives(ty::OutlivesPredicate(
+                    relation.relate(&a_pred.0, &b_pred.0)?,
+                    relation.relate(&a_pred.1, &b_pred.1)?,
+                )))
+            }
+
+            _ =>  Err(TypeError::Mismatch),
+        }
+    }
+}
+
+impl<'tcx> Relate<'tcx> for traits::WellFormed<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::WellFormed<'tcx>,
+        b: &traits::WellFormed<'tcx>
+    ) -> RelateResult<'tcx, traits::WellFormed<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        use traits::WellFormed::*;
+        match (a, b) {
+            (Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)),
+            (Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)),
+            _ =>  Err(TypeError::Mismatch),
+        }
+    }
+}
+
+impl<'tcx> Relate<'tcx> for traits::FromEnv<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::FromEnv<'tcx>,
+        b: &traits::FromEnv<'tcx>
+    ) -> RelateResult<'tcx, traits::FromEnv<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        use traits::FromEnv::*;
+        match (a, b) {
+            (Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)),
+            (Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)),
+            _ =>  Err(TypeError::Mismatch),
+        }
+    }
+}
+
+impl<'tcx> Relate<'tcx> for traits::DomainGoal<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::DomainGoal<'tcx>,
+        b: &traits::DomainGoal<'tcx>
+    ) -> RelateResult<'tcx, traits::DomainGoal<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        use traits::DomainGoal::*;
+        match (a, b) {
+            (Holds(a_wc), Holds(b_wc)) => Ok(Holds(relation.relate(a_wc, b_wc)?)),
+            (WellFormed(a_wf), WellFormed(b_wf)) => Ok(WellFormed(relation.relate(a_wf, b_wf)?)),
+            (FromEnv(a_fe), FromEnv(b_fe)) => Ok(FromEnv(relation.relate(a_fe, b_fe)?)),
+
+            (Normalize(a_pred), Normalize(b_pred)) => {
+                Ok(Normalize(relation.relate(a_pred, b_pred)?))
+            }
+
+            _ =>  Err(TypeError::Mismatch),
+        }
+    }
+}
+
+impl<'tcx> Relate<'tcx> for traits::Goal<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::Goal<'tcx>,
+        b: &traits::Goal<'tcx>
+    ) -> RelateResult<'tcx, traits::Goal<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        use traits::GoalKind::*;
+        match (a, b) {
+            (Implies(a_clauses, a_goal), Implies(b_clauses, b_goal)) => {
+                let clauses = relation.relate(a_clauses, b_clauses)?;
+                let goal = relation.relate(a_goal, b_goal)?;
+                Ok(relation.tcx().mk_goal(Implies(clauses, goal)))
+            }
+
+            (And(a_left, a_right), And(b_left, b_right)) => {
+                let left = relation.relate(a_left, b_left)?;
+                let right = relation.relate(a_right, b_right)?;
+                Ok(relation.tcx().mk_goal(And(left, right)))
+            }
+
+            (Not(a_goal), Not(b_goal)) => {
+                let goal = relation.relate(a_goal, b_goal)?;
+                Ok(relation.tcx().mk_goal(Not(goal)))
+            }
+
+            (DomainGoal(a_goal), DomainGoal(b_goal)) => {
+                let goal = relation.relate(a_goal, b_goal)?;
+                Ok(relation.tcx().mk_goal(DomainGoal(goal)))
+            }
+
+            (Quantified(a_qkind, a_goal), Quantified(b_qkind, b_goal))
+                if a_qkind == b_qkind =>
+            {
+                let goal = relation.relate(a_goal, b_goal)?;
+                Ok(relation.tcx().mk_goal(Quantified(*a_qkind, goal)))
+            }
+
+            (CannotProve, CannotProve) => Ok(*a),
+
+            _ => Err(TypeError::Mismatch),
+        }
+    }
+}
+
+impl<'tcx> Relate<'tcx> for traits::Goals<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::Goals<'tcx>,
+        b: &traits::Goals<'tcx>
+    ) -> RelateResult<'tcx, traits::Goals<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        if a.len() != b.len() {
+            return Err(TypeError::Mismatch);
+        }
+
+        let tcx = relation.tcx();
+        let goals = a.iter().zip(b.iter()).map(|(a, b)| relation.relate(a, b));
+        Ok(tcx.mk_goals(goals)?)
+    }
+}
+
+impl<'tcx> Relate<'tcx> for traits::Clause<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::Clause<'tcx>,
+        b: &traits::Clause<'tcx>
+    ) -> RelateResult<'tcx, traits::Clause<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        use traits::Clause::*;
+        match (a, b) {
+            (Implies(a_clause), Implies(b_clause)) => {
+                let clause = relation.relate(a_clause, b_clause)?;
+                Ok(Implies(clause))
+            }
+
+            (ForAll(a_clause), ForAll(b_clause)) => {
+                let clause = relation.relate(a_clause, b_clause)?;
+                Ok(ForAll(clause))
+            }
+
+            _ => Err(TypeError::Mismatch),
+        }
+    }
+}
+
+impl<'tcx> Relate<'tcx> for traits::Clauses<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::Clauses<'tcx>,
+        b: &traits::Clauses<'tcx>
+    ) -> RelateResult<'tcx, traits::Clauses<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        if a.len() != b.len() {
+            return Err(TypeError::Mismatch);
+        }
+
+        let tcx = relation.tcx();
+        let clauses = a.iter().zip(b.iter()).map(|(a, b)| relation.relate(a, b));
+        Ok(tcx.mk_clauses(clauses)?)
+    }
+}
+
+impl<'tcx> Relate<'tcx> for traits::ProgramClause<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::ProgramClause<'tcx>,
+        b: &traits::ProgramClause<'tcx>
+    ) -> RelateResult<'tcx, traits::ProgramClause<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        Ok(traits::ProgramClause {
+            goal: relation.relate(&a.goal, &b.goal)?,
+            hypotheses: relation.relate(&a.hypotheses, &b.hypotheses)?,
+            category: traits::ProgramClauseCategory::Other,
+        })
+    }
+}
+
+impl<'tcx> Relate<'tcx> for traits::Environment<'tcx> {
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::Environment<'tcx>,
+        b: &traits::Environment<'tcx>
+    ) -> RelateResult<'tcx, traits::Environment<'tcx>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        Ok(traits::Environment {
+            clauses: relation.relate(&a.clauses, &b.clauses)?,
+        })
+    }
+}
+
+impl<'tcx, G> Relate<'tcx> for traits::InEnvironment<'tcx, G>
+    where G: Relate<'tcx>
+{
+    fn relate<'a, 'gcx, R>(
+        relation: &mut R,
+        a: &traits::InEnvironment<'tcx, G>,
+        b: &traits::InEnvironment<'tcx, G>
+    ) -> RelateResult<'tcx, traits::InEnvironment<'tcx, G>>
+        where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'tcx, 'tcx: 'a
+    {
+        Ok(traits::InEnvironment {
+            environment: relation.relate(&a.environment, &b.environment)?,
+            goal: relation.relate(&a.goal, &b.goal)?,
+        })
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // Error handling
 
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 3056abb..d861fb3 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -667,6 +667,7 @@
         }
     }
 
+    #[inline]
     pub fn self_ty(&self) -> Ty<'tcx> {
         self.substs.type_at(0)
     }
@@ -978,15 +979,18 @@
 pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
 
 impl<'tcx> PolyFnSig<'tcx> {
+    #[inline]
     pub fn inputs(&self) -> Binder<&'tcx [Ty<'tcx>]> {
         self.map_bound_ref(|fn_sig| fn_sig.inputs())
     }
+    #[inline]
     pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
         self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
     }
     pub fn inputs_and_output(&self) -> ty::Binder<&'tcx List<Ty<'tcx>>> {
         self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
     }
+    #[inline]
     pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
         self.map_bound_ref(|fn_sig| fn_sig.output())
     }
@@ -1016,7 +1020,7 @@
     }
 
     pub fn for_self() -> ParamTy {
-        ParamTy::new(0, keywords::SelfType.name().as_interned_str())
+        ParamTy::new(0, keywords::SelfUpper.name().as_interned_str())
     }
 
     pub fn for_def(def: &ty::GenericParamDef) -> ParamTy {
@@ -1031,7 +1035,7 @@
         // FIXME(#50125): Ignoring `Self` with `idx != 0` might lead to weird behavior elsewhere,
         // but this should only be possible when using `-Z continue-parse-after-error` like
         // `compile-fail/issue-36638.rs`.
-        self.name == keywords::SelfType.name().as_str() && self.idx == 0
+        self.name == keywords::SelfUpper.name().as_str() && self.idx == 0
     }
 }
 
@@ -1138,7 +1142,7 @@
 ///
 /// [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/traits/hrtb.html
+/// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/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
@@ -1548,6 +1552,7 @@
         }
     }
 
+    #[inline]
     pub fn is_ty_var(&self) -> bool {
         match self.sty {
             Infer(TyVar(_)) => true,
@@ -1732,6 +1737,7 @@
         }
     }
 
+    #[inline]
     pub fn is_integral(&self) -> bool {
         match self.sty {
             Infer(IntVar(_)) | Int(_) | Uint(_) => true,
@@ -1762,6 +1768,7 @@
         }
     }
 
+    #[inline]
     pub fn is_fp(&self) -> bool {
         match self.sty {
             Infer(FloatVar(_)) | Float(_) => true,
@@ -1780,6 +1787,13 @@
         }
     }
 
+    pub fn is_pointer_sized(&self) -> bool {
+        match self.sty {
+            Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => true,
+            _ => false,
+        }
+    }
+
     pub fn is_machine(&self) -> bool {
         match self.sty {
             Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false,
@@ -1845,6 +1859,7 @@
         }
     }
 
+    #[inline]
     pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
         match self.sty {
             Adt(adt, _) => Some(adt),
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index bcc0b80..c6ba20d 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -24,12 +24,11 @@
 use syntax_pos::{SpanData};
 use ty::TyCtxt;
 use dep_graph::{DepNode};
-use proc_macro;
 use lazy_static;
 use session::Session;
 
 // The name of the associated type for `Fn` return types
-pub const FN_OUTPUT_NAME: &'static str = "Output";
+pub const FN_OUTPUT_NAME: &str = "Output";
 
 // Useful type to use with `Result<>` indicate that an error has already
 // been reported to the user, so no need to continue checking.
@@ -47,14 +46,13 @@
 }
 
 fn panic_hook(info: &panic::PanicInfo<'_>) {
-    if !proc_macro::__internal::in_sess() {
-        (*DEFAULT_HOOK)(info);
+    (*DEFAULT_HOOK)(info);
 
-        let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false);
+    let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false);
 
-        if backtrace {
-            TyCtxt::try_print_query_stack();
-        }
+    if backtrace {
+        TyCtxt::try_print_query_stack();
+    }
 
         #[cfg(windows)]
         unsafe {
@@ -66,7 +64,6 @@
                 DebugBreak();
             }
         }
-    }
 }
 
 pub fn install_panic_hook() {
diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs
index 6540a09..bea3453 100644
--- a/src/librustc/util/profiling.rs
+++ b/src/librustc/util/profiling.rs
@@ -102,7 +102,7 @@
                         };
 
                     json.push_str(&format!(
-                        "{{ \"category\": {}, \"time_ms\": {},
+                        "{{ \"category\": \"{}\", \"time_ms\": {},\
                             \"query_count\": {}, \"query_hits\": {} }},",
                         stringify!($name),
                         self.times.$name / 1_000_000,
diff --git a/src/librustc_borrowck/borrowck/README.md b/src/librustc_borrowck/borrowck/README.md
index 8bc0b49..a05c56e 100644
--- a/src/librustc_borrowck/borrowck/README.md
+++ b/src/librustc_borrowck/borrowck/README.md
@@ -3,7 +3,7 @@
 > 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
+[rustc guide]: https://rust-lang.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
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index a802729..e47e95a 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -615,7 +615,7 @@
                     let new_loan_str = &new_loan.kind.to_user_str();
                     self.bccx.cannot_reborrow_already_uniquely_borrowed(
                         new_loan.span, "closure", &nl, &new_loan_msg, new_loan_str,
-                        old_loan.span, &old_loan_msg, previous_end_span, Origin::Ast)
+                        old_loan.span, &old_loan_msg, previous_end_span, "", Origin::Ast)
                 }
                 (..) =>
                     self.bccx.cannot_reborrow_already_borrowed(
diff --git a/src/librustc_codegen_llvm/README.md b/src/librustc_codegen_llvm/README.md
index 8d1c9a5..dda2e5a 100644
--- a/src/librustc_codegen_llvm/README.md
+++ b/src/librustc_codegen_llvm/README.md
@@ -4,4 +4,4 @@
 
 For more information about how codegen works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/codegen.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/codegen.html
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index 3470d6f..5b6d157 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -212,7 +212,7 @@
             // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
             let can_store_through_cast_ptr = false;
             if can_store_through_cast_ptr {
-                let cast_ptr_llty = bx.cx().type_ptr_to(cast.llvm_type(bx.cx()));
+                let cast_ptr_llty = bx.type_ptr_to(cast.llvm_type(bx));
                 let cast_dst = bx.pointercast(dst.llval, cast_ptr_llty);
                 bx.store(val, cast_dst, self.layout.align.abi);
             } else {
@@ -231,9 +231,9 @@
                 //   bitcasting to the struct type yields invalid cast errors.
 
                 // We instead thus allocate some scratch space...
-                let scratch_size = cast.size(bx.cx());
-                let scratch_align = cast.align(bx.cx());
-                let llscratch = bx.alloca(cast.llvm_type(bx.cx()), "abi_cast", scratch_align);
+                let scratch_size = cast.size(bx);
+                let scratch_align = cast.align(bx);
+                let llscratch = bx.alloca(cast.llvm_type(bx), "abi_cast", scratch_align);
                 bx.lifetime_start(llscratch, scratch_size);
 
                 // ...where we first store the value...
@@ -245,7 +245,7 @@
                     self.layout.align.abi,
                     llscratch,
                     scratch_align,
-                    bx.cx().const_usize(self.layout.size.bytes()),
+                    bx.const_usize(self.layout.size.bytes()),
                     MemFlags::empty()
                 );
 
@@ -299,7 +299,7 @@
         ty.store(self, val, dst)
     }
     fn memory_ty(&self, ty: &ArgType<'tcx, Ty<'tcx>>) -> &'ll Type {
-        ty.memory_ty(self.cx())
+        ty.memory_ty(self)
     }
 }
 
@@ -780,7 +780,7 @@
             // by the LLVM verifier.
             if let layout::Int(..) = scalar.value {
                 if !scalar.is_bool() {
-                    let range = scalar.valid_range_exclusive(bx.cx());
+                    let range = scalar.valid_range_exclusive(bx);
                     if range.start != range.end {
                         bx.range_metadata(callsite, range);
                     }
diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs
index efbe7ca..294596c 100644
--- a/src/librustc_codegen_llvm/asm.rs
+++ b/src/librustc_codegen_llvm/asm.rs
@@ -57,7 +57,7 @@
 
         // Default per-arch clobbers
         // Basically what clang does
-        let arch_clobbers = match &self.cx().sess().target.target.arch[..] {
+        let arch_clobbers = match &self.sess().target.target.arch[..] {
             "x86" | "x86_64"  => vec!["~{dirflag}", "~{fpsr}", "~{flags}"],
             "mips" | "mips64" => vec!["~{$1}"],
             _                 => Vec::new()
@@ -76,9 +76,9 @@
         // Depending on how many outputs we have, the return type is different
         let num_outputs = output_types.len();
         let output_type = match num_outputs {
-            0 => self.cx().type_void(),
+            0 => self.type_void(),
             1 => output_types[0],
-            _ => self.cx().type_struct(&output_types, false)
+            _ => self.type_struct(&output_types, false)
         };
 
         let asm = CString::new(ia.asm.as_str().as_bytes()).unwrap();
@@ -108,13 +108,13 @@
         // back to source locations.  See #17552.
         unsafe {
             let key = "srcloc";
-            let kind = llvm::LLVMGetMDKindIDInContext(self.cx().llcx,
+            let kind = llvm::LLVMGetMDKindIDInContext(self.llcx,
                 key.as_ptr() as *const c_char, key.len() as c_uint);
 
-            let val: &'ll Value = self.cx().const_i32(ia.ctxt.outer().as_u32() as i32);
+            let val: &'ll Value = self.const_i32(ia.ctxt.outer().as_u32() as i32);
 
             llvm::LLVMSetMetadata(r, kind,
-                llvm::LLVMMDNodeInContext(self.cx().llcx, &val, 1));
+                llvm::LLVMMDNodeInContext(self.llcx, &val, 1));
         }
 
         true
diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs
index 89d84ac..68da145 100644
--- a/src/librustc_codegen_llvm/back/link.rs
+++ b/src/librustc_codegen_llvm/back/link.rs
@@ -72,12 +72,12 @@
            bug!("invalid output type `{:?}` for target os `{}`",
                 crate_type, sess.opts.target_triple);
         }
-        let mut out_files = link_binary_output(sess,
-                                               codegen_results,
-                                               crate_type,
-                                               outputs,
-                                               crate_name);
-        out_filenames.append(&mut out_files);
+        let out_files = link_binary_output(sess,
+                                           codegen_results,
+                                           crate_type,
+                                           outputs,
+                                           crate_name);
+        out_filenames.extend(out_files);
     }
 
     // Remove the temporary object file and metadata if we aren't saving temps
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index b5ebd04..99828e5 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -225,11 +225,12 @@
         // and we want to move everything to the same LLVM context. Currently the
         // way we know of to do that is to serialize them to a string and them parse
         // them later. Not great but hey, that's why it's "fat" LTO, right?
-        for module in modules {
+        serialized_modules.extend(modules.into_iter().map(|module| {
             let buffer = ModuleBuffer::new(module.module_llvm.llmod());
             let llmod_id = CString::new(&module.name[..]).unwrap();
-            serialized_modules.push((SerializedModule::Local(buffer), llmod_id));
-        }
+
+            (SerializedModule::Local(buffer), llmod_id)
+        }));
 
         // For all serialized bitcode files we parse them and link them in as we did
         // above, this is all mostly handled in C++. Like above, though, we don't
@@ -349,9 +350,10 @@
             .map(|&(_, ref wp)| (wp.cgu_name.clone(), wp.clone()))
             .collect();
 
-        let mut thin_buffers = Vec::new();
-        let mut module_names = Vec::new();
-        let mut thin_modules = Vec::new();
+        let full_scope_len = modules.len() + serialized_modules.len() + cached_modules.len();
+        let mut thin_buffers = Vec::with_capacity(modules.len());
+        let mut module_names = Vec::with_capacity(full_scope_len);
+        let mut thin_modules = Vec::with_capacity(full_scope_len);
 
         // FIXME: right now, like with fat LTO, we serialize all in-memory
         //        modules before working with them and ThinLTO. We really
@@ -360,7 +362,7 @@
         //        into the global index. It turns out that this loop is by far
         //        the most expensive portion of this small bit of global
         //        analysis!
-        for (i, module) in modules.iter().enumerate() {
+        for (i, module) in modules.into_iter().enumerate() {
             info!("local module: {} - {}", i, module.name);
             let name = CString::new(module.name.clone()).unwrap();
             let buffer = ThinBuffer::new(module.module_llvm.llmod());
@@ -406,7 +408,7 @@
         //        incremental ThinLTO first where we could actually avoid
         //        looking at upstream modules entirely sometimes (the contents,
         //        we must always unconditionally look at the index).
-        let mut serialized = Vec::new();
+        let mut serialized = Vec::with_capacity(serialized_modules.len() + cached_modules.len());
 
         let cached_modules = cached_modules.into_iter().map(|(sm, wp)| {
             (sm, CString::new(wp.cgu_name).unwrap())
diff --git a/src/librustc_codegen_llvm/back/rpath.rs b/src/librustc_codegen_llvm/back/rpath.rs
index ee4a9b3..73a7366 100644
--- a/src/librustc_codegen_llvm/back/rpath.rs
+++ b/src/librustc_codegen_llvm/back/rpath.rs
@@ -31,14 +31,12 @@
         return Vec::new();
     }
 
-    let mut flags = Vec::new();
-
     debug!("preparing the RPATH!");
 
     let libs = config.used_crates.clone();
     let libs = libs.iter().filter_map(|&(_, ref l)| l.option()).collect::<Vec<_>>();
     let rpaths = get_rpaths(config, &libs);
-    flags.extend_from_slice(&rpaths_to_flags(&rpaths));
+    let mut flags = rpaths_to_flags(&rpaths);
 
     // Use DT_RUNPATH instead of DT_RPATH if available
     if config.linker_is_gnu {
@@ -49,7 +47,8 @@
 }
 
 fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
-    let mut ret = Vec::new();
+    let mut ret = Vec::with_capacity(rpaths.len()); // the minimum needed capacity
+
     for rpath in rpaths {
         if rpath.contains(',') {
             ret.push("-Wl,-rpath".into());
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 7945d38..2ddbd0c 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -23,7 +23,7 @@
 use ModuleLlvm;
 use rustc_codegen_ssa::{ModuleCodegen, CompiledModule};
 use rustc::util::common::time_ext;
-use rustc_fs_util::{path2cstr, link_or_copy};
+use rustc_fs_util::{path_to_c_string, link_or_copy};
 use rustc_data_structures::small_c_str::SmallCStr;
 use errors::{self, Handler, FatalError};
 use type_::Type;
@@ -80,7 +80,7 @@
         output: &Path,
         file_type: llvm::FileType) -> Result<(), FatalError> {
     unsafe {
-        let output_c = path2cstr(output);
+        let output_c = path_to_c_string(output);
         let result = llvm::LLVMRustWriteOutputFile(target, pm, m, output_c.as_ptr(), file_type);
         if result.into_result().is_err() {
             let msg = format!("could not write output to {}", output.display());
@@ -211,7 +211,7 @@
         let ext = format!("{}.bc", name);
         let cgu = Some(&module.name[..]);
         let path = cgcx.output_filenames.temp_path_ext(&ext, cgu);
-        let cstr = path2cstr(&path);
+        let cstr = path_to_c_string(&path);
         let llmod = module.module_llvm.llmod();
         llvm::LLVMWriteBitcodeToFile(llmod, cstr.as_ptr());
     }
@@ -324,7 +324,7 @@
 
     if config.emit_no_opt_bc {
         let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name);
-        let out = path2cstr(&out);
+        let out = path_to_c_string(&out);
         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
     }
 
@@ -371,15 +371,16 @@
                     .unwrap_or(llvm::CodeGenOptLevel::None);
                 let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal ||
                     (cgcx.lto != Lto::Fat && cgcx.opts.debugging_opts.cross_lang_lto.enabled());
+                with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| {
+                    llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
+                    llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
+                });
+
                 have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto;
                 if using_thin_buffers && !prepare_for_thin_lto {
                     assert!(addpass("name-anon-globals"));
                     have_name_anon_globals_pass = true;
                 }
-                with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| {
-                    llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
-                    llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
-                })
             }
 
             for pass in &config.passes {
@@ -530,7 +531,7 @@
             || -> Result<(), FatalError> {
             if config.emit_ir {
                 let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
-                let out = path2cstr(&out);
+                let out = path_to_c_string(&out);
 
                 extern "C" fn demangle_callback(input_ptr: *const c_char,
                                                 input_len: size_t,
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index 78693a3..904e5d7 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -195,7 +195,9 @@
             // Run replace-all-uses-with for statics that need it
             for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() {
                 unsafe {
-                    cx.static_replace_all_uses(old_g, new_g)
+                    let bitcast = llvm::LLVMConstPointerCast(new_g, cx.val_ty(old_g));
+                    llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
+                    llvm::LLVMDeleteGlobal(old_g);
                 }
             }
 
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index d2a99ea..a95ddef 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -20,6 +20,7 @@
 use libc::{c_uint, c_char};
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::layout::{self, Align, Size, TyLayout};
+use rustc::hir::def_id::DefId;
 use rustc::session::config;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_codegen_ssa::traits::*;
@@ -29,7 +30,7 @@
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use std::borrow::Cow;
 use std::ffi::CStr;
-use std::ops::Range;
+use std::ops::{Deref, Range};
 use std::ptr;
 
 // All Builders must have an llfn associated with them
@@ -58,7 +59,6 @@
     type Value = <CodegenCx<'ll, 'tcx> as BackendTypes>::Value;
     type BasicBlock = <CodegenCx<'ll, 'tcx> as BackendTypes>::BasicBlock;
     type Type = <CodegenCx<'ll, 'tcx> as BackendTypes>::Type;
-    type Context = <CodegenCx<'ll, 'tcx> as BackendTypes>::Context;
     type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet;
 
     type DIScope = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIScope;
@@ -85,6 +85,13 @@
     }
 }
 
+impl Deref for Builder<'_, 'll, 'tcx> {
+    type Target = CodegenCx<'ll, 'tcx>;
+
+    fn deref(&self) -> &Self::Target {
+        self.cx
+    }
+}
 
 impl HasCodegen<'tcx> for Builder<'_, 'll, 'tcx> {
     type CodegenCx = CodegenCx<'ll, 'tcx>;
@@ -137,11 +144,11 @@
     }
 
     fn count_insn(&self, category: &str) {
-        if self.cx().sess().codegen_stats() {
-            self.cx().stats.borrow_mut().n_llvm_insns += 1;
+        if self.sess().codegen_stats() {
+            self.stats.borrow_mut().n_llvm_insns += 1;
         }
-        if self.cx().sess().count_llvm_insns() {
-            *self.cx().stats
+        if self.sess().count_llvm_insns() {
+            *self.stats
                       .borrow_mut()
                       .llvm_insns
                       .entry(category.to_string())
@@ -457,6 +464,80 @@
         }
     }
 
+    fn checked_binop(
+        &mut self,
+        oop: OverflowOp,
+        ty: Ty,
+        lhs: Self::Value,
+        rhs: Self::Value,
+    ) -> (Self::Value, Self::Value) {
+        use syntax::ast::IntTy::*;
+        use syntax::ast::UintTy::*;
+        use rustc::ty::{Int, Uint};
+
+        let new_sty = match ty.sty {
+            Int(Isize) => Int(self.tcx.sess.target.isize_ty),
+            Uint(Usize) => Uint(self.tcx.sess.target.usize_ty),
+            ref t @ Uint(_) | ref t @ Int(_) => t.clone(),
+            _ => panic!("tried to get overflow intrinsic for op applied to non-int type")
+        };
+
+        let name = match oop {
+            OverflowOp::Add => match new_sty {
+                Int(I8) => "llvm.sadd.with.overflow.i8",
+                Int(I16) => "llvm.sadd.with.overflow.i16",
+                Int(I32) => "llvm.sadd.with.overflow.i32",
+                Int(I64) => "llvm.sadd.with.overflow.i64",
+                Int(I128) => "llvm.sadd.with.overflow.i128",
+
+                Uint(U8) => "llvm.uadd.with.overflow.i8",
+                Uint(U16) => "llvm.uadd.with.overflow.i16",
+                Uint(U32) => "llvm.uadd.with.overflow.i32",
+                Uint(U64) => "llvm.uadd.with.overflow.i64",
+                Uint(U128) => "llvm.uadd.with.overflow.i128",
+
+                _ => unreachable!(),
+            },
+            OverflowOp::Sub => match new_sty {
+                Int(I8) => "llvm.ssub.with.overflow.i8",
+                Int(I16) => "llvm.ssub.with.overflow.i16",
+                Int(I32) => "llvm.ssub.with.overflow.i32",
+                Int(I64) => "llvm.ssub.with.overflow.i64",
+                Int(I128) => "llvm.ssub.with.overflow.i128",
+
+                Uint(U8) => "llvm.usub.with.overflow.i8",
+                Uint(U16) => "llvm.usub.with.overflow.i16",
+                Uint(U32) => "llvm.usub.with.overflow.i32",
+                Uint(U64) => "llvm.usub.with.overflow.i64",
+                Uint(U128) => "llvm.usub.with.overflow.i128",
+
+                _ => unreachable!(),
+            },
+            OverflowOp::Mul => match new_sty {
+                Int(I8) => "llvm.smul.with.overflow.i8",
+                Int(I16) => "llvm.smul.with.overflow.i16",
+                Int(I32) => "llvm.smul.with.overflow.i32",
+                Int(I64) => "llvm.smul.with.overflow.i64",
+                Int(I128) => "llvm.smul.with.overflow.i128",
+
+                Uint(U8) => "llvm.umul.with.overflow.i8",
+                Uint(U16) => "llvm.umul.with.overflow.i16",
+                Uint(U32) => "llvm.umul.with.overflow.i32",
+                Uint(U64) => "llvm.umul.with.overflow.i64",
+                Uint(U128) => "llvm.umul.with.overflow.i128",
+
+                _ => unreachable!(),
+            },
+        };
+
+        let intrinsic = self.get_intrinsic(&name);
+        let res = self.call(intrinsic, &[lhs, rhs], None);
+        (
+            self.extract_value(res, 0),
+            self.extract_value(res, 1),
+        )
+    }
+
     fn alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
         let mut bx = Builder::with_cx(self.cx);
         bx.position_at_start(unsafe {
@@ -557,7 +638,7 @@
             let vr = scalar.valid_range.clone();
             match scalar.value {
                 layout::Int(..) => {
-                    let range = scalar.valid_range_exclusive(bx.cx());
+                    let range = scalar.valid_range_exclusive(bx);
                     if range.start != range.end {
                         bx.range_metadata(load, range);
                     }
@@ -589,17 +670,23 @@
             });
             OperandValue::Immediate(to_immediate(self, llval, place.layout))
         } else if let layout::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
-            let mut load = |i, scalar: &layout::Scalar| {
+            let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
+
+            let mut load = |i, scalar: &layout::Scalar, align| {
                 let llptr = self.struct_gep(place.llval, i as u64);
-                let load = self.load(llptr, place.align);
+                let load = self.load(llptr, align);
                 scalar_load_metadata(self, load, scalar);
                 if scalar.is_bool() {
-                    self.trunc(load, self.cx().type_i1())
+                    self.trunc(load, self.type_i1())
                 } else {
                     load
                 }
             };
-            OperandValue::Pair(load(0, a), load(1, b))
+
+            OperandValue::Pair(
+                load(0, a, place.align),
+                load(1, b, place.align.restrict_for_offset(b_offset)),
+            )
         } else {
             OperandValue::Ref(place.llval, None, place.align)
         };
@@ -610,7 +697,7 @@
 
 
     fn range_metadata(&mut self, load: &'ll Value, range: Range<u128>) {
-        if self.cx().sess().target.target.arch == "amdgpu" {
+        if self.sess().target.target.arch == "amdgpu" {
             // amdgpu/LLVM does something weird and thinks a i64 value is
             // split into a v2i32, halving the bitwidth LLVM expects,
             // tripping an assertion. So, for now, just disable this
@@ -856,7 +943,7 @@
         }).collect::<Vec<_>>();
 
         debug!("Asm Output Type: {:?}", output);
-        let fty = self.cx().type_func(&argtys[..], output);
+        let fty = self.type_func(&argtys[..], output);
         unsafe {
             // Ask LLVM to verify that the constraints are well-formed.
             let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr());
@@ -884,14 +971,14 @@
         if flags.contains(MemFlags::NONTEMPORAL) {
             // HACK(nox): This is inefficient but there is no nontemporal memcpy.
             let val = self.load(src, src_align);
-            let ptr = self.pointercast(dst, self.cx().type_ptr_to(self.cx().val_ty(val)));
+            let ptr = self.pointercast(dst, self.type_ptr_to(self.val_ty(val)));
             self.store_with_flags(val, ptr, dst_align, flags);
             return;
         }
-        let size = self.intcast(size, self.cx().type_isize(), false);
+        let size = self.intcast(size, self.type_isize(), false);
         let is_volatile = flags.contains(MemFlags::VOLATILE);
-        let dst = self.pointercast(dst, self.cx().type_i8p());
-        let src = self.pointercast(src, self.cx().type_i8p());
+        let dst = self.pointercast(dst, self.type_i8p());
+        let src = self.pointercast(src, self.type_i8p());
         unsafe {
             llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align.bytes() as c_uint,
                                       src, src_align.bytes() as c_uint, size, is_volatile);
@@ -904,14 +991,14 @@
         if flags.contains(MemFlags::NONTEMPORAL) {
             // HACK(nox): This is inefficient but there is no nontemporal memmove.
             let val = self.load(src, src_align);
-            let ptr = self.pointercast(dst, self.cx().type_ptr_to(self.cx().val_ty(val)));
+            let ptr = self.pointercast(dst, self.type_ptr_to(self.val_ty(val)));
             self.store_with_flags(val, ptr, dst_align, flags);
             return;
         }
-        let size = self.intcast(size, self.cx().type_isize(), false);
+        let size = self.intcast(size, self.type_isize(), false);
         let is_volatile = flags.contains(MemFlags::VOLATILE);
-        let dst = self.pointercast(dst, self.cx().type_i8p());
-        let src = self.pointercast(src, self.cx().type_i8p());
+        let dst = self.pointercast(dst, self.type_i8p());
+        let src = self.pointercast(src, self.type_i8p());
         unsafe {
             llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align.bytes() as c_uint,
                                       src, src_align.bytes() as c_uint, size, is_volatile);
@@ -926,12 +1013,12 @@
         align: Align,
         flags: MemFlags,
     ) {
-        let ptr_width = &self.cx().sess().target.target.target_pointer_width;
+        let ptr_width = &self.sess().target.target.target_pointer_width;
         let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
-        let llintrinsicfn = self.cx().get_intrinsic(&intrinsic_key);
-        let ptr = self.pointercast(ptr, self.cx().type_i8p());
-        let align = self.cx().const_u32(align.bytes() as u32);
-        let volatile = self.cx().const_bool(flags.contains(MemFlags::VOLATILE));
+        let llintrinsicfn = self.get_intrinsic(&intrinsic_key);
+        let ptr = self.pointercast(ptr, self.type_i8p());
+        let align = self.const_u32(align.bytes() as u32);
+        let volatile = self.const_bool(flags.contains(MemFlags::VOLATILE));
         self.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None);
     }
 
@@ -997,10 +1084,10 @@
     fn vector_splat(&mut self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
         unsafe {
             let elt_ty = self.cx.val_ty(elt);
-            let undef = llvm::LLVMGetUndef(self.cx().type_vector(elt_ty, num_elts as u64));
+            let undef = llvm::LLVMGetUndef(self.type_vector(elt_ty, num_elts as u64));
             let vec = self.insert_element(undef, elt, self.cx.const_i32(0));
-            let vec_i32_ty = self.cx().type_vector(self.cx().type_i32(), num_elts as u64);
-            self.shuffle_vector(vec, undef, self.cx().const_null(vec_i32_ty))
+            let vec_i32_ty = self.type_vector(self.type_i32(), num_elts as u64);
+            self.shuffle_vector(vec, undef, self.const_null(vec_i32_ty))
         }
     }
 
@@ -1311,7 +1398,7 @@
         let param_tys = self.cx.func_params_types(fn_ty);
 
         let all_args_match = param_tys.iter()
-            .zip(args.iter().map(|&v| self.cx().val_ty(v)))
+            .zip(args.iter().map(|&v| self.val_ty(v)))
             .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
 
         if all_args_match {
@@ -1322,7 +1409,7 @@
             .zip(args.iter())
             .enumerate()
             .map(|(i, (expected_ty, &actual_val))| {
-                let actual_ty = self.cx().val_ty(actual_val);
+                let actual_ty = self.val_ty(actual_val);
                 if expected_ty != actual_ty {
                     debug!("Type mismatch in function call of {:?}. \
                             Expected {:?} for param {}, got {:?}; injecting bitcast",
@@ -1345,22 +1432,6 @@
         self.call_lifetime_intrinsic("llvm.lifetime.end", ptr, size);
     }
 
-    fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
-        if self.cx.sess().opts.optimize == config::OptLevel::No {
-            return;
-        }
-
-        let size = size.bytes();
-        if size == 0 {
-            return;
-        }
-
-        let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic);
-
-        let ptr = self.pointercast(ptr, self.cx.type_i8p());
-        self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);
-    }
-
     fn call(
         &mut self,
         llfn: &'ll Value,
@@ -1415,3 +1486,27 @@
         llvm::Attribute::NoInline.apply_callsite(llvm::AttributePlace::Function, llret);
     }
 }
+
+impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
+    fn get_static(&self, def_id: DefId) -> &'ll Value {
+        self.cx().get_static(def_id)
+    }
+}
+
+impl Builder<'a, 'll, 'tcx> {
+    fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
+        if self.cx.sess().opts.optimize == config::OptLevel::No {
+            return;
+        }
+
+        let size = size.bytes();
+        if size == 0 {
+            return;
+        }
+
+        let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic);
+
+        let ptr = self.pointercast(ptr, self.cx.type_i8p());
+        self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);
+    }
+}
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index e79880e..f13eeb6 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -81,7 +81,7 @@
         // other weird situations. Annoying.
         if cx.val_ty(llfn) != llptrty {
             debug!("get_fn: casting {:?} to {:?}", llfn, llptrty);
-            cx.static_ptrcast(llfn, llptrty)
+            cx.const_ptrcast(llfn, llptrty)
         } else {
             debug!("get_fn: not casting pointer!");
             llfn
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index cd74a58..fd13421 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -98,7 +98,6 @@
     type Value = &'ll Value;
     type BasicBlock = &'ll BasicBlock;
     type Type = &'ll Type;
-    type Context = &'ll llvm::Context;
     type Funclet = Funclet<'ll>;
 
     type DIScope = &'ll llvm::debuginfo::DIScope;
@@ -313,7 +312,7 @@
                 if layout.value == layout::Pointer {
                     unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
                 } else {
-                    self.static_bitcast(llval, llty)
+                    self.const_bitcast(llval, llty)
                 }
             },
             Scalar::Ptr(ptr) => {
@@ -337,14 +336,14 @@
                     None => bug!("missing allocation {:?}", ptr.alloc_id),
                 };
                 let llval = unsafe { llvm::LLVMConstInBoundsGEP(
-                    self.static_bitcast(base_addr, self.type_i8p()),
+                    self.const_bitcast(base_addr, self.type_i8p()),
                     &self.const_usize(ptr.offset.bytes()),
                     1,
                 ) };
                 if layout.value != layout::Pointer {
                     unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
                 } else {
-                    self.static_bitcast(llval, llty)
+                    self.const_bitcast(llval, llty)
                 }
             }
         }
@@ -360,13 +359,17 @@
         let base_addr = self.static_addr_of(init, layout.align.abi, None);
 
         let llval = unsafe { llvm::LLVMConstInBoundsGEP(
-            self.static_bitcast(base_addr, self.type_i8p()),
+            self.const_bitcast(base_addr, self.type_i8p()),
             &self.const_usize(offset.bytes()),
             1,
         )};
-        let llval = self.static_bitcast(llval, self.type_ptr_to(layout.llvm_type(self)));
+        let llval = self.const_bitcast(llval, self.type_ptr_to(layout.llvm_type(self)));
         PlaceRef::new_sized(llval, layout, alloc.align)
     }
+
+    fn const_ptrcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
+        consts::ptrcast(val, ty)
+    }
 }
 
 pub fn val_ty(v: &'ll Value) -> &'ll Type {
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 07dde2d..5311a6a 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -171,19 +171,14 @@
     }
 }
 
-impl StaticMethods<'tcx> for CodegenCx<'ll, 'tcx> {
-
-    fn static_ptrcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
-        ptrcast(val, ty)
-    }
-
-    fn static_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
+impl CodegenCx<'ll, 'tcx> {
+    crate fn const_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
         unsafe {
             llvm::LLVMConstBitCast(val, ty)
         }
     }
 
-    fn static_addr_of_mut(
+    crate fn static_addr_of_mut(
         &self,
         cv: &'ll Value,
         align: Align,
@@ -209,32 +204,7 @@
         }
     }
 
-    fn static_addr_of(
-        &self,
-        cv: &'ll Value,
-        align: Align,
-        kind: Option<&str>,
-    ) -> &'ll Value {
-        if let Some(&gv) = self.const_globals.borrow().get(&cv) {
-            unsafe {
-                // Upgrade the alignment in cases where the same constant is used with different
-                // alignment requirements
-                let llalign = align.bytes() as u32;
-                if llalign > llvm::LLVMGetAlignment(gv) {
-                    llvm::LLVMSetAlignment(gv, llalign);
-                }
-            }
-            return gv;
-        }
-        let gv = self.static_addr_of_mut(cv, align, kind);
-        unsafe {
-            llvm::LLVMSetGlobalConstant(gv, True);
-        }
-        self.const_globals.borrow_mut().insert(cv, gv);
-        gv
-    }
-
-    fn get_static(&self, def_id: DefId) -> &'ll Value {
+    crate fn get_static(&self, def_id: DefId) -> &'ll Value {
         let instance = Instance::mono(self.tcx, def_id);
         if let Some(&g) = self.instances.borrow().get(&instance) {
             return g;
@@ -354,6 +324,33 @@
         self.instances.borrow_mut().insert(instance, g);
         g
     }
+}
+
+impl StaticMethods for CodegenCx<'ll, 'tcx> {
+    fn static_addr_of(
+        &self,
+        cv: &'ll Value,
+        align: Align,
+        kind: Option<&str>,
+    ) -> &'ll Value {
+        if let Some(&gv) = self.const_globals.borrow().get(&cv) {
+            unsafe {
+                // Upgrade the alignment in cases where the same constant is used with different
+                // alignment requirements
+                let llalign = align.bytes() as u32;
+                if llalign > llvm::LLVMGetAlignment(gv) {
+                    llvm::LLVMSetAlignment(gv, llalign);
+                }
+            }
+            return gv;
+        }
+        let gv = self.static_addr_of_mut(cv, align, kind);
+        unsafe {
+            llvm::LLVMSetGlobalConstant(gv, True);
+        }
+        self.const_globals.borrow_mut().insert(cv, gv);
+        gv
+    }
 
     fn codegen_static(
         &self,
@@ -498,9 +495,4 @@
             }
         }
     }
-    unsafe fn static_replace_all_uses(&self, old_g: &'ll Value, new_g: &'ll Value) {
-        let bitcast = llvm::LLVMConstPointerCast(new_g, self.val_ty(old_g));
-        llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
-        llvm::LLVMDeleteGlobal(old_g);
-    }
 }
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 5b088ad..564e424 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -314,6 +314,10 @@
             local_gen_sym_counter: Cell::new(0),
         }
     }
+
+    crate fn statics_to_rauw(&self) -> &RefCell<Vec<(&'ll Value, &'ll Value)>> {
+        &self.statics_to_rauw
+    }
 }
 
 impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
@@ -328,7 +332,7 @@
     }
 
     fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value {
-        get_fn(&&self,instance)
+        get_fn(self, instance)
     }
 
     fn get_param(&self, llfn: &'ll Value, index: c_uint) -> &'ll Value {
@@ -431,10 +435,6 @@
         &self.codegen_unit
     }
 
-    fn statics_to_rauw(&self) -> &RefCell<Vec<(&'ll Value, &'ll Value)>> {
-        &self.statics_to_rauw
-    }
-
     fn used_statics(&self) -> &RefCell<Vec<&'ll Value>> {
         &self.used_statics
     }
@@ -470,8 +470,8 @@
     }
 }
 
-impl IntrinsicDeclarationMethods<'tcx> for CodegenCx<'b, 'tcx> {
-    fn get_intrinsic(&self, key: &str) -> &'b Value {
+impl CodegenCx<'b, 'tcx> {
+    crate fn get_intrinsic(&self, key: &str) -> &'b Value {
         if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
             return v;
         }
@@ -723,17 +723,17 @@
         ifn!("llvm.bitreverse.i64", fn(t_i64) -> t_i64);
         ifn!("llvm.bitreverse.i128", fn(t_i128) -> t_i128);
 
-    ifn!("llvm.fshl.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
-    ifn!("llvm.fshl.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
-    ifn!("llvm.fshl.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
-    ifn!("llvm.fshl.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
-    ifn!("llvm.fshl.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
+        ifn!("llvm.fshl.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
+        ifn!("llvm.fshl.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
+        ifn!("llvm.fshl.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
+        ifn!("llvm.fshl.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
+        ifn!("llvm.fshl.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
 
-    ifn!("llvm.fshr.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
-    ifn!("llvm.fshr.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
-    ifn!("llvm.fshr.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
-    ifn!("llvm.fshr.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
-    ifn!("llvm.fshr.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
+        ifn!("llvm.fshr.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
+        ifn!("llvm.fshr.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
+        ifn!("llvm.fshr.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
+        ifn!("llvm.fshr.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
+        ifn!("llvm.fshr.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
 
         ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
         ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
@@ -783,6 +783,11 @@
         ifn!("llvm.assume", fn(i1) -> void);
         ifn!("llvm.prefetch", fn(i8p, t_i32, t_i32, t_i32) -> void);
 
+        // variadic intrinsics
+        ifn!("llvm.va_start", fn(i8p) -> void);
+        ifn!("llvm.va_end", fn(i8p) -> void);
+        ifn!("llvm.va_copy", fn(i8p, i8p) -> void);
+
         if self.sess().opts.debuginfo != DebugInfo::None {
             ifn!("llvm.dbg.declare", fn(self.type_metadata(), self.type_metadata()) -> void);
             ifn!("llvm.dbg.value", fn(self.type_metadata(), t_i64, self.type_metadata()) -> void);
diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs
index 0046a07..4be93d8 100644
--- a/src/librustc_codegen_llvm/debuginfo/gdb.rs
+++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs
@@ -24,11 +24,11 @@
 /// Inserts a side-effect free instruction sequence that makes sure that the
 /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
 pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder) {
-    if needs_gdb_debug_scripts_section(bx.cx()) {
-        let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx.cx());
+    if needs_gdb_debug_scripts_section(bx) {
+        let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx);
         // Load just the first byte as that's all that's necessary to force
         // LLVM to keep around the reference to the global.
-        let indices = [bx.cx().const_i32(0), bx.cx().const_i32(0)];
+        let indices = [bx.const_i32(0), bx.const_i32(0)];
         let element = bx.inbounds_gep(gdb_debug_scripts_section, &indices);
         let volative_load_instruction = bx.volatile_load(element);
         unsafe {
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 81f2769..5a1c62e 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -22,7 +22,7 @@
 use value::Value;
 
 use llvm;
-use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
+use llvm::debuginfo::{DIArray, DIType, DIFile, DIScope, DIDescriptor,
                       DICompositeType, DILexicalBlock, DIFlags};
 use llvm_util;
 
@@ -35,12 +35,14 @@
 use rustc::ty::Instance;
 use common::CodegenCx;
 use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
-use rustc::ty::layout::{self, Align, HasDataLayout, Integer, IntegerExt, LayoutOf,
+use rustc::ty::layout::{self, Align, Integer, IntegerExt, LayoutOf,
                         PrimitiveExt, Size, TyLayout};
+use rustc::ty::subst::UnpackedKind;
 use rustc::session::config;
 use rustc::util::nodemap::FxHashMap;
-use rustc_fs_util::path2cstr;
+use rustc_fs_util::path_to_c_string;
 use rustc_data_structures::small_c_str::SmallCStr;
+use rustc_target::abi::HasDataLayout;
 
 use libc::{c_uint, c_longlong};
 use std::ffi::CString;
@@ -273,6 +275,7 @@
 
                 // ... and attach them to the stub to complete it.
                 set_members_of_composite_type(cx,
+                                              unfinished_type,
                                               member_holding_stub,
                                               member_descriptions);
                 return MetadataCreationResult::new(metadata_stub, true);
@@ -892,7 +895,7 @@
     };
 
     fn path_to_mdstring(llcx: &'ll llvm::Context, path: &Path) -> &'ll Value {
-        let path_str = path2cstr(path);
+        let path_str = path_to_c_string(path);
         unsafe {
             llvm::LLVMMDStringInContext(llcx,
                                         path_str.as_ptr(),
@@ -1214,6 +1217,7 @@
                     member_description_factory.create_member_descriptions(cx);
 
                 set_members_of_composite_type(cx,
+                                              self.enum_type,
                                               variant_type_metadata,
                                               member_descriptions);
                 vec![
@@ -1254,6 +1258,7 @@
                         .create_member_descriptions(cx);
 
                     set_members_of_composite_type(cx,
+                                                  self.enum_type,
                                                   variant_type_metadata,
                                                   member_descriptions);
                     MemberDescription {
@@ -1295,6 +1300,7 @@
                         member_description_factory.create_member_descriptions(cx);
 
                     set_members_of_composite_type(cx,
+                                                  self.enum_type,
                                                   variant_type_metadata,
                                                   variant_member_descriptions);
 
@@ -1354,6 +1360,7 @@
                             .create_member_descriptions(cx);
 
                         set_members_of_composite_type(cx,
+                                                      self.enum_type,
                                                       variant_type_metadata,
                                                       member_descriptions);
 
@@ -1765,13 +1772,15 @@
                                                      containing_scope);
     // ... and immediately create and add the member descriptions.
     set_members_of_composite_type(cx,
+                                  composite_type,
                                   composite_type_metadata,
                                   member_descriptions);
 
     composite_type_metadata
 }
 
-fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
+fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
+                                 composite_type: Ty<'tcx>,
                                  composite_type_metadata: &'ll DICompositeType,
                                  member_descriptions: Vec<MemberDescription<'ll>>) {
     // In some rare cases LLVM metadata uniquing would lead to an existing type
@@ -1815,10 +1824,57 @@
         })
         .collect();
 
+    let type_params = compute_type_parameters(cx, composite_type);
     unsafe {
         let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
-        llvm::LLVMRustDICompositeTypeSetTypeArray(
-            DIB(cx), composite_type_metadata, type_array);
+        llvm::LLVMRustDICompositeTypeReplaceArrays(
+            DIB(cx), composite_type_metadata, Some(type_array), type_params);
+    }
+}
+
+// Compute the type parameters for a type, if any, for the given
+// metadata.
+fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'ll DIArray> {
+    if let ty::Adt(def, substs) = ty.sty {
+        if !substs.types().next().is_none() {
+            let generics = cx.tcx.generics_of(def.did);
+            let names = get_parameter_names(cx, generics);
+            let template_params: Vec<_> = substs.iter().zip(names).filter_map(|(kind, name)| {
+                if let UnpackedKind::Type(ty) = kind.unpack() {
+                    let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
+                    let actual_type_metadata =
+                        type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
+                    let name = SmallCStr::new(&name.as_str());
+                    Some(unsafe {
+
+                        Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
+                            DIB(cx),
+                            None,
+                            name.as_ptr(),
+                            actual_type_metadata,
+                            unknown_file_metadata(cx),
+                            0,
+                            0,
+                        ))
+                    })
+                } else {
+                    None
+                }
+            }).collect();
+
+            return Some(create_DIArray(DIB(cx), &template_params[..]));
+        }
+    }
+    return Some(create_DIArray(DIB(cx), &[]));
+
+    fn get_parameter_names(cx: &CodegenCx,
+                           generics: &ty::Generics)
+                           -> Vec<InternedString> {
+        let mut names = generics.parent.map_or(vec![], |def_id| {
+            get_parameter_names(cx, cx.tcx.generics_of(def_id))
+        });
+        names.extend(generics.params.iter().map(|param| param.name));
+        names
     }
 }
 
diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs
index c6772e8..9519628 100644
--- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs
+++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs
@@ -41,7 +41,7 @@
     };
 
     let dbg_loc = if function_debug_context.source_locations_enabled.get() {
-        debug!("set_source_location: {}", bx.cx().sess().source_map().span_to_string(span));
+        debug!("set_source_location: {}", bx.sess().source_map().span_to_string(span));
         let loc = span_start(bx.cx(), span);
         InternalDebugLocation::new(scope.unwrap(), loc.line, loc.col.to_usize())
     } else {
@@ -76,7 +76,7 @@
             // For MSVC, set the column number to zero.
             // Otherwise, emit it. This mimics clang behaviour.
             // See discussion in https://github.com/rust-lang/rust/issues/42921
-            let col_used =  if bx.cx().sess().target.target.options.is_like_msvc {
+            let col_used =  if bx.sess().target.target.options.is_like_msvc {
                 UNKNOWN_COLUMN_NUMBER
             } else {
                 col as c_uint
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 3548ccf..313aa17 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -24,13 +24,14 @@
 use type_::Type;
 use type_of::LayoutLlvmExt;
 use rustc::ty::{self, Ty};
-use rustc::ty::layout::{LayoutOf, HasTyCtxt};
+use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Primitive};
 use rustc_codegen_ssa::common::TypeKind;
 use rustc::hir;
-use syntax::ast;
+use syntax::ast::{self, FloatTy};
 use syntax::symbol::Symbol;
 use builder::Builder;
 use value::Value;
+use va_arg::emit_va_arg;
 
 use rustc_codegen_ssa::traits::*;
 
@@ -96,7 +97,7 @@
         llresult: &'ll Value,
         span: Span,
     ) {
-        let tcx = self.cx().tcx;
+        let tcx = self.tcx;
 
         let (def_id, substs) = match callee_ty.sty {
             ty::FnDef(def_id, substs) => (def_id, substs),
@@ -109,10 +110,10 @@
         let ret_ty = sig.output();
         let name = &*tcx.item_name(def_id).as_str();
 
-        let llret_ty = self.cx().layout_of(ret_ty).llvm_type(self.cx());
+        let llret_ty = self.layout_of(ret_ty).llvm_type(self);
         let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align.abi);
 
-        let simple = get_simple_intrinsic(self.cx(), name);
+        let simple = get_simple_intrinsic(self, name);
         let llval = match name {
             _ if simple.is_some() => {
                 self.call(simple.unwrap(),
@@ -123,12 +124,12 @@
                 return;
             },
             "likely" => {
-                let expect = self.cx().get_intrinsic(&("llvm.expect.i1"));
-                self.call(expect, &[args[0].immediate(), self.cx().const_bool(true)], None)
+                let expect = self.get_intrinsic(&("llvm.expect.i1"));
+                self.call(expect, &[args[0].immediate(), self.const_bool(true)], None)
             }
             "unlikely" => {
-                let expect = self.cx().get_intrinsic(&("llvm.expect.i1"));
-                self.call(expect, &[args[0].immediate(), self.cx().const_bool(false)], None)
+                let expect = self.get_intrinsic(&("llvm.expect.i1"));
+                self.call(expect, &[args[0].immediate(), self.const_bool(false)], None)
             }
             "try" => {
                 try_intrinsic(self,
@@ -139,12 +140,65 @@
                 return;
             }
             "breakpoint" => {
-                let llfn = self.cx().get_intrinsic(&("llvm.debugtrap"));
+                let llfn = self.get_intrinsic(&("llvm.debugtrap"));
                 self.call(llfn, &[], None)
             }
             "size_of" => {
                 let tp_ty = substs.type_at(0);
-                self.cx().const_usize(self.cx().size_of(tp_ty).bytes())
+                self.const_usize(self.size_of(tp_ty).bytes())
+            }
+            func @ "va_start" | func @ "va_end" => {
+                let va_list = match (tcx.lang_items().va_list(), &result.layout.ty.sty) {
+                    (Some(did), ty::Adt(def, _)) if def.did == did => args[0].immediate(),
+                    (Some(_), _) => self.load(args[0].immediate(),
+                                              tcx.data_layout.pointer_align.abi),
+                    (None, _) => bug!("va_list language item must be defined")
+                };
+                let intrinsic = self.cx().get_intrinsic(&format!("llvm.{}", func));
+                self.call(intrinsic, &[va_list], None)
+            }
+            "va_copy" => {
+                let va_list = match (tcx.lang_items().va_list(), &result.layout.ty.sty) {
+                    (Some(did), ty::Adt(def, _)) if def.did == did => args[0].immediate(),
+                    (Some(_), _)  => self.load(args[0].immediate(),
+                                               tcx.data_layout.pointer_align.abi),
+                    (None, _) => bug!("va_list language item must be defined")
+                };
+                let intrinsic = self.cx().get_intrinsic(&("llvm.va_copy"));
+                self.call(intrinsic, &[llresult, va_list], None);
+                return;
+            }
+            "va_arg" => {
+                match fn_ty.ret.layout.abi {
+                    layout::Abi::Scalar(ref scalar) => {
+                        match scalar.value {
+                            Primitive::Int(..) => {
+                                if self.cx().size_of(ret_ty).bytes() < 4 {
+                                    // va_arg should not be called on a integer type
+                                    // less than 4 bytes in length. If it is, promote
+                                    // the integer to a `i32` and truncate the result
+                                    // back to the smaller type.
+                                    let promoted_result = emit_va_arg(self, args[0],
+                                                                      tcx.types.i32);
+                                    self.trunc(promoted_result, llret_ty)
+                                } else {
+                                    emit_va_arg(self, args[0], ret_ty)
+                                }
+                            }
+                            Primitive::Float(FloatTy::F64) |
+                            Primitive::Pointer => {
+                                emit_va_arg(self, args[0], ret_ty)
+                            }
+                            // `va_arg` should never be used with the return type f32.
+                            Primitive::Float(FloatTy::F32) => {
+                                bug!("the va_arg intrinsic does not work with `f32`")
+                            }
+                        }
+                    }
+                    _ => {
+                        bug!("the va_arg intrinsic does not work with non-scalar types")
+                    }
+                }
             }
             "size_of_val" => {
                 let tp_ty = substs.type_at(0);
@@ -153,12 +207,12 @@
                         glue::size_and_align_of_dst(self, tp_ty, Some(meta));
                     llsize
                 } else {
-                    self.cx().const_usize(self.cx().size_of(tp_ty).bytes())
+                    self.const_usize(self.size_of(tp_ty).bytes())
                 }
             }
             "min_align_of" => {
                 let tp_ty = substs.type_at(0);
-                self.cx().const_usize(self.cx().align_of(tp_ty).bytes())
+                self.const_usize(self.align_of(tp_ty).bytes())
             }
             "min_align_of_val" => {
                 let tp_ty = substs.type_at(0);
@@ -167,24 +221,24 @@
                         glue::size_and_align_of_dst(self, tp_ty, Some(meta));
                     llalign
                 } else {
-                    self.cx().const_usize(self.cx().align_of(tp_ty).bytes())
+                    self.const_usize(self.align_of(tp_ty).bytes())
                 }
             }
             "pref_align_of" => {
                 let tp_ty = substs.type_at(0);
-                self.cx().const_usize(self.cx().layout_of(tp_ty).align.pref.bytes())
+                self.const_usize(self.layout_of(tp_ty).align.pref.bytes())
             }
             "type_name" => {
                 let tp_ty = substs.type_at(0);
                 let ty_name = Symbol::intern(&tp_ty.to_string()).as_str();
-                self.cx().const_str_slice(ty_name)
+                self.const_str_slice(ty_name)
             }
             "type_id" => {
-                self.cx().const_u64(self.cx().tcx.type_id_hash(substs.type_at(0)))
+                self.const_u64(self.tcx.type_id_hash(substs.type_at(0)))
             }
             "init" => {
                 let ty = substs.type_at(0);
-                if !self.cx().layout_of(ty).is_zst() {
+                if !self.layout_of(ty).is_zst() {
                     // Just zero out the stack slot.
                     // If we store a zero constant, LLVM will drown in vreg allocation for large
                     // data structures, and the generated code will be awful. (A telltale sign of
@@ -194,8 +248,8 @@
                         false,
                         ty,
                         llresult,
-                        self.cx().const_u8(0),
-                        self.cx().const_usize(1)
+                        self.const_u8(0),
+                        self.const_usize(1)
                     );
                 }
                 return;
@@ -207,7 +261,7 @@
             "needs_drop" => {
                 let tp_ty = substs.type_at(0);
 
-                self.cx().const_bool(self.cx().type_needs_drop(tp_ty))
+                self.const_bool(self.type_needs_drop(tp_ty))
             }
             "offset" => {
                 let ptr = args[0].immediate();
@@ -255,18 +309,18 @@
                 let tp_ty = substs.type_at(0);
                 let mut ptr = args[0].immediate();
                 if let PassMode::Cast(ty) = fn_ty.ret.mode {
-                    ptr = self.pointercast(ptr, self.cx().type_ptr_to(ty.llvm_type(self.cx())));
+                    ptr = self.pointercast(ptr, self.type_ptr_to(ty.llvm_type(self)));
                 }
                 let load = self.volatile_load(ptr);
                 let align = if name == "unaligned_volatile_load" {
                     1
                 } else {
-                    self.cx().align_of(tp_ty).bytes() as u32
+                    self.align_of(tp_ty).bytes() as u32
                 };
                 unsafe {
                     llvm::LLVMSetAlignment(load, align);
                 }
-                to_immediate(self, load, self.cx().layout_of(tp_ty))
+                to_immediate(self, load, self.layout_of(tp_ty))
             },
             "volatile_store" => {
                 let dst = args[0].deref(self.cx());
@@ -280,7 +334,7 @@
             },
             "prefetch_read_data" | "prefetch_write_data" |
             "prefetch_read_instruction" | "prefetch_write_instruction" => {
-                let expect = self.cx().get_intrinsic(&("llvm.prefetch"));
+                let expect = self.get_intrinsic(&("llvm.prefetch"));
                 let (rw, cache_type) = match name {
                     "prefetch_read_data" => (0, 1),
                     "prefetch_write_data" => (1, 1),
@@ -290,9 +344,9 @@
                 };
                 self.call(expect, &[
                     args[0].immediate(),
-                    self.cx().const_i32(rw),
+                    self.const_i32(rw),
                     args[1].immediate(),
-                    self.cx().const_i32(cache_type)
+                    self.const_i32(cache_type)
                 ], None)
             },
             "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
@@ -301,24 +355,24 @@
             "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "exact_div" |
             "rotate_left" | "rotate_right" => {
                 let ty = arg_tys[0];
-                match int_type_width_signed(ty, self.cx()) {
+                match int_type_width_signed(ty, self) {
                     Some((width, signed)) =>
                         match name {
                             "ctlz" | "cttz" => {
-                                let y = self.cx().const_bool(false);
-                                let llfn = self.cx().get_intrinsic(
+                                let y = self.const_bool(false);
+                                let llfn = self.get_intrinsic(
                                     &format!("llvm.{}.i{}", name, width),
                                 );
                                 self.call(llfn, &[args[0].immediate(), y], None)
                             }
                             "ctlz_nonzero" | "cttz_nonzero" => {
-                                let y = self.cx().const_bool(true);
+                                let y = self.const_bool(true);
                                 let llvm_name = &format!("llvm.{}.i{}", &name[..4], width);
-                                let llfn = self.cx().get_intrinsic(llvm_name);
+                                let llfn = self.get_intrinsic(llvm_name);
                                 self.call(llfn, &[args[0].immediate(), y], None)
                             }
                             "ctpop" => self.call(
-                                self.cx().get_intrinsic(&format!("llvm.ctpop.i{}", width)),
+                                self.get_intrinsic(&format!("llvm.ctpop.i{}", width)),
                                 &[args[0].immediate()],
                                 None
                             ),
@@ -327,7 +381,7 @@
                                     args[0].immediate() // byte swap a u8/i8 is just a no-op
                                 } else {
                                     self.call(
-                                        self.cx().get_intrinsic(
+                                        self.get_intrinsic(
                                             &format!("llvm.bswap.i{}", width),
                                         ),
                                         &[args[0].immediate()],
@@ -337,7 +391,7 @@
                             }
                             "bitreverse" => {
                                 self.call(
-                                    self.cx().get_intrinsic(
+                                    self.get_intrinsic(
                                         &format!("llvm.bitreverse.i{}", width),
                                     ),
                                     &[args[0].immediate()],
@@ -348,7 +402,7 @@
                                 let intrinsic = format!("llvm.{}{}.with.overflow.i{}",
                                                         if signed { 's' } else { 'u' },
                                                         &name[..3], width);
-                                let llfn = self.cx().get_intrinsic(&intrinsic);
+                                let llfn = self.get_intrinsic(&intrinsic);
 
                                 // Convert `i1` to a `bool`, and write it to the out parameter
                                 let pair = self.call(llfn, &[
@@ -357,7 +411,7 @@
                                 ], None);
                                 let val = self.extract_value(pair, 0);
                                 let overflow = self.extract_value(pair, 1);
-                                let overflow = self.zext(overflow, self.cx().type_bool());
+                                let overflow = self.zext(overflow, self.type_bool());
 
                                 let dest = result.project_field(self, 0);
                                 self.store(val, dest.llval, dest.align);
@@ -402,13 +456,13 @@
                                     // rotate = funnel shift with first two args the same
                                     let llvm_name = &format!("llvm.fsh{}.i{}",
                                                             if is_left { 'l' } else { 'r' }, width);
-                                    let llfn = self.cx().get_intrinsic(llvm_name);
+                                    let llfn = self.get_intrinsic(llvm_name);
                                     self.call(llfn, &[val, val, raw_shift], None)
                                 } else {
                                     // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
                                     // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
-                                    let width = self.cx().const_uint(
-                                        self.cx().type_ix(width),
+                                    let width = self.const_uint(
+                                        self.type_ix(width),
                                         width,
                                     );
                                     let shift = self.urem(raw_shift, width);
@@ -496,16 +550,16 @@
                             (SequentiallyConsistent, Monotonic),
                         "failacq" if is_cxchg =>
                             (SequentiallyConsistent, Acquire),
-                        _ => self.cx().sess().fatal("unknown ordering in atomic intrinsic")
+                        _ => self.sess().fatal("unknown ordering in atomic intrinsic")
                     },
                     4 => match (split[2], split[3]) {
                         ("acq", "failrelaxed") if is_cxchg =>
                             (Acquire, Monotonic),
                         ("acqrel", "failrelaxed") if is_cxchg =>
                             (AcquireRelease, Monotonic),
-                        _ => self.cx().sess().fatal("unknown ordering in atomic intrinsic")
+                        _ => self.sess().fatal("unknown ordering in atomic intrinsic")
                     },
-                    _ => self.cx().sess().fatal("Atomic intrinsic not in correct format"),
+                    _ => self.sess().fatal("Atomic intrinsic not in correct format"),
                 };
 
                 let invalid_monomorphization = |ty| {
@@ -517,7 +571,7 @@
                 match split[1] {
                     "cxchg" | "cxchgweak" => {
                         let ty = substs.type_at(0);
-                        if int_type_width_signed(ty, self.cx()).is_some() {
+                        if int_type_width_signed(ty, self).is_some() {
                             let weak = split[1] == "cxchgweak";
                             let pair = self.atomic_cmpxchg(
                                 args[0].immediate(),
@@ -528,7 +582,7 @@
                                 weak);
                             let val = self.extract_value(pair, 0);
                             let success = self.extract_value(pair, 1);
-                            let success = self.zext(success, self.cx().type_bool());
+                            let success = self.zext(success, self.type_bool());
 
                             let dest = result.project_field(self, 0);
                             self.store(val, dest.llval, dest.align);
@@ -542,8 +596,8 @@
 
                     "load" => {
                         let ty = substs.type_at(0);
-                        if int_type_width_signed(ty, self.cx()).is_some() {
-                            let size = self.cx().size_of(ty);
+                        if int_type_width_signed(ty, self).is_some() {
+                            let size = self.size_of(ty);
                             self.atomic_load(args[0].immediate(), order, size)
                         } else {
                             return invalid_monomorphization(ty);
@@ -552,8 +606,8 @@
 
                     "store" => {
                         let ty = substs.type_at(0);
-                        if int_type_width_signed(ty, self.cx()).is_some() {
-                            let size = self.cx().size_of(ty);
+                        if int_type_width_signed(ty, self).is_some() {
+                            let size = self.size_of(ty);
                             self.atomic_store(
                                 args[1].immediate(),
                                 args[0].immediate(),
@@ -590,11 +644,11 @@
                             "min"   => AtomicRmwBinOp::AtomicMin,
                             "umax"  => AtomicRmwBinOp::AtomicUMax,
                             "umin"  => AtomicRmwBinOp::AtomicUMin,
-                            _ => self.cx().sess().fatal("unknown atomic operation")
+                            _ => self.sess().fatal("unknown atomic operation")
                         };
 
                         let ty = substs.type_at(0);
-                        if int_type_width_signed(ty, self.cx()).is_some() {
+                        if int_type_width_signed(ty, self).is_some() {
                             self.atomic_rmw(
                                 atom_op,
                                 args[0].immediate(),
@@ -681,7 +735,7 @@
                             // This assumes the type is "simple", i.e. no
                             // destructors, and the contents are SIMD
                             // etc.
-                            assert!(!bx.cx().type_needs_drop(arg.layout.ty));
+                            assert!(!bx.type_needs_drop(arg.layout.ty));
                             let (ptr, align) = match arg.val {
                                 OperandValue::Ref(ptr, None, align) => (ptr, align),
                                 _ => bug!()
@@ -693,21 +747,21 @@
                             }).collect()
                         }
                         intrinsics::Type::Pointer(_, Some(ref llvm_elem), _) => {
-                            let llvm_elem = one(ty_to_type(bx.cx(), llvm_elem));
-                            vec![bx.pointercast(arg.immediate(), bx.cx().type_ptr_to(llvm_elem))]
+                            let llvm_elem = one(ty_to_type(bx, llvm_elem));
+                            vec![bx.pointercast(arg.immediate(), bx.type_ptr_to(llvm_elem))]
                         }
                         intrinsics::Type::Vector(_, Some(ref llvm_elem), length) => {
-                            let llvm_elem = one(ty_to_type(bx.cx(), llvm_elem));
+                            let llvm_elem = one(ty_to_type(bx, llvm_elem));
                             vec![
                                 bx.bitcast(arg.immediate(),
-                                bx.cx().type_vector(llvm_elem, length as u64))
+                                bx.type_vector(llvm_elem, length as u64))
                             ]
                         }
                         intrinsics::Type::Integer(_, width, llvm_width) if width != llvm_width => {
                             // the LLVM intrinsic uses a smaller integer
                             // size than the C intrinsic's signature, so
                             // we have to trim it down here.
-                            vec![bx.trunc(arg.immediate(), bx.cx().type_ix(llvm_width as u64))]
+                            vec![bx.trunc(arg.immediate(), bx.type_ix(llvm_width as u64))]
                         }
                         _ => vec![arg.immediate()],
                     }
@@ -715,10 +769,10 @@
 
 
                 let inputs = intr.inputs.iter()
-                                        .flat_map(|t| ty_to_type(self.cx(), t))
+                                        .flat_map(|t| ty_to_type(self, t))
                                         .collect::<Vec<_>>();
 
-                let outputs = one(ty_to_type(self.cx(), &intr.output));
+                let outputs = one(ty_to_type(self, &intr.output));
 
                 let llargs: Vec<_> = intr.inputs.iter().zip(args).flat_map(|(t, arg)| {
                     modify_as_needed(self, t, arg)
@@ -727,9 +781,9 @@
 
                 let val = match intr.definition {
                     intrinsics::IntrinsicDef::Named(name) => {
-                        let f = self.cx().declare_cfn(
+                        let f = self.declare_cfn(
                             name,
-                            self.cx().type_func(&inputs, outputs),
+                            self.type_func(&inputs, outputs),
                         );
                         self.call(f, &llargs, None)
                     }
@@ -754,7 +808,7 @@
 
         if !fn_ty.ret.is_ignore() {
             if let PassMode::Cast(ty) = fn_ty.ret.mode {
-                let ptr_llty = self.cx().type_ptr_to(ty.llvm_type(self.cx()));
+                let ptr_llty = self.type_ptr_to(ty.llvm_type(self));
                 let ptr = self.pointercast(result.llval, ptr_llty);
                 self.store(llval, ptr, result.align);
             } else {
@@ -763,6 +817,21 @@
             }
         }
     }
+
+    fn abort(&mut self) {
+        let fnname = self.get_intrinsic(&("llvm.trap"));
+        self.call(fnname, &[], None);
+    }
+
+    fn assume(&mut self, val: Self::Value) {
+        let assume_intrinsic = self.get_intrinsic("llvm.assume");
+        self.call(assume_intrinsic, &[val], None);
+    }
+
+    fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value {
+        let expect = self.get_intrinsic(&"llvm.expect.i1");
+        self.call(expect, &[cond, self.const_bool(expected)], None)
+    }
 }
 
 fn copy_intrinsic(
@@ -774,8 +843,8 @@
     src: &'ll Value,
     count: &'ll Value,
 ) {
-    let (size, align) = bx.cx().size_and_align_of(ty);
-    let size = bx.mul(bx.cx().const_usize(size.bytes()), count);
+    let (size, align) = bx.size_and_align_of(ty);
+    let size = bx.mul(bx.const_usize(size.bytes()), count);
     let flags = if volatile {
         MemFlags::VOLATILE
     } else {
@@ -796,8 +865,8 @@
     val: &'ll Value,
     count: &'ll Value
 ) {
-    let (size, align) = bx.cx().size_and_align_of(ty);
-    let size = bx.mul(bx.cx().const_usize(size.bytes()), count);
+    let (size, align) = bx.size_and_align_of(ty);
+    let size = bx.mul(bx.const_usize(size.bytes()), count);
     let flags = if volatile {
         MemFlags::VOLATILE
     } else {
@@ -813,11 +882,11 @@
     local_ptr: &'ll Value,
     dest: &'ll Value,
 ) {
-    if bx.cx().sess().no_landing_pads() {
+    if bx.sess().no_landing_pads() {
         bx.call(func, &[data], None);
         let ptr_align = bx.tcx().data_layout.pointer_align.abi;
-        bx.store(bx.cx().const_null(bx.cx().type_i8p()), dest, ptr_align);
-    } else if wants_msvc_seh(bx.cx().sess()) {
+        bx.store(bx.const_null(bx.type_i8p()), dest, ptr_align);
+    } else if wants_msvc_seh(bx.sess()) {
         codegen_msvc_try(bx, func, data, local_ptr, dest);
     } else {
         codegen_gnu_try(bx, func, data, local_ptr, dest);
@@ -838,8 +907,8 @@
     local_ptr: &'ll Value,
     dest: &'ll Value,
 ) {
-    let llfn = get_rust_try_fn(bx.cx(), &mut |mut bx| {
-        bx.set_personality_fn(bx.cx().eh_personality());
+    let llfn = get_rust_try_fn(bx, &mut |mut bx| {
+        bx.set_personality_fn(bx.eh_personality());
 
         let mut normal = bx.build_sibling_block("normal");
         let mut catchswitch = bx.build_sibling_block("catchswitch");
@@ -889,26 +958,26 @@
         //      }
         //
         // More information can be found in libstd's seh.rs implementation.
-        let i64p = bx.cx().type_ptr_to(bx.cx().type_i64());
+        let i64p = bx.type_ptr_to(bx.type_i64());
         let ptr_align = bx.tcx().data_layout.pointer_align.abi;
         let slot = bx.alloca(i64p, "slot", ptr_align);
         bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None);
 
-        normal.ret(bx.cx().const_i32(0));
+        normal.ret(bx.const_i32(0));
 
         let cs = catchswitch.catch_switch(None, None, 1);
         catchswitch.add_handler(cs, catchpad.llbb());
 
         let tydesc = match bx.tcx().lang_items().msvc_try_filter() {
-            Some(did) => bx.cx().get_static(did),
+            Some(did) => bx.get_static(did),
             None => bug!("msvc_try_filter not defined"),
         };
-        let funclet = catchpad.catch_pad(cs, &[tydesc, bx.cx().const_i32(0), slot]);
+        let funclet = catchpad.catch_pad(cs, &[tydesc, bx.const_i32(0), slot]);
         let addr = catchpad.load(slot, ptr_align);
 
         let i64_align = bx.tcx().data_layout.i64_align.abi;
         let arg1 = catchpad.load(addr, i64_align);
-        let val1 = bx.cx().const_i32(1);
+        let val1 = bx.const_i32(1);
         let gep1 = catchpad.inbounds_gep(addr, &[val1]);
         let arg2 = catchpad.load(gep1, i64_align);
         let local_ptr = catchpad.bitcast(local_ptr, i64p);
@@ -917,7 +986,7 @@
         catchpad.store(arg2, gep2, i64_align);
         catchpad.catch_ret(&funclet, caught.llbb());
 
-        caught.ret(bx.cx().const_i32(1));
+        caught.ret(bx.const_i32(1));
     });
 
     // Note that no invoke is used here because by definition this function
@@ -945,7 +1014,7 @@
     local_ptr: &'ll Value,
     dest: &'ll Value,
 ) {
-    let llfn = get_rust_try_fn(bx.cx(), &mut |mut bx| {
+    let llfn = get_rust_try_fn(bx, &mut |mut bx| {
         // Codegens the shims described above:
         //
         //   bx:
@@ -970,7 +1039,7 @@
         let data = llvm::get_param(bx.llfn(), 1);
         let local_ptr = llvm::get_param(bx.llfn(), 2);
         bx.invoke(func, &[data], then.llbb(), catch.llbb(), None);
-        then.ret(bx.cx().const_i32(0));
+        then.ret(bx.const_i32(0));
 
         // Type indicator for the exception being thrown.
         //
@@ -978,14 +1047,14 @@
         // being thrown.  The second value is a "selector" indicating which of
         // the landing pad clauses the exception's type had been matched to.
         // rust_try ignores the selector.
-        let lpad_ty = bx.cx().type_struct(&[bx.cx().type_i8p(), bx.cx().type_i32()], false);
-        let vals = catch.landing_pad(lpad_ty, bx.cx().eh_personality(), 1);
-        catch.add_clause(vals, bx.cx().const_null(bx.cx().type_i8p()));
+        let lpad_ty = bx.type_struct(&[bx.type_i8p(), bx.type_i32()], false);
+        let vals = catch.landing_pad(lpad_ty, bx.eh_personality(), 1);
+        catch.add_clause(vals, bx.const_null(bx.type_i8p()));
         let ptr = catch.extract_value(vals, 0);
         let ptr_align = bx.tcx().data_layout.pointer_align.abi;
-        let bitcast = catch.bitcast(local_ptr, bx.cx().type_ptr_to(bx.cx().type_i8p()));
+        let bitcast = catch.bitcast(local_ptr, bx.type_ptr_to(bx.type_i8p()));
         catch.store(ptr, bitcast, ptr_align);
-        catch.ret(bx.cx().const_i32(1));
+        catch.ret(bx.const_i32(1));
     });
 
     // Note that no invoke is used here because by definition this function
@@ -1066,7 +1135,7 @@
         };
         ($msg: tt, $($fmt: tt)*) => {
             span_invalid_monomorphization_error(
-                bx.cx().sess(), span,
+                bx.sess(), span,
                 &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg),
                          name, $($fmt)*));
         }
@@ -1127,7 +1196,7 @@
                   found `{}` with length {}",
                  in_len, in_ty,
                  ret_ty, out_len);
-        require!(bx.cx().type_kind(bx.cx().element_type(llret_ty)) == TypeKind::Integer,
+        require!(bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
                  "expected return type with integer elements, found `{}` with non-integer `{}`",
                  ret_ty,
                  ret_ty.simd_type(tcx));
@@ -1163,8 +1232,8 @@
         let indices: Option<Vec<_>> = (0..n)
             .map(|i| {
                 let arg_idx = i;
-                let val = bx.cx().const_get_elt(vector, i as u64);
-                match bx.cx().const_to_opt_u128(val, true) {
+                let val = bx.const_get_elt(vector, i as u64);
+                match bx.const_to_opt_u128(val, true) {
                     None => {
                         emit_error!("shuffle index #{} is not a constant", arg_idx);
                         None
@@ -1174,18 +1243,18 @@
                                     arg_idx, total_len);
                         None
                     }
-                    Some(idx) => Some(bx.cx().const_i32(idx as i32)),
+                    Some(idx) => Some(bx.const_i32(idx as i32)),
                 }
             })
             .collect();
         let indices = match indices {
             Some(i) => i,
-            None => return Ok(bx.cx().const_null(llret_ty))
+            None => return Ok(bx.const_null(llret_ty))
         };
 
         return Ok(bx.shuffle_vector(args[0].immediate(),
                                     args[1].immediate(),
-                                    bx.cx().const_vector(&indices)))
+                                    bx.const_vector(&indices)))
     }
 
     if name == "simd_insert" {
@@ -1216,8 +1285,8 @@
             _ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty)
         }
         // truncate the mask to a vector of i1s
-        let i1 = bx.cx().type_i1();
-        let i1xn = bx.cx().type_vector(i1, m_len as u64);
+        let i1 = bx.type_i1();
+        let i1xn = bx.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()));
     }
@@ -1237,7 +1306,7 @@
             };
             ($msg: tt, $($fmt: tt)*) => {
                 span_invalid_monomorphization_error(
-                    bx.cx().sess(), span,
+                    bx.sess(), span,
                     &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg),
                              name, $($fmt)*));
             }
@@ -1278,7 +1347,7 @@
         };
 
         let llvm_name = &format!("llvm.{0}.v{1}{2}", name, in_len, ety);
-        let intrinsic = bx.cx().get_intrinsic(&llvm_name);
+        let intrinsic = bx.get_intrinsic(&llvm_name);
         let c = bx.call(intrinsic,
                         &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
                         None);
@@ -1435,28 +1504,28 @@
         }
 
         // Alignment of T, must be a constant integer value:
-        let alignment_ty = bx.cx().type_i32();
-        let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).bytes() as i32);
+        let alignment_ty = bx.type_i32();
+        let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32);
 
         // Truncate the mask vector to a vector of i1s:
         let (mask, mask_ty) = {
-            let i1 = bx.cx().type_i1();
-            let i1xn = bx.cx().type_vector(i1, in_len as u64);
+            let i1 = bx.type_i1();
+            let i1xn = bx.type_vector(i1, in_len as u64);
             (bx.trunc(args[2].immediate(), i1xn), i1xn)
         };
 
         // Type of the vector of pointers:
-        let llvm_pointer_vec_ty = llvm_vector_ty(bx.cx(), underlying_ty, in_len, pointer_count);
+        let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count);
         let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count);
 
         // Type of the vector of elements:
-        let llvm_elem_vec_ty = llvm_vector_ty(bx.cx(), underlying_ty, in_len, pointer_count - 1);
+        let llvm_elem_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count - 1);
         let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1);
 
         let llvm_intrinsic = format!("llvm.masked.gather.{}.{}",
                                      llvm_elem_vec_str, llvm_pointer_vec_str);
-        let f = bx.cx().declare_cfn(&llvm_intrinsic,
-                                     bx.cx().type_func(&[
+        let f = bx.declare_cfn(&llvm_intrinsic,
+                                     bx.type_func(&[
                                          llvm_pointer_vec_ty,
                                          alignment_ty,
                                          mask_ty,
@@ -1535,30 +1604,30 @@
         }
 
         // Alignment of T, must be a constant integer value:
-        let alignment_ty = bx.cx().type_i32();
-        let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).bytes() as i32);
+        let alignment_ty = bx.type_i32();
+        let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32);
 
         // Truncate the mask vector to a vector of i1s:
         let (mask, mask_ty) = {
-            let i1 = bx.cx().type_i1();
-            let i1xn = bx.cx().type_vector(i1, in_len as u64);
+            let i1 = bx.type_i1();
+            let i1xn = bx.type_vector(i1, in_len as u64);
             (bx.trunc(args[2].immediate(), i1xn), i1xn)
         };
 
-        let ret_t = bx.cx().type_void();
+        let ret_t = bx.type_void();
 
         // Type of the vector of pointers:
-        let llvm_pointer_vec_ty = llvm_vector_ty(bx.cx(), underlying_ty, in_len, pointer_count);
+        let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count);
         let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count);
 
         // Type of the vector of elements:
-        let llvm_elem_vec_ty = llvm_vector_ty(bx.cx(), underlying_ty, in_len, pointer_count - 1);
+        let llvm_elem_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count - 1);
         let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1);
 
         let llvm_intrinsic = format!("llvm.masked.scatter.{}.{}",
                                      llvm_elem_vec_str, llvm_pointer_vec_str);
-        let f = bx.cx().declare_cfn(&llvm_intrinsic,
-                                     bx.cx().type_func(&[llvm_elem_vec_ty,
+        let f = bx.declare_cfn(&llvm_intrinsic,
+                                     bx.type_func(&[llvm_elem_vec_ty,
                                                   llvm_pointer_vec_ty,
                                                   alignment_ty,
                                                   mask_ty], ret_t));
@@ -1598,7 +1667,7 @@
                             //   code is generated
                             // * if the accumulator of the fmul isn't 1, incorrect
                             //   code is generated
-                            match bx.cx().const_get_real(acc) {
+                            match bx.const_get_real(acc) {
                                 None => return_error!("accumulator of {} is not a constant", $name),
                                 Some((v, loses_info)) => {
                                     if $name.contains("mul") && v != 1.0_f64 {
@@ -1614,8 +1683,8 @@
                         } else {
                             // unordered arithmetic reductions do not:
                             match f.bit_width() {
-                                32 => bx.cx().const_undef(bx.cx().type_f32()),
-                                64 => bx.cx().const_undef(bx.cx().type_f64()),
+                                32 => bx.const_undef(bx.type_f32()),
+                                64 => bx.const_undef(bx.type_f64()),
                                 v => {
                                     return_error!(r#"
 unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
@@ -1692,8 +1761,8 @@
                     }
 
                     // boolean reductions operate on vectors of i1s:
-                    let i1 = bx.cx().type_i1();
-                    let i1xn = bx.cx().type_vector(i1, in_len as u64);
+                    let i1 = bx.type_i1();
+                    let i1xn = bx.type_vector(i1, in_len as u64);
                     bx.trunc(args[0].immediate(), i1xn)
                 };
                 return match in_elem.sty {
@@ -1703,7 +1772,7 @@
                             if !$boolean {
                                 r
                             } else {
-                                bx.zext(r, bx.cx().type_bool())
+                                bx.zext(r, bx.type_bool())
                             }
                         )
                     },
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index f904a92..4f90cb7 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -127,6 +127,7 @@
 mod type_;
 mod type_of;
 mod value;
+mod va_arg;
 
 #[derive(Clone)]
 pub struct LlvmCodegenBackend(());
diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs
index 2a77f25..d5c73fe 100644
--- a/src/librustc_codegen_llvm/llvm/archive_ro.rs
+++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs
@@ -10,10 +10,10 @@
 
 //! A wrapper around LLVM's archive (.a) code
 
-use std::ffi::CString;
 use std::path::Path;
 use std::slice;
 use std::str;
+use rustc_fs_util::path_to_c_string;
 
 pub struct ArchiveRO {
     pub raw: &'static mut super::Archive,
@@ -38,24 +38,12 @@
     /// raised.
     pub fn open(dst: &Path) -> Result<ArchiveRO, String> {
         return unsafe {
-            let s = path2cstr(dst);
+            let s = path_to_c_string(dst);
             let ar = super::LLVMRustOpenArchive(s.as_ptr()).ok_or_else(|| {
                 super::last_error().unwrap_or_else(|| "failed to open archive".to_owned())
             })?;
             Ok(ArchiveRO { raw: ar })
         };
-
-        #[cfg(unix)]
-        fn path2cstr(p: &Path) -> CString {
-            use std::os::unix::prelude::*;
-            use std::ffi::OsStr;
-            let p: &OsStr = p.as_ref();
-            CString::new(p.as_bytes()).unwrap()
-        }
-        #[cfg(windows)]
-        fn path2cstr(p: &Path) -> CString {
-            CString::new(p.to_str().unwrap()).unwrap()
-        }
     }
 
     pub fn iter(&self) -> Iter {
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index f1a966d..127759a 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -1358,6 +1358,7 @@
     pub fn LLVMRustDebugMetadataVersion() -> u32;
     pub fn LLVMRustVersionMajor() -> u32;
     pub fn LLVMRustVersionMinor() -> u32;
+    pub fn LLVMRustIsRustLLVM() -> bool;
 
     pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32);
 
@@ -1586,9 +1587,10 @@
                                             LineNo: c_uint)
                                             -> &'a DINameSpace;
 
-    pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &DIBuilder<'a>,
-                                               CompositeType: &'a DIType,
-                                               TypeArray: &'a DIArray);
+    pub fn LLVMRustDICompositeTypeReplaceArrays(Builder: &DIBuilder<'a>,
+                                                CompositeType: &'a DIType,
+                                                Elements: Option<&'a DIArray>,
+                                                Params: Option<&'a DIArray>);
 
 
     pub fn LLVMRustDIBuilderCreateDebugLocation(Context: &'a Context,
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 267d7e0..fdb6373 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -70,6 +70,9 @@
         if sess.opts.debugging_opts.disable_instrumentation_preinliner {
             add("-disable-preinline");
         }
+        if llvm::LLVMRustIsRustLLVM() {
+            add("-mergefunc-use-aliases");
+        }
 
         for arg in &sess.opts.cg.llvm_args {
             add(&(*arg));
diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs
index 7752465..5605f64 100644
--- a/src/librustc_codegen_llvm/metadata.rs
+++ b/src/librustc_codegen_llvm/metadata.rs
@@ -18,7 +18,7 @@
 use std::path::Path;
 use std::ptr;
 use std::slice;
-use rustc_fs_util::path2cstr;
+use rustc_fs_util::path_to_c_string;
 
 pub use rustc_data_structures::sync::MetadataRef;
 
@@ -57,7 +57,7 @@
                           filename: &Path)
                           -> Result<MetadataRef, String> {
         unsafe {
-            let buf = path2cstr(filename);
+            let buf = path_to_c_string(filename);
             let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr())
                 .ok_or_else(|| format!("error reading library: '{}'", filename.display()))?;
             let of = ObjectFile::new(mb)
diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs
index 5c4ebc3..b100b67 100644
--- a/src/librustc_codegen_llvm/type_.rs
+++ b/src/librustc_codegen_llvm/type_.rs
@@ -47,6 +47,22 @@
     }
 }
 
+impl CodegenCx<'ll, 'tcx> {
+    crate fn type_named_struct(&self, name: &str) -> &'ll Type {
+        let name = SmallCStr::new(name);
+        unsafe {
+            llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr())
+        }
+    }
+
+    crate fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) {
+        unsafe {
+            llvm::LLVMStructSetBody(ty, els.as_ptr(),
+                                    els.len() as c_uint, packed as Bool)
+        }
+    }
+}
+
 impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn type_void(&self) -> &'ll Type {
         unsafe {
@@ -160,13 +176,6 @@
         }
     }
 
-    fn type_named_struct(&self, name: &str) -> &'ll Type {
-        let name = SmallCStr::new(name);
-        unsafe {
-            llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr())
-        }
-    }
-
 
     fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type {
         unsafe {
@@ -186,13 +195,6 @@
         }
     }
 
-    fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) {
-        unsafe {
-            llvm::LLVMStructSetBody(ty, els.as_ptr(),
-                                    els.len() as c_uint, packed as Bool)
-        }
-    }
-
     fn type_ptr_to(&self, ty: &'ll Type) -> &'ll Type {
         assert_ne!(self.type_kind(ty), TypeKind::Function,
                    "don't call ptr_to on function types, use ptr_to_llvm_type on FnType instead");
diff --git a/src/librustc_codegen_llvm/va_arg.rs b/src/librustc_codegen_llvm/va_arg.rs
new file mode 100644
index 0000000..fbc3e6f
--- /dev/null
+++ b/src/librustc_codegen_llvm/va_arg.rs
@@ -0,0 +1,142 @@
+// 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 builder::Builder;
+use rustc_codegen_ssa::mir::operand::OperandRef;
+use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods, ConstMethods, DerivedTypeMethods};
+use rustc::ty::layout::{Align, HasDataLayout, HasTyCtxt, LayoutOf, Size};
+use rustc::ty::Ty;
+use type_::Type;
+use type_of::LayoutLlvmExt;
+use value::Value;
+
+#[allow(dead_code)]
+fn round_pointer_up_to_alignment(
+    bx: &mut Builder<'a, 'll, 'tcx>,
+    addr: &'ll Value,
+    align: Align,
+    ptr_ty: &'ll Type
+) -> &'ll Value {
+    let mut ptr_as_int = bx.ptrtoint(addr, bx.cx().type_isize());
+    ptr_as_int = bx.add(ptr_as_int, bx.cx().const_i32(align.bytes() as i32 - 1));
+    ptr_as_int = bx.and(ptr_as_int, bx.cx().const_i32(-(align.bytes() as i32)));
+    bx.inttoptr(ptr_as_int, ptr_ty)
+}
+
+fn emit_direct_ptr_va_arg(
+    bx: &mut Builder<'a, 'll, 'tcx>,
+    list: OperandRef<'tcx, &'ll Value>,
+    llty: &'ll Type,
+    size: Size,
+    align: Align,
+    slot_size: Align,
+    allow_higher_align: bool
+) -> (&'ll Value, Align) {
+    let va_list_ptr_ty = bx.cx().type_ptr_to(bx.cx.type_i8p());
+    let va_list_addr = if list.layout.llvm_type(bx.cx) != va_list_ptr_ty {
+        bx.bitcast(list.immediate(), va_list_ptr_ty)
+    } else {
+        list.immediate()
+    };
+
+    let ptr = bx.load(va_list_addr, bx.tcx().data_layout.pointer_align.abi);
+
+    let (addr, addr_align) = if allow_higher_align && align > slot_size {
+        (round_pointer_up_to_alignment(bx, ptr, align, bx.cx().type_i8p()), align)
+    } else {
+        (ptr, slot_size)
+    };
+
+
+    let aligned_size = size.align_to(slot_size).bytes() as i32;
+    let full_direct_size = bx.cx().const_i32(aligned_size);
+    let next = bx.inbounds_gep(addr, &[full_direct_size]);
+    bx.store(next, va_list_addr, bx.tcx().data_layout.pointer_align.abi);
+
+    if size.bytes() < slot_size.bytes() &&
+            &*bx.tcx().sess.target.target.target_endian == "big" {
+        let adjusted_size = bx.cx().const_i32((slot_size.bytes() - size.bytes()) as i32);
+        let adjusted = bx.inbounds_gep(addr, &[adjusted_size]);
+        (bx.bitcast(adjusted, bx.cx().type_ptr_to(llty)), addr_align)
+    } else {
+        (bx.bitcast(addr, bx.cx().type_ptr_to(llty)), addr_align)
+    }
+}
+
+fn emit_ptr_va_arg(
+    bx: &mut Builder<'a, 'll, 'tcx>,
+    list: OperandRef<'tcx, &'ll Value>,
+    target_ty: Ty<'tcx>,
+    indirect: bool,
+    slot_size: Align,
+    allow_higher_align: bool
+) -> &'ll Value {
+    let layout = bx.cx.layout_of(target_ty);
+    let (llty, size, align) = if indirect {
+        (bx.cx.layout_of(bx.cx.tcx.mk_imm_ptr(target_ty)).llvm_type(bx.cx),
+         bx.cx.data_layout().pointer_size,
+         bx.cx.data_layout().pointer_align)
+    } else {
+        (layout.llvm_type(bx.cx),
+         layout.size,
+         layout.align)
+    };
+    let (addr, addr_align) = emit_direct_ptr_va_arg(bx, list, llty, size, align.abi,
+                                                    slot_size, allow_higher_align);
+    if indirect {
+        let tmp_ret = bx.load(addr, addr_align);
+        bx.load(tmp_ret, align.abi)
+    } else {
+        bx.load(addr, addr_align)
+    }
+}
+
+pub(super) fn emit_va_arg(
+    bx: &mut Builder<'a, 'll, 'tcx>,
+    addr: OperandRef<'tcx, &'ll Value>,
+    target_ty: Ty<'tcx>,
+) -> &'ll Value {
+    // Determine the va_arg implementation to use. The LLVM va_arg instruction
+    // is lacking in some instances, so we should only use it as a fallback.
+    let arch = &bx.cx.tcx.sess.target.target.arch;
+    match (&**arch,
+           bx.cx.tcx.sess.target.target.options.is_like_windows) {
+        ("x86", true) => {
+            emit_ptr_va_arg(bx, addr, target_ty, false,
+                            Align::from_bytes(4).unwrap(), false)
+        }
+        ("x86_64", true) => {
+            let target_ty_size = bx.cx.size_of(target_ty).bytes();
+            let indirect = if target_ty_size > 8 || !target_ty_size.is_power_of_two() {
+                true
+            } else {
+                false
+            };
+            emit_ptr_va_arg(bx, addr, target_ty, indirect,
+                            Align::from_bytes(8).unwrap(), false)
+        }
+        ("x86", false) => {
+            emit_ptr_va_arg(bx, addr, target_ty, false,
+                            Align::from_bytes(4).unwrap(), true)
+        }
+        _ => {
+            let va_list = if (bx.tcx().sess.target.target.arch == "aarch64" ||
+                              bx.tcx().sess.target.target.arch == "x86_64" ||
+                              bx.tcx().sess.target.target.arch == "powerpc") &&
+                             !bx.tcx().sess.target.target.options.is_like_windows {
+                bx.load(addr.immediate(), bx.tcx().data_layout.pointer_align.abi)
+            } else {
+                addr.immediate()
+            };
+            bx.va_arg(va_list, bx.cx.layout_of(target_ty).llvm_type(bx.cx))
+        }
+    }
+}
+
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index b0575b8..24a70dc 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -161,7 +161,11 @@
                 LinkerFlavor::Lld(_) => "lld",
             }), flavor)),
             (Some(linker), None) => {
-                let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| {
+                let stem = if linker.extension().and_then(|ext| ext.to_str()) == Some("exe") {
+                    linker.file_stem().and_then(|stem| stem.to_str())
+                } else {
+                    linker.to_str()
+                }.unwrap_or_else(|| {
                     sess.fatal("couldn't extract file stem from specified linker");
                 }).to_owned();
 
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index 0463da0..ecae619 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -157,7 +157,7 @@
         })
         .collect();
 
-    if let Some(id) = *tcx.sess.derive_registrar_fn.get() {
+    if let Some(id) = *tcx.sess.proc_macro_decls_static.get() {
         let def_id = tcx.hir.local_def_id(id);
         reachable_non_generics.insert(def_id, SymbolExportLevel::C);
     }
@@ -225,14 +225,15 @@
         // 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] = [
+        const PROFILER_WEAK_SYMBOLS: [&str; 2] = [
             "__llvm_profile_raw_version",
             "__llvm_profile_filename",
         ];
-        for sym in &PROFILER_WEAK_SYMBOLS {
+
+        symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| {
             let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(sym));
-            symbols.push((exported_symbol, SymbolExportLevel::C));
-        }
+            (exported_symbol, SymbolExportLevel::C)
+        }));
     }
 
     if tcx.sess.crate_types.borrow().contains(&config::CrateType::Dylib) {
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index 856bb95..266f789 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -192,7 +192,7 @@
         (_, &ty::Dynamic(ref data, ..)) => {
             let vtable_ptr = cx.layout_of(cx.tcx().mk_mut_ptr(target))
                 .field(cx, FAT_PTR_EXTRA);
-            cx.static_ptrcast(meth::get_vtable(cx, source, data.principal()),
+            cx.const_ptrcast(meth::get_vtable(cx, source, data.principal()),
                             cx.backend_type(vtable_ptr))
         }
         _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}",
@@ -366,14 +366,6 @@
     sess.target.target.options.is_like_msvc
 }
 
-pub fn call_assume<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
-    bx: &mut Bx,
-    val: Bx::Value
-) {
-    let assume_intrinsic = bx.cx().get_intrinsic("llvm.assume");
-    bx.call(assume_intrinsic, &[val], None);
-}
-
 pub fn from_immediate<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     val: Bx::Value
diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs
index 6259318..8c53129 100644
--- a/src/librustc_codegen_ssa/common.rs
+++ b/src/librustc_codegen_ssa/common.rs
@@ -194,7 +194,7 @@
     bx: &mut Bx,
     rhs: Bx::Value
 ) -> Bx::Value {
-    let rhs_llty = bx.cx().val_ty(rhs);
+    let rhs_llty = bx.val_ty(rhs);
     let shift_val = shift_mask_val(bx, rhs_llty, rhs_llty, false);
     bx.and(rhs, shift_val)
 }
@@ -205,25 +205,25 @@
     mask_llty: Bx::Type,
     invert: bool
 ) -> Bx::Value {
-    let kind = bx.cx().type_kind(llty);
+    let kind = bx.type_kind(llty);
     match kind {
         TypeKind::Integer => {
             // i8/u8 can shift by at most 7, i16/u16 by at most 15, etc.
-            let val = bx.cx().int_width(llty) - 1;
+            let val = bx.int_width(llty) - 1;
             if invert {
-                bx.cx().const_int(mask_llty, !val as i64)
+                bx.const_int(mask_llty, !val as i64)
             } else {
-                bx.cx().const_uint(mask_llty, val)
+                bx.const_uint(mask_llty, val)
             }
         },
         TypeKind::Vector => {
             let mask = shift_mask_val(
                 bx,
-                bx.cx().element_type(llty),
-                bx.cx().element_type(mask_llty),
+                bx.element_type(llty),
+                bx.element_type(mask_llty),
                 invert
             );
-            bx.vector_splat(bx.cx().vector_length(mask_llty), mask)
+            bx.vector_splat(bx.vector_length(mask_llty), mask)
         },
         _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
     }
diff --git a/src/librustc_codegen_ssa/debuginfo.rs b/src/librustc_codegen_ssa/debuginfo.rs
index 0fc6142..bcf6d7b 100644
--- a/src/librustc_codegen_ssa/debuginfo.rs
+++ b/src/librustc_codegen_ssa/debuginfo.rs
@@ -23,22 +23,21 @@
         match *self {
             FunctionDebugContext::RegularContext(ref data) => data,
             FunctionDebugContext::DebugInfoDisabled => {
-                span_bug!(span, "{}", FunctionDebugContext::<D>::debuginfo_disabled_message());
+                span_bug!(
+                    span,
+                    "debuginfo: Error trying to access FunctionDebugContext \
+                     although debug info is disabled!",
+                );
             }
             FunctionDebugContext::FunctionWithoutDebugInfo => {
-                span_bug!(span, "{}", FunctionDebugContext::<D>::should_be_ignored_message());
+                span_bug!(
+                    span,
+                    "debuginfo: Error trying to access FunctionDebugContext \
+                     for function that should be ignored by debug info!",
+                );
             }
         }
     }
-
-    fn debuginfo_disabled_message() -> &'static str {
-        "debuginfo: Error trying to access FunctionDebugContext although debug info is disabled!"
-    }
-
-    fn should_be_ignored_message() -> &'static str {
-        "debuginfo: Error trying to access FunctionDebugContext for function that should be \
-         ignored by debug info!"
-    }
 }
 
 /// Enables emitting source locations for the given functions.
diff --git a/src/librustc_codegen_ssa/glue.rs b/src/librustc_codegen_ssa/glue.rs
index bb28ea7..b3257db 100644
--- a/src/librustc_codegen_ssa/glue.rs
+++ b/src/librustc_codegen_ssa/glue.rs
@@ -16,7 +16,6 @@
 
 use common::IntPredicate;
 use meth;
-use rustc::ty::layout::LayoutOf;
 use rustc::ty::{self, Ty};
 use traits::*;
 
@@ -25,12 +24,12 @@
     t: Ty<'tcx>,
     info: Option<Bx::Value>
 ) -> (Bx::Value, Bx::Value) {
-    let layout = bx.cx().layout_of(t);
+    let layout = bx.layout_of(t);
     debug!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}",
            t, info, layout);
     if !layout.is_unsized() {
-        let size = bx.cx().const_usize(layout.size.bytes());
-        let align = bx.cx().const_usize(layout.align.abi.bytes());
+        let size = bx.const_usize(layout.size.bytes());
+        let align = bx.const_usize(layout.align.abi.bytes());
         return (size, align);
     }
     match t.sty {
@@ -40,11 +39,11 @@
             (meth::SIZE.get_usize(bx, vtable), meth::ALIGN.get_usize(bx, vtable))
         }
         ty::Slice(_) | ty::Str => {
-            let unit = layout.field(bx.cx(), 0);
+            let unit = layout.field(bx, 0);
             // The info in this case is the length of the str, so the size is that
             // times the unit size.
-            (bx.mul(info.unwrap(), bx.cx().const_usize(unit.size.bytes())),
-             bx.cx().const_usize(unit.align.abi.bytes()))
+            (bx.mul(info.unwrap(), bx.const_usize(unit.size.bytes())),
+             bx.const_usize(unit.align.abi.bytes()))
         }
         _ => {
             // First get the size of all statically known fields.
@@ -58,12 +57,12 @@
             let sized_align = layout.align.abi.bytes();
             debug!("DST {} statically sized prefix size: {} align: {}",
                    t, sized_size, sized_align);
-            let sized_size = bx.cx().const_usize(sized_size);
-            let sized_align = bx.cx().const_usize(sized_align);
+            let sized_size = bx.const_usize(sized_size);
+            let sized_align = bx.const_usize(sized_align);
 
             // Recurse to get the size of the dynamically sized field (must be
             // the last field).
-            let field_ty = layout.field(bx.cx(), i).ty;
+            let field_ty = layout.field(bx, i).ty;
             let (unsized_size, mut unsized_align) = size_and_align_of_dst(bx, field_ty, info);
 
             // FIXME (#26403, #27023): We should be adding padding
@@ -85,12 +84,12 @@
 
             // Choose max of two known alignments (combined value must
             // be aligned according to more restrictive of the two).
-            let align = match (bx.cx().const_to_opt_u128(sized_align, false),
-                               bx.cx().const_to_opt_u128(unsized_align, false)) {
+            let align = match (bx.const_to_opt_u128(sized_align, false),
+                               bx.const_to_opt_u128(unsized_align, false)) {
                 (Some(sized_align), Some(unsized_align)) => {
                     // If both alignments are constant, (the sized_align should always be), then
                     // pick the correct alignment statically.
-                    bx.cx().const_usize(std::cmp::max(sized_align, unsized_align) as u64)
+                    bx.const_usize(std::cmp::max(sized_align, unsized_align) as u64)
                 }
                 _ => {
                     let cmp = bx.icmp(IntPredicate::IntUGT, sized_align, unsized_align);
@@ -108,7 +107,7 @@
             // emulated via the semi-standard fast bit trick:
             //
             //   `(size + (align-1)) & -align`
-            let one = bx.cx().const_usize(1);
+            let one = bx.const_usize(1);
             let addend = bx.sub(align, one);
             let add = bx.add(size, addend);
             let neg =  bx.neg(align);
diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs
index d70fcf6..3880935 100644
--- a/src/librustc_codegen_ssa/meth.rs
+++ b/src/librustc_codegen_ssa/meth.rs
@@ -39,10 +39,10 @@
 
         let llvtable = bx.pointercast(
             llvtable,
-            bx.cx().type_ptr_to(bx.cx().fn_ptr_backend_type(fn_ty))
+            bx.type_ptr_to(bx.fn_ptr_backend_type(fn_ty))
         );
         let ptr_align = bx.tcx().data_layout.pointer_align.abi;
-        let gep = bx.inbounds_gep(llvtable, &[bx.cx().const_usize(self.0)]);
+        let gep = bx.inbounds_gep(llvtable, &[bx.const_usize(self.0)]);
         let ptr = bx.load(gep, ptr_align);
         bx.nonnull_metadata(ptr);
         // Vtable loads are invariant
@@ -58,9 +58,9 @@
         // Load the data pointer from the object.
         debug!("get_int({:?}, {:?})", llvtable, self);
 
-        let llvtable = bx.pointercast(llvtable, bx.cx().type_ptr_to(bx.cx().type_isize()));
+        let llvtable = bx.pointercast(llvtable, bx.type_ptr_to(bx.type_isize()));
         let usize_align = bx.tcx().data_layout.pointer_align.abi;
-        let gep = bx.inbounds_gep(llvtable, &[bx.cx().const_usize(self.0)]);
+        let gep = bx.inbounds_gep(llvtable, &[bx.const_usize(self.0)]);
         let ptr = bx.load(gep, usize_align);
         // Vtable loads are invariant
         bx.set_invariant_load(ptr);
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 75a6f07..a3bfbc2 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -182,22 +182,20 @@
                     let lp1 = bx.load_operand(lp1).immediate();
                     slot.storage_dead(&mut bx);
 
-                    if !bx.cx().sess().target.target.options.custom_unwind_resume {
-                        let mut lp = bx.cx().const_undef(self.landing_pad_type());
+                    if !bx.sess().target.target.options.custom_unwind_resume {
+                        let mut lp = bx.const_undef(self.landing_pad_type());
                         lp = bx.insert_value(lp, lp0, 0);
                         lp = bx.insert_value(lp, lp1, 1);
                         bx.resume(lp);
                     } else {
-                        bx.call(bx.cx().eh_unwind_resume(), &[lp0], funclet(self));
+                        bx.call(bx.eh_unwind_resume(), &[lp0], funclet(self));
                         bx.unreachable();
                     }
                 }
             }
 
             mir::TerminatorKind::Abort => {
-                // Call core::intrinsics::abort()
-                let fnname = bx.cx().get_intrinsic(&("llvm.trap"));
-                bx.call(fnname, &[], None);
+                bx.abort();
                 bx.unreachable();
             }
 
@@ -220,10 +218,10 @@
                             bx.cond_br(discr.immediate(), lltrue, llfalse);
                         }
                     } else {
-                        let switch_llty = bx.cx().immediate_backend_type(
-                            bx.cx().layout_of(switch_ty)
+                        let switch_llty = bx.immediate_backend_type(
+                            bx.layout_of(switch_ty)
                         );
-                        let llval = bx.cx().const_uint_big(switch_llty, values[0]);
+                        let llval = bx.const_uint_big(switch_llty, values[0]);
                         let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval);
                         bx.cond_br(cmp, lltrue, llfalse);
                     }
@@ -232,11 +230,11 @@
                     let switch = bx.switch(discr.immediate(),
                                            llblock(self, *otherwise),
                                            values.len());
-                    let switch_llty = bx.cx().immediate_backend_type(
-                        bx.cx().layout_of(switch_ty)
+                    let switch_llty = bx.immediate_backend_type(
+                        bx.layout_of(switch_ty)
                     );
                     for (&value, target) in values.iter().zip(targets) {
-                        let llval = bx.cx().const_uint_big(switch_llty, value);
+                        let llval = bx.const_uint_big(switch_llty, value);
                         let llbb = llblock(self, *target);
                         bx.add_case(switch, llval, llbb)
                     }
@@ -285,8 +283,8 @@
                                 llval
                             }
                         };
-                        let addr = bx.pointercast(llslot, bx.cx().type_ptr_to(
-                            bx.cx().cast_backend_type(&cast_ty)
+                        let addr = bx.pointercast(llslot, bx.type_ptr_to(
+                            bx.cast_backend_type(&cast_ty)
                         ));
                         bx.load(addr, self.fn_ty.ret.layout.align.abi)
                     }
@@ -301,7 +299,7 @@
             mir::TerminatorKind::Drop { ref location, target, unwind } => {
                 let ty = location.ty(self.mir, bx.tcx()).to_ty(bx.tcx());
                 let ty = self.monomorphize(&ty);
-                let drop_fn = monomorphize::resolve_drop_in_place(bx.cx().tcx(), ty);
+                let drop_fn = monomorphize::resolve_drop_in_place(bx.tcx(), ty);
 
                 if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def {
                     // we don't actually need to drop anything.
@@ -325,14 +323,14 @@
                             ty::ParamEnv::reveal_all(),
                             &sig,
                         );
-                        let fn_ty = bx.cx().new_vtable(sig, &[]);
+                        let fn_ty = bx.new_vtable(sig, &[]);
                         let vtable = args[1];
                         args = &args[..1];
                         (meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_ty), fn_ty)
                     }
                     _ => {
-                        (bx.cx().get_fn(drop_fn),
-                         bx.cx().fn_type_of_instance(&drop_fn))
+                        (bx.get_fn(drop_fn),
+                         bx.fn_type_of_instance(&drop_fn))
                     }
                 };
                 do_call(self, &mut bx, fn_ty, drop_fn, args,
@@ -342,7 +340,7 @@
 
             mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, cleanup } => {
                 let cond = self.codegen_operand(&mut bx, cond).immediate();
-                let mut const_cond = bx.cx().const_to_opt_u128(cond, false).map(|c| c == 1);
+                let mut const_cond = bx.const_to_opt_u128(cond, false).map(|c| c == 1);
 
                 // This case can currently arise only from functions marked
                 // with #[rustc_inherit_overflow_checks] and inlined from
@@ -351,7 +349,7 @@
                 // NOTE: Unlike binops, negation doesn't have its own
                 // checked operation, just a comparison with the minimum
                 // value, so we have to check for the assert message.
-                if !bx.cx().check_overflow() {
+                if !bx.check_overflow() {
                     if let mir::interpret::EvalErrorKind::OverflowNeg = *msg {
                         const_cond = Some(expected);
                     }
@@ -364,8 +362,7 @@
                 }
 
                 // Pass the condition through llvm.expect for branch hinting.
-                let expect = bx.cx().get_intrinsic(&"llvm.expect.i1");
-                let cond = bx.call(expect, &[cond, bx.cx().const_bool(expected)], None);
+                let cond = bx.expect(cond, expected);
 
                 // Create the failure block and the conditional branch to it.
                 let lltarget = llblock(self, target);
@@ -381,11 +378,11 @@
                 self.set_debug_loc(&mut bx, terminator.source_info);
 
                 // Get the location information.
-                let loc = bx.cx().sess().source_map().lookup_char_pos(span.lo());
+                let loc = bx.sess().source_map().lookup_char_pos(span.lo());
                 let filename = Symbol::intern(&loc.file.name.to_string()).as_str();
-                let filename = bx.cx().const_str_slice(filename);
-                let line = bx.cx().const_u32(loc.line as u32);
-                let col = bx.cx().const_u32(loc.col.to_usize() as u32 + 1);
+                let filename = bx.const_str_slice(filename);
+                let line = bx.const_u32(loc.line as u32);
+                let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
                 let align = tcx.data_layout.aggregate_align.abi
                     .max(tcx.data_layout.i32_align.abi)
                     .max(tcx.data_layout.pointer_align.abi);
@@ -396,8 +393,8 @@
                         let len = self.codegen_operand(&mut bx, len).immediate();
                         let index = self.codegen_operand(&mut bx, index).immediate();
 
-                        let file_line_col = bx.cx().const_struct(&[filename, line, col], false);
-                        let file_line_col = bx.cx().static_addr_of(
+                        let file_line_col = bx.const_struct(&[filename, line, col], false);
+                        let file_line_col = bx.static_addr_of(
                             file_line_col,
                             align,
                             Some("panic_bounds_check_loc")
@@ -408,12 +405,12 @@
                     _ => {
                         let str = msg.description();
                         let msg_str = Symbol::intern(str).as_str();
-                        let msg_str = bx.cx().const_str_slice(msg_str);
-                        let msg_file_line_col = bx.cx().const_struct(
+                        let msg_str = bx.const_str_slice(msg_str);
+                        let msg_file_line_col = bx.const_struct(
                             &[msg_str, filename, line, col],
                             false
                         );
-                        let msg_file_line_col = bx.cx().static_addr_of(
+                        let msg_file_line_col = bx.static_addr_of(
                             msg_file_line_col,
                             align,
                             Some("panic_loc")
@@ -426,8 +423,8 @@
                 // Obtain the panic entry point.
                 let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
                 let instance = ty::Instance::mono(bx.tcx(), def_id);
-                let fn_ty = bx.cx().fn_type_of_instance(&instance);
-                let llfn = bx.cx().get_fn(instance);
+                let fn_ty = bx.fn_type_of_instance(&instance);
+                let llfn = bx.get_fn(instance);
 
                 // Codegen the actual panic invoke/call.
                 do_call(self, &mut bx, fn_ty, llfn, &args, None, cleanup);
@@ -449,7 +446,7 @@
 
                 let (instance, mut llfn) = match callee.layout.ty.sty {
                     ty::FnDef(def_id, substs) => {
-                        (Some(ty::Instance::resolve(bx.cx().tcx(),
+                        (Some(ty::Instance::resolve(bx.tcx(),
                                                     ty::ParamEnv::reveal_all(),
                                                     def_id,
                                                     substs).unwrap()),
@@ -488,7 +485,7 @@
                         // we can do what we like. Here, we declare that transmuting
                         // into an uninhabited type is impossible, so anything following
                         // it must be unreachable.
-                        assert_eq!(bx.cx().layout_of(sig.output()).abi, layout::Abi::Uninhabited);
+                        assert_eq!(bx.layout_of(sig.output()).abi, layout::Abi::Uninhabited);
                         bx.unreachable();
                     }
                     return;
@@ -502,7 +499,7 @@
 
                 let fn_ty = match def {
                     Some(ty::InstanceDef::Virtual(..)) => {
-                        bx.cx().new_vtable(sig, &extra_args)
+                        bx.new_vtable(sig, &extra_args)
                     }
                     Some(ty::InstanceDef::DropGlue(_, None)) => {
                         // empty drop glue - a nop.
@@ -510,18 +507,18 @@
                         funclet_br(self, &mut bx, target);
                         return;
                     }
-                    _ => bx.cx().new_fn_type(sig, &extra_args)
+                    _ => bx.new_fn_type(sig, &extra_args)
                 };
 
                 // emit a panic instead of instantiating an uninhabited type
                 if (intrinsic == Some("init") || intrinsic == Some("uninit")) &&
                     fn_ty.ret.layout.abi.is_uninhabited()
                 {
-                    let loc = bx.cx().sess().source_map().lookup_char_pos(span.lo());
+                    let loc = bx.sess().source_map().lookup_char_pos(span.lo());
                     let filename = Symbol::intern(&loc.file.name.to_string()).as_str();
-                    let filename = bx.cx().const_str_slice(filename);
-                    let line = bx.cx().const_u32(loc.line as u32);
-                    let col = bx.cx().const_u32(loc.col.to_usize() as u32 + 1);
+                    let filename = bx.const_str_slice(filename);
+                    let line = bx.const_u32(loc.line as u32);
+                    let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
                     let align = tcx.data_layout.aggregate_align.abi
                         .max(tcx.data_layout.i32_align.abi)
                         .max(tcx.data_layout.pointer_align.abi);
@@ -532,12 +529,12 @@
                         if intrinsic == Some("init") { "zeroed" } else { "uninitialized" }
                     );
                     let msg_str = Symbol::intern(&str).as_str();
-                    let msg_str = bx.cx().const_str_slice(msg_str);
-                    let msg_file_line_col = bx.cx().const_struct(
+                    let msg_str = bx.const_str_slice(msg_str);
+                    let msg_file_line_col = bx.const_struct(
                         &[msg_str, filename, line, col],
                         false,
                     );
-                    let msg_file_line_col = bx.cx().static_addr_of(
+                    let msg_file_line_col = bx.static_addr_of(
                         msg_file_line_col,
                         align,
                         Some("panic_loc"),
@@ -547,8 +544,8 @@
                     let def_id =
                         common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem);
                     let instance = ty::Instance::mono(bx.tcx(), def_id);
-                    let fn_ty = bx.cx().fn_type_of_instance(&instance);
-                    let llfn = bx.cx().get_fn(instance);
+                    let fn_ty = bx.fn_type_of_instance(&instance);
+                    let llfn = bx.get_fn(instance);
 
                     // Codegen the actual panic invoke/call.
                     do_call(
@@ -580,7 +577,7 @@
                     let dest = match ret_dest {
                         _ if fn_ty.ret.is_indirect() => llargs[0],
                         ReturnDest::Nothing => {
-                            bx.cx().const_undef(bx.cx().type_ptr_to(bx.memory_ty(&fn_ty.ret)))
+                            bx.const_undef(bx.type_ptr_to(bx.memory_ty(&fn_ty.ret)))
                         }
                         ReturnDest::IndirectOperand(dst, _) |
                         ReturnDest::Store(dst) => dst.llval,
@@ -614,7 +611,7 @@
                                     );
                                     return OperandRef {
                                         val: Immediate(llval),
-                                        layout: bx.cx().layout_of(ty),
+                                        layout: bx.layout_of(ty),
                                     };
 
                                 },
@@ -632,7 +629,7 @@
                                     );
                                     return OperandRef {
                                         val: Immediate(llval),
-                                        layout: bx.cx().layout_of(ty)
+                                        layout: bx.layout_of(ty)
                                     };
                                 }
                             }
@@ -642,7 +639,7 @@
                     }).collect();
 
 
-                    let callee_ty = instance.as_ref().unwrap().ty(bx.cx().tcx());
+                    let callee_ty = instance.as_ref().unwrap().ty(bx.tcx());
                     bx.codegen_intrinsic_call(callee_ty, &fn_ty, &args, dest,
                                                terminator.source_info.span);
 
@@ -739,7 +736,7 @@
 
                 let fn_ptr = match (llfn, instance) {
                     (Some(llfn), _) => llfn,
-                    (None, Some(instance)) => bx.cx().get_fn(instance),
+                    (None, Some(instance)) => bx.get_fn(instance),
                     _ => span_bug!(span, "no llfn for call"),
                 };
 
@@ -763,7 +760,7 @@
     ) {
         // Fill padding with undef value, where applicable.
         if let Some(ty) = arg.pad {
-            llargs.push(bx.cx().const_undef(bx.cx().reg_backend_type(&ty)))
+            llargs.push(bx.const_undef(bx.reg_backend_type(&ty)))
         }
 
         if arg.is_ignore() {
@@ -823,8 +820,8 @@
         if by_ref && !arg.is_indirect() {
             // Have to load the argument, maybe while casting it.
             if let PassMode::Cast(ty) = arg.mode {
-                let addr = bx.pointercast(llval, bx.cx().type_ptr_to(
-                    bx.cx().cast_backend_type(&ty))
+                let addr = bx.pointercast(llval, bx.type_ptr_to(
+                    bx.cast_backend_type(&ty))
                 );
                 llval = bx.load(addr, align.min(arg.layout.align.abi));
             } else {
@@ -1033,7 +1030,7 @@
                 LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
                 LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"),
                 LocalRef::Operand(None) => {
-                    let dst_layout = bx.cx().layout_of(self.monomorphized_place_ty(dst));
+                    let dst_layout = bx.layout_of(self.monomorphized_place_ty(dst));
                     assert!(!dst_layout.ty.has_erasable_regions());
                     let place = PlaceRef::alloca(bx, dst_layout, "transmute_temp");
                     place.storage_live(bx);
@@ -1060,8 +1057,8 @@
         dst: PlaceRef<'tcx, Bx::Value>
     ) {
         let src = self.codegen_operand(bx, src);
-        let llty = bx.cx().backend_type(src.layout);
-        let cast_ptr = bx.pointercast(dst.llval, bx.cx().type_ptr_to(llty));
+        let llty = bx.backend_type(src.layout);
+        let cast_ptr = bx.pointercast(dst.llval, bx.type_ptr_to(llty));
         let align = src.layout.align.abi.min(dst.align);
         src.val.store(bx, PlaceRef::new_sized(cast_ptr, src.layout, align));
     }
diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs
index 568e1f0..c03fff7 100644
--- a/src/librustc_codegen_ssa/mir/constant.rs
+++ b/src/librustc_codegen_ssa/mir/constant.rs
@@ -14,7 +14,7 @@
 use rustc_data_structures::indexed_vec::Idx;
 use rustc::mir::interpret::{GlobalId, ConstValue};
 use rustc::ty::{self, Ty};
-use rustc::ty::layout::{self, LayoutOf};
+use rustc::ty::layout;
 use syntax::source_map::Span;
 use traits::*;
 
@@ -75,20 +75,20 @@
                         c,
                     )?;
                     if let Some(prim) = field.val.try_to_scalar() {
-                        let layout = bx.cx().layout_of(field_ty);
+                        let layout = bx.layout_of(field_ty);
                         let scalar = match layout.abi {
                             layout::Abi::Scalar(ref x) => x,
                             _ => bug!("from_const: invalid ByVal layout: {:#?}", layout)
                         };
-                        Ok(bx.cx().scalar_to_backend(
+                        Ok(bx.scalar_to_backend(
                             prim, scalar,
-                            bx.cx().immediate_backend_type(layout),
+                            bx.immediate_backend_type(layout),
                         ))
                     } else {
                         bug!("simd shuffle field {:?}", field)
                     }
                 }).collect();
-                let llval = bx.cx().const_struct(&values?, false);
+                let llval = bx.const_struct(&values?, false);
                 Ok((llval, c.ty))
             })
             .unwrap_or_else(|_| {
@@ -98,8 +98,8 @@
                 );
                 // We've errored, so we don't have to produce working code.
                 let ty = self.monomorphize(&ty);
-                let llty = bx.cx().backend_type(bx.cx().layout_of(ty));
-                (bx.cx().const_undef(llty), ty)
+                let llty = bx.backend_type(bx.layout_of(ty));
+                (bx.const_undef(llty), ty)
             })
     }
 }
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index fdc9a37..a992364 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -10,7 +10,7 @@
 
 use libc::c_uint;
 use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts};
-use rustc::ty::layout::{LayoutOf, TyLayout, HasTyCtxt};
+use rustc::ty::layout::{TyLayout, HasTyCtxt};
 use rustc::mir::{self, Mir};
 use rustc::ty::subst::Substs;
 use rustc::session::config::DebugInfo;
@@ -266,14 +266,14 @@
 
         let mut allocate_local = |local| {
             let decl = &mir.local_decls[local];
-            let layout = bx.cx().layout_of(fx.monomorphize(&decl.ty));
+            let layout = bx.layout_of(fx.monomorphize(&decl.ty));
             assert!(!layout.ty.has_erasable_regions());
 
             if let Some(name) = decl.name {
                 // User variable
                 let debug_scope = fx.scopes[decl.visibility_scope];
                 let dbg = debug_scope.is_valid() &&
-                    bx.cx().sess().opts.debuginfo == DebugInfo::Full;
+                    bx.sess().opts.debuginfo == DebugInfo::Full;
 
                 if !memory_locals.contains(local) && !dbg {
                     debug!("alloc: {:?} ({}) -> operand", local, name);
@@ -376,7 +376,7 @@
 {
     block_bxs.iter_enumerated().zip(cleanup_kinds).map(|((bb, &llbb), cleanup_kind)| {
         match *cleanup_kind {
-            CleanupKind::Funclet if base::wants_msvc_seh(bx.cx().sess()) => {}
+            CleanupKind::Funclet if base::wants_msvc_seh(bx.sess()) => {}
             _ => return (None, None)
         }
 
@@ -415,8 +415,8 @@
                 // C++ personality function, but `catch (...)` has no type so
                 // it's null. The 64 here is actually a bitfield which
                 // represents that this is a catch-all block.
-                let null = bx.cx().const_null(bx.cx().type_i8p());
-                let sixty_four = bx.cx().const_i32(64);
+                let null = bx.const_null(bx.type_i8p());
+                let sixty_four = bx.const_i32(64);
                 funclet = cp_bx.catch_pad(cs, &[null, sixty_four, null]);
                 cp_bx.br(llbb);
             }
@@ -451,7 +451,7 @@
 
     // Get the argument scope, if it exists and if we need it.
     let arg_scope = scopes[mir::OUTERMOST_SOURCE_SCOPE];
-    let arg_scope = if bx.cx().sess().opts.debuginfo == DebugInfo::Full {
+    let arg_scope = if bx.sess().opts.debuginfo == DebugInfo::Full {
         arg_scope.scope_metadata
     } else {
         None
@@ -478,7 +478,7 @@
                 _ => bug!("spread argument isn't a tuple?!")
             };
 
-            let place = PlaceRef::alloca(bx, bx.cx().layout_of(arg_ty), &name);
+            let place = PlaceRef::alloca(bx, bx.layout_of(arg_ty), &name);
             for i in 0..tupled_arg_tys.len() {
                 let arg = &fx.fn_ty.args[idx];
                 idx += 1;
@@ -524,18 +524,18 @@
                     return local(OperandRef::new_zst(bx.cx(), arg.layout));
                 }
                 PassMode::Direct(_) => {
-                    let llarg = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint);
+                    let llarg = bx.get_param(bx.llfn(), llarg_idx as c_uint);
                     bx.set_value_name(llarg, &name);
                     llarg_idx += 1;
                     return local(
                         OperandRef::from_immediate_or_packed_pair(bx, llarg, arg.layout));
                 }
                 PassMode::Pair(..) => {
-                    let a = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint);
+                    let a = bx.get_param(bx.llfn(), llarg_idx as c_uint);
                     bx.set_value_name(a, &(name.clone() + ".0"));
                     llarg_idx += 1;
 
-                    let b = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint);
+                    let b = bx.get_param(bx.llfn(), llarg_idx as c_uint);
                     bx.set_value_name(b, &(name + ".1"));
                     llarg_idx += 1;
 
@@ -552,16 +552,16 @@
             // Don't copy an indirect argument to an alloca, the caller
             // already put it in a temporary alloca and gave it up.
             // FIXME: lifetimes
-            let llarg = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint);
+            let llarg = bx.get_param(bx.llfn(), llarg_idx as c_uint);
             bx.set_value_name(llarg, &name);
             llarg_idx += 1;
             PlaceRef::new_sized(llarg, arg.layout, arg.layout.align.abi)
         } else if arg.is_unsized_indirect() {
             // As the storage for the indirect argument lives during
             // the whole function call, we just copy the fat pointer.
-            let llarg = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint);
+            let llarg = bx.get_param(bx.llfn(), llarg_idx as c_uint);
             llarg_idx += 1;
-            let llextra = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint);
+            let llextra = bx.get_param(bx.llfn(), llarg_idx as c_uint);
             llarg_idx += 1;
             let indirect_operand = OperandValue::Pair(llarg, llextra);
 
@@ -599,7 +599,7 @@
             // Or is it the closure environment?
             let (closure_layout, env_ref) = match arg.layout.ty.sty {
                 ty::RawPtr(ty::TypeAndMut { ty, .. }) |
-                ty::Ref(_, ty, _)  => (bx.cx().layout_of(ty), true),
+                ty::Ref(_, ty, _)  => (bx.layout_of(ty), true),
                 _ => (arg.layout, false)
             };
 
@@ -618,10 +618,10 @@
             // doesn't actually strip the offset when splitting the closure
             // environment into its components so it ends up out of bounds.
             // (cuviper) It seems to be fine without the alloca on LLVM 6 and later.
-            let env_alloca = !env_ref && bx.cx().closure_env_needs_indirect_debuginfo();
+            let env_alloca = !env_ref && bx.closure_env_needs_indirect_debuginfo();
             let env_ptr = if env_alloca {
                 let scratch = PlaceRef::alloca(bx,
-                    bx.cx().layout_of(tcx.mk_mut_ptr(arg.layout.ty)),
+                    bx.layout_of(tcx.mk_mut_ptr(arg.layout.ty)),
                     "__debuginfo_env_ptr");
                 bx.store(place.llval, scratch.llval, scratch.align);
                 scratch.llval
@@ -632,7 +632,7 @@
             for (i, (decl, ty)) in mir.upvar_decls.iter().zip(upvar_tys).enumerate() {
                 let byte_offset_of_var_in_env = closure_layout.fields.offset(i).bytes();
 
-                let ops = bx.cx().debuginfo_upvar_decls_ops_sequence(byte_offset_of_var_in_env);
+                let ops = bx.debuginfo_upvar_decls_ops_sequence(byte_offset_of_var_in_env);
 
                 // The environment and the capture can each be indirect.
 
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index 92d0219..a85e759 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -331,11 +331,21 @@
                 bx.store_with_flags(val, dest.llval, dest.align, flags);
             }
             OperandValue::Pair(a, b) => {
-                for (i, &x) in [a, b].iter().enumerate() {
-                    let llptr = bx.struct_gep(dest.llval, i as u64);
-                    let val = base::from_immediate(bx, x);
-                    bx.store_with_flags(val, llptr, dest.align, flags);
-                }
+                let (a_scalar, b_scalar) = match dest.layout.abi {
+                    layout::Abi::ScalarPair(ref a, ref b) => (a, b),
+                    _ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout)
+                };
+                let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi);
+
+                let llptr = bx.struct_gep(dest.llval, 0);
+                let val = base::from_immediate(bx, a);
+                let align = dest.align;
+                bx.store_with_flags(val, llptr, align, flags);
+
+                let llptr = bx.struct_gep(dest.llval, 1);
+                let val = base::from_immediate(bx, b);
+                let align = dest.align.restrict_for_offset(b_offset);
+                bx.store_with_flags(val, llptr, align, flags);
             }
         }
     }
@@ -474,8 +484,7 @@
                         }
                         // Allow RalfJ to sleep soundly knowing that even refactorings that remove
                         // the above error (or silence it under some conditions) will not cause UB
-                        let fnname = bx.cx().get_intrinsic(&("llvm.trap"));
-                        bx.call(fnname, &[], None);
+                        bx.abort();
                         // We've errored, so we don't have to produce working code.
                         let layout = bx.cx().layout_of(ty);
                         bx.load_operand(PlaceRef::new_sized(
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index e6fd6df..1aba532 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -413,8 +413,7 @@
                         // and compile-time agree on values
                         // With floats that won't always be true
                         // so we generate an abort
-                        let fnname = bx.cx().get_intrinsic(&("llvm.trap"));
-                        bx.call(fnname, &[], None);
+                        bx.abort();
                         let llval = bx.cx().const_undef(
                             bx.cx().type_ptr_to(bx.cx().backend_type(layout))
                         );
@@ -424,7 +423,7 @@
             }
             mir::Place::Static(box mir::Static { def_id, ty }) => {
                 let layout = cx.layout_of(self.monomorphize(&ty));
-                PlaceRef::new_sized(cx.get_static(def_id), layout, layout.align.abi)
+                PlaceRef::new_sized(bx.get_static(def_id), layout, layout.align.abi)
             },
             mir::Place::Projection(box mir::Projection {
                 ref base,
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index 805c1a3..dc7b1ec 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -337,7 +337,7 @@
                                         llval,
                                         ll_t_in_const
                                     );
-                                    base::call_assume(&mut bx, cmp);
+                                    bx.assume(cmp);
                                 }
                             }
                         }
@@ -693,11 +693,7 @@
                     mir::BinOp::Mul => OverflowOp::Mul,
                     _ => unreachable!()
                 };
-                let intrinsic = get_overflow_intrinsic(oop, bx, input_ty);
-                let res = bx.call(intrinsic, &[lhs, rhs], None);
-
-                (bx.extract_value(res, 0),
-                 bx.extract_value(res, 1))
+                bx.checked_binop(oop, input_ty, lhs, rhs)
             }
             mir::BinOp::Shl | mir::BinOp::Shr => {
                 let lhs_llty = bx.cx().val_ty(lhs);
@@ -744,80 +740,6 @@
     }
 }
 
-#[derive(Copy, Clone)]
-enum OverflowOp {
-    Add, Sub, Mul
-}
-
-fn get_overflow_intrinsic<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
-    oop: OverflowOp,
-    bx: &mut Bx,
-    ty: Ty
-) -> Bx::Value {
-    use syntax::ast::IntTy::*;
-    use syntax::ast::UintTy::*;
-    use rustc::ty::{Int, Uint};
-
-    let tcx = bx.tcx();
-
-    let new_sty = match ty.sty {
-        Int(Isize) => Int(tcx.sess.target.isize_ty),
-        Uint(Usize) => Uint(tcx.sess.target.usize_ty),
-        ref t @ Uint(_) | ref t @ Int(_) => t.clone(),
-        _ => panic!("tried to get overflow intrinsic for op applied to non-int type")
-    };
-
-    let name = match oop {
-        OverflowOp::Add => match new_sty {
-            Int(I8) => "llvm.sadd.with.overflow.i8",
-            Int(I16) => "llvm.sadd.with.overflow.i16",
-            Int(I32) => "llvm.sadd.with.overflow.i32",
-            Int(I64) => "llvm.sadd.with.overflow.i64",
-            Int(I128) => "llvm.sadd.with.overflow.i128",
-
-            Uint(U8) => "llvm.uadd.with.overflow.i8",
-            Uint(U16) => "llvm.uadd.with.overflow.i16",
-            Uint(U32) => "llvm.uadd.with.overflow.i32",
-            Uint(U64) => "llvm.uadd.with.overflow.i64",
-            Uint(U128) => "llvm.uadd.with.overflow.i128",
-
-            _ => unreachable!(),
-        },
-        OverflowOp::Sub => match new_sty {
-            Int(I8) => "llvm.ssub.with.overflow.i8",
-            Int(I16) => "llvm.ssub.with.overflow.i16",
-            Int(I32) => "llvm.ssub.with.overflow.i32",
-            Int(I64) => "llvm.ssub.with.overflow.i64",
-            Int(I128) => "llvm.ssub.with.overflow.i128",
-
-            Uint(U8) => "llvm.usub.with.overflow.i8",
-            Uint(U16) => "llvm.usub.with.overflow.i16",
-            Uint(U32) => "llvm.usub.with.overflow.i32",
-            Uint(U64) => "llvm.usub.with.overflow.i64",
-            Uint(U128) => "llvm.usub.with.overflow.i128",
-
-            _ => unreachable!(),
-        },
-        OverflowOp::Mul => match new_sty {
-            Int(I8) => "llvm.smul.with.overflow.i8",
-            Int(I16) => "llvm.smul.with.overflow.i16",
-            Int(I32) => "llvm.smul.with.overflow.i32",
-            Int(I64) => "llvm.smul.with.overflow.i64",
-            Int(I128) => "llvm.smul.with.overflow.i128",
-
-            Uint(U8) => "llvm.umul.with.overflow.i8",
-            Uint(U16) => "llvm.umul.with.overflow.i16",
-            Uint(U32) => "llvm.umul.with.overflow.i32",
-            Uint(U64) => "llvm.umul.with.overflow.i64",
-            Uint(U128) => "llvm.umul.with.overflow.i128",
-
-            _ => unreachable!(),
-        },
-    };
-
-    bx.cx().get_intrinsic(&name)
-}
-
 fn cast_int_to_float<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     signed: bool,
diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs
index 0d058c8..568a7e7 100644
--- a/src/librustc_codegen_ssa/mir/statement.rs
+++ b/src/librustc_codegen_ssa/mir/statement.rs
@@ -89,7 +89,7 @@
                         if let OperandValue::Immediate(_) = op.val {
                             acc.push(op.immediate());
                         } else {
-                            span_err!(bx.cx().sess(), span.to_owned(), E0669,
+                            span_err!(bx.sess(), span.to_owned(), E0669,
                                      "invalid value for constraint in inline assembly");
                         }
                         acc
@@ -98,7 +98,7 @@
                 if input_vals.len() == inputs.len() {
                     let res = bx.codegen_inline_asm(asm, outputs, input_vals);
                     if !res {
-                        span_err!(bx.cx().sess(), statement.source_info.span, E0668,
+                        span_err!(bx.sess(), statement.source_info.span, E0668,
                                   "malformed inline assembly");
                     }
                 }
diff --git a/src/librustc_codegen_ssa/traits/abi.rs b/src/librustc_codegen_ssa/traits/abi.rs
index f35eb84..c659a99 100644
--- a/src/librustc_codegen_ssa/traits/abi.rs
+++ b/src/librustc_codegen_ssa/traits/abi.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::HasCodegen;
+use super::BackendTypes;
 use rustc::ty::{FnSig, Instance, Ty};
 use rustc_target::abi::call::FnType;
 
@@ -18,6 +18,6 @@
     fn fn_type_of_instance(&self, instance: &Instance<'tcx>) -> FnType<'tcx, Ty<'tcx>>;
 }
 
-pub trait AbiBuilderMethods<'tcx>: HasCodegen<'tcx> {
+pub trait AbiBuilderMethods<'tcx>: BackendTypes {
     fn apply_attrs_callsite(&mut self, ty: &FnType<'tcx, Ty<'tcx>>, callsite: Self::Value);
 }
diff --git a/src/librustc_codegen_ssa/traits/asm.rs b/src/librustc_codegen_ssa/traits/asm.rs
index 93e4869..0e56fe4 100644
--- a/src/librustc_codegen_ssa/traits/asm.rs
+++ b/src/librustc_codegen_ssa/traits/asm.rs
@@ -8,13 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::Backend;
-use super::HasCodegen;
+use super::BackendTypes;
 use mir::place::PlaceRef;
 use rustc::hir::{GlobalAsm, InlineAsm};
 
-pub trait AsmBuilderMethods<'tcx>: HasCodegen<'tcx> {
-    // Take an inline assembly expression and splat it out via LLVM
+pub trait AsmBuilderMethods<'tcx>: BackendTypes {
+    /// Take an inline assembly expression and splat it out via LLVM
     fn codegen_inline_asm(
         &mut self,
         ia: &InlineAsm,
@@ -23,6 +22,6 @@
     ) -> bool;
 }
 
-pub trait AsmMethods<'tcx>: Backend<'tcx> {
+pub trait AsmMethods<'tcx> {
     fn codegen_global_asm(&self, ga: &GlobalAsm);
 }
diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs
index b4d376c..b59f970 100644
--- a/src/librustc_codegen_ssa/traits/backend.rs
+++ b/src/librustc_codegen_ssa/traits/backend.rs
@@ -26,7 +26,6 @@
     type Value: CodegenObject;
     type BasicBlock: Copy;
     type Type: CodegenObject;
-    type Context;
     type Funclet;
 
     type DIScope: Copy;
@@ -39,7 +38,8 @@
 
 impl<'tcx, T> Backend<'tcx> for T where
     Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
-{}
+{
+}
 
 pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send {
     fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Module;
diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs
index 0b3066f..c134932 100644
--- a/src/librustc_codegen_ssa/traits/builder.rs
+++ b/src/librustc_codegen_ssa/traits/builder.rs
@@ -13,10 +13,11 @@
 use super::debuginfo::DebugInfoBuilderMethods;
 use super::intrinsic::IntrinsicCallMethods;
 use super::type_::ArgTypeMethods;
-use super::HasCodegen;
+use super::{HasCodegen, StaticBuilderMethods};
 use common::{AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope};
 use mir::operand::OperandRef;
 use mir::place::PlaceRef;
+use rustc::ty::Ty;
 use rustc::ty::layout::{Align, Size};
 use std::ffi::CStr;
 use MemFlags;
@@ -25,6 +26,13 @@
 use std::ops::Range;
 use syntax::ast::AsmDialect;
 
+#[derive(Copy, Clone)]
+pub enum OverflowOp {
+    Add,
+    Sub,
+    Mul,
+}
+
 pub trait BuilderMethods<'a, 'tcx: 'a>:
     HasCodegen<'tcx>
     + DebugInfoBuilderMethods<'tcx>
@@ -32,6 +40,7 @@
     + AbiBuilderMethods<'tcx>
     + IntrinsicCallMethods<'tcx>
     + AsmBuilderMethods<'tcx>
+    + StaticBuilderMethods<'tcx>
 {
     fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self;
     fn with_cx(cx: &'a Self::CodegenCx) -> Self;
@@ -97,6 +106,14 @@
     fn fneg(&mut self, v: Self::Value) -> Self::Value;
     fn not(&mut self, v: Self::Value) -> Self::Value;
 
+    fn checked_binop(
+        &mut self,
+        oop: OverflowOp,
+        ty: Ty,
+        lhs: Self::Value,
+        rhs: Self::Value,
+    ) -> (Self::Value, Self::Value);
+
     fn alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value;
     fn dynamic_alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value;
     fn array_alloca(
@@ -297,18 +314,12 @@
     ) -> Cow<'b, [Self::Value]>
     where
         [Self::Value]: ToOwned;
-    fn lifetime_start(&mut self, ptr: Self::Value, size: Size);
-    fn lifetime_end(&mut self, ptr: Self::Value, size: Size);
 
-    /// If LLVM lifetime intrinsic support is enabled (i.e. optimizations
-    /// on), and `ptr` is nonzero-sized, then extracts the size of `ptr`
-    /// and the intrinsic for `lt` and passes them to `emit`, which is in
-    /// charge of generating code to call the passed intrinsic on whatever
-    /// block of generated code is targeted for the intrinsic.
-    ///
-    /// If LLVM lifetime intrinsic support is disabled (i.e.  optimizations
-    /// off) or `ptr` is zero-sized, then no-op (does not call `emit`).
-    fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: Self::Value, size: Size);
+    /// Called for `StorageLive`
+    fn lifetime_start(&mut self, ptr: Self::Value, size: Size);
+
+    /// Called for `StorageDead`
+    fn lifetime_end(&mut self, ptr: Self::Value, size: Size);
 
     fn call(
         &mut self,
diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs
index c0a5445..af49410 100644
--- a/src/librustc_codegen_ssa/traits/consts.rs
+++ b/src/librustc_codegen_ssa/traits/consts.rs
@@ -8,16 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::Backend;
+use super::BackendTypes;
 use mir::place::PlaceRef;
 use rustc::mir::interpret::Allocation;
 use rustc::mir::interpret::Scalar;
 use rustc::ty::layout;
 use syntax::symbol::LocalInternedString;
 
-pub trait ConstMethods<'tcx>: Backend<'tcx> {
+pub trait ConstMethods<'tcx>: BackendTypes {
     // Constant constructors
-
     fn const_null(&self, t: Self::Type) -> Self::Value;
     fn const_undef(&self, t: Self::Type) -> Self::Value;
     fn const_int(&self, t: Self::Type, i: i64) -> Self::Value;
@@ -61,4 +60,6 @@
         alloc: &Allocation,
         offset: layout::Size,
     ) -> PlaceRef<'tcx, Self::Value>;
+
+    fn const_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
 }
diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs
index 643776f..c4becf3 100644
--- a/src/librustc_codegen_ssa/traits/debuginfo.rs
+++ b/src/librustc_codegen_ssa/traits/debuginfo.rs
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::Backend;
-use super::HasCodegen;
+use super::BackendTypes;
 use debuginfo::{FunctionDebugContext, MirDebugScope, VariableAccess, VariableKind};
 use rustc::hir::def_id::CrateNum;
 use rustc::mir;
@@ -19,7 +18,7 @@
 use syntax::ast::Name;
 use syntax_pos::{SourceFile, Span};
 
-pub trait DebugInfoMethods<'tcx>: Backend<'tcx> {
+pub trait DebugInfoMethods<'tcx>: BackendTypes {
     fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value);
 
     /// Creates the function-specific debug context.
@@ -51,7 +50,7 @@
     fn debuginfo_upvar_decls_ops_sequence(&self, byte_offset_of_var_in_env: u64) -> [i64; 4];
 }
 
-pub trait DebugInfoBuilderMethods<'tcx>: HasCodegen<'tcx> {
+pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes {
     fn declare_local(
         &mut self,
         dbg_context: &FunctionDebugContext<Self::DIScope>,
diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/src/librustc_codegen_ssa/traits/declare.rs
index 38ef52e..f9a2965 100644
--- a/src/librustc_codegen_ssa/traits/declare.rs
+++ b/src/librustc_codegen_ssa/traits/declare.rs
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::Backend;
+use super::BackendTypes;
 use rustc::hir::def_id::DefId;
 use rustc::mir::mono::{Linkage, Visibility};
 use rustc::ty;
 use rustc_mir::monomorphize::Instance;
 
-pub trait DeclareMethods<'tcx>: Backend<'tcx> {
+pub trait DeclareMethods<'tcx>: BackendTypes {
     /// Declare a global value.
     ///
     /// If there’s a value with the same name already declared, the function will
@@ -71,7 +71,7 @@
     fn get_defined_value(&self, name: &str) -> Option<Self::Value>;
 }
 
-pub trait PreDefineMethods<'tcx>: Backend<'tcx> {
+pub trait PreDefineMethods<'tcx>: BackendTypes {
     fn predefine_static(
         &self,
         def_id: DefId,
diff --git a/src/librustc_codegen_ssa/traits/intrinsic.rs b/src/librustc_codegen_ssa/traits/intrinsic.rs
index 53a7878..abc118e 100644
--- a/src/librustc_codegen_ssa/traits/intrinsic.rs
+++ b/src/librustc_codegen_ssa/traits/intrinsic.rs
@@ -8,14 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::Backend;
-use super::HasCodegen;
+use super::BackendTypes;
 use mir::operand::OperandRef;
 use rustc::ty::Ty;
 use rustc_target::abi::call::FnType;
 use syntax_pos::Span;
 
-pub trait IntrinsicCallMethods<'tcx>: HasCodegen<'tcx> {
+pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
     /// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
     /// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
     /// add them to librustc_codegen_llvm/context.rs
@@ -27,11 +26,8 @@
         llresult: Self::Value,
         span: Span,
     );
-}
 
-pub trait IntrinsicDeclarationMethods<'tcx>: Backend<'tcx> {
-    fn get_intrinsic(&self, key: &str) -> Self::Value;
-
-    /// Declare any llvm intrinsics that you might need
-    fn declare_intrinsic(&self, key: &str) -> Option<Self::Value>;
+    fn abort(&mut self);
+    fn assume(&mut self, val: Self::Value);
+    fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value;
 }
diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs
index 0425b8e..d8871dd 100644
--- a/src/librustc_codegen_ssa/traits/misc.rs
+++ b/src/librustc_codegen_ssa/traits/misc.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::Backend;
+use super::BackendTypes;
 use libc::c_uint;
 use rustc::mir::mono::Stats;
 use rustc::session::Session;
@@ -18,7 +18,7 @@
 use std::cell::RefCell;
 use std::sync::Arc;
 
-pub trait MiscMethods<'tcx>: Backend<'tcx> {
+pub trait MiscMethods<'tcx>: BackendTypes {
     fn vtables(
         &self,
     ) -> &RefCell<FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>), Self::Value>>;
@@ -32,7 +32,6 @@
     fn stats(&self) -> &RefCell<Stats>;
     fn consume_stats(self) -> RefCell<Stats>;
     fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>>;
-    fn statics_to_rauw(&self) -> &RefCell<Vec<(Self::Value, Self::Value)>>;
     fn closure_env_needs_indirect_debuginfo(&self) -> bool;
     fn used_statics(&self) -> &RefCell<Vec<Self::Value>>;
     fn set_frame_pointer_elimination(&self, llfn: Self::Value);
diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs
index 5cff31e..6251fc3 100644
--- a/src/librustc_codegen_ssa/traits/mod.rs
+++ b/src/librustc_codegen_ssa/traits/mod.rs
@@ -40,13 +40,13 @@
 pub use self::abi::{AbiBuilderMethods, AbiMethods};
 pub use self::asm::{AsmBuilderMethods, AsmMethods};
 pub use self::backend::{Backend, BackendTypes, ExtraBackendMethods};
-pub use self::builder::BuilderMethods;
+pub use self::builder::{BuilderMethods, OverflowOp};
 pub use self::consts::ConstMethods;
 pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods};
 pub use self::declare::{DeclareMethods, PreDefineMethods};
-pub use self::intrinsic::{IntrinsicCallMethods, IntrinsicDeclarationMethods};
+pub use self::intrinsic::IntrinsicCallMethods;
 pub use self::misc::MiscMethods;
-pub use self::statics::StaticMethods;
+pub use self::statics::{StaticMethods, StaticBuilderMethods};
 pub use self::type_::{
     ArgTypeMethods, BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods, TypeMethods,
 };
@@ -62,10 +62,9 @@
     + TypeMethods<'tcx>
     + MiscMethods<'tcx>
     + ConstMethods<'tcx>
-    + StaticMethods<'tcx>
+    + StaticMethods
     + DebugInfoMethods<'tcx>
     + AbiMethods<'tcx>
-    + IntrinsicDeclarationMethods<'tcx>
     + DeclareMethods<'tcx>
     + AsmMethods<'tcx>
     + PreDefineMethods<'tcx>
@@ -77,22 +76,23 @@
         + TypeMethods<'tcx>
         + MiscMethods<'tcx>
         + ConstMethods<'tcx>
-        + StaticMethods<'tcx>
+        + StaticMethods
         + DebugInfoMethods<'tcx>
         + AbiMethods<'tcx>
-        + IntrinsicDeclarationMethods<'tcx>
         + DeclareMethods<'tcx>
         + AsmMethods<'tcx>
         + PreDefineMethods<'tcx>
-{}
+{
+}
 
-pub trait HasCodegen<'tcx>: Backend<'tcx> {
+pub trait HasCodegen<'tcx>:
+    Backend<'tcx> + ::std::ops::Deref<Target = <Self as HasCodegen<'tcx>>::CodegenCx>
+{
     type CodegenCx: CodegenMethods<'tcx>
         + BackendTypes<
             Value = Self::Value,
             BasicBlock = Self::BasicBlock,
             Type = Self::Type,
-            Context = Self::Context,
             Funclet = Self::Funclet,
             DIScope = Self::DIScope,
         >;
diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs
index 172c48f..0e665fc 100644
--- a/src/librustc_codegen_ssa/traits/statics.rs
+++ b/src/librustc_codegen_ssa/traits/statics.rs
@@ -8,16 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::Backend;
+use super::BackendTypes;
 use rustc::hir::def_id::DefId;
 use rustc::ty::layout::Align;
 
-pub trait StaticMethods<'tcx>: Backend<'tcx> {
-    fn static_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
-    fn static_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
-    fn static_addr_of_mut(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
+pub trait StaticMethods: BackendTypes {
     fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
-    fn get_static(&self, def_id: DefId) -> Self::Value;
     fn codegen_static(&self, def_id: DefId, is_mutable: bool);
-    unsafe fn static_replace_all_uses(&self, old_g: Self::Value, new_g: Self::Value);
+}
+
+pub trait StaticBuilderMethods<'tcx>: BackendTypes {
+    fn get_static(&self, def_id: DefId) -> Self::Value;
 }
diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs
index 15976ac..1d31bdf 100644
--- a/src/librustc_codegen_ssa/traits/type_.rs
+++ b/src/librustc_codegen_ssa/traits/type_.rs
@@ -20,6 +20,8 @@
 use std::cell::RefCell;
 use syntax::ast;
 
+// This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use
+// `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves.
 pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
     fn type_void(&self) -> Self::Type;
     fn type_metadata(&self) -> Self::Type;
@@ -41,11 +43,9 @@
     fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type;
     fn type_variadic_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type;
     fn type_struct(&self, els: &[Self::Type], packed: bool) -> Self::Type;
-    fn type_named_struct(&self, name: &str) -> Self::Type;
     fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type;
     fn type_vector(&self, ty: Self::Type, len: u64) -> Self::Type;
     fn type_kind(&self, ty: Self::Type) -> TypeKind;
-    fn set_struct_body(&self, ty: Self::Type, els: &[Self::Type], packed: bool);
     fn type_ptr_to(&self, ty: Self::Type) -> Self::Type;
     fn element_type(&self, ty: Self::Type) -> Self::Type;
 
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index c3edbb6..ea8259d 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -60,5 +60,3 @@
         }
     }
 }
-
-__build_diagnostic_array! { librustc_codegen_utils, DIAGNOSTICS }
diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs
index f859336..611d7b1 100644
--- a/src/librustc_codegen_utils/symbol_names.rs
+++ b/src/librustc_codegen_utils/symbol_names.rs
@@ -257,9 +257,9 @@
             let disambiguator = tcx.sess.local_crate_disambiguator();
             return tcx.sess.generate_plugin_registrar_symbol(disambiguator);
         }
-        if *tcx.sess.derive_registrar_fn.get() == Some(id) {
+        if *tcx.sess.proc_macro_decls_static.get() == Some(id) {
             let disambiguator = tcx.sess.local_crate_disambiguator();
-            return tcx.sess.generate_derive_registrar_symbol(disambiguator);
+            return tcx.sess.generate_proc_macro_decls_symbol(disambiguator);
         }
     }
 
@@ -389,7 +389,7 @@
 
 impl ItemPathBuffer for SymbolPathBuffer {
     fn root_mode(&self) -> &RootMode {
-        const ABSOLUTE: &'static RootMode = &RootMode::Absolute;
+        const ABSOLUTE: &RootMode = &RootMode::Absolute;
         ABSOLUTE
     }
 
diff --git a/src/librustc_cratesio_shim/src/lib.rs b/src/librustc_cratesio_shim/src/lib.rs
index 1fe70fa..56e4802 100644
--- a/src/librustc_cratesio_shim/src/lib.rs
+++ b/src/librustc_cratesio_shim/src/lib.rs
@@ -15,4 +15,5 @@
 
 extern crate bitflags;
 extern crate log;
+extern crate proc_macro;
 extern crate unicode_width;
diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs
index a59bf9d..6522dbe 100644
--- a/src/librustc_data_structures/indexed_vec.rs
+++ b/src/librustc_data_structures/indexed_vec.rs
@@ -98,12 +98,18 @@
      @max          [$max:expr]
      @vis          [$v:vis]
      @debug_format [$debug_format:tt]) => (
-        #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)]
+        #[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)]
         #[rustc_layout_scalar_valid_range_end($max)]
         $v struct $type {
             private: u32
         }
 
+        impl Clone for $type {
+            fn clone(&self) -> Self {
+                *self
+            }
+        }
+
         impl $type {
             $v const MAX_AS_U32: u32 = $max;
 
@@ -145,7 +151,7 @@
 
             #[inline]
             $v const unsafe fn from_u32_unchecked(value: u32) -> Self {
-                $type { private: value }
+                unsafe { $type { private: value } }
             }
 
             /// Extract value of this index as an integer.
@@ -328,12 +334,13 @@
                    derive [$($derives:ident,)+]
                    $($tokens:tt)*) => (
         newtype_index!(
-            @derives      [$($derives,)+ RustcDecodable, RustcEncodable,]
+            @derives      [$($derives,)+ RustcEncodable,]
             @type         [$type]
             @max          [$max]
             @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
+        newtype_index!(@decodable $type);
     );
 
     // The case where no derives are added, but encodable is overridden. Don't
@@ -360,12 +367,29 @@
      @debug_format [$debug_format:tt]
                    $($tokens:tt)*) => (
         newtype_index!(
-            @derives      [RustcDecodable, RustcEncodable,]
+            @derives      [RustcEncodable,]
             @type         [$type]
             @max          [$max]
             @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
+        newtype_index!(@decodable $type);
+    );
+
+    (@decodable $type:ident) => (
+        impl $type {
+            fn __decodable__impl__hack() {
+                mod __more_hacks_because__self_doesnt_work_in_functions {
+                    extern crate serialize;
+                    use self::serialize::{Decodable, Decoder};
+                    impl Decodable for super::$type {
+                        fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
+                            d.read_u32().map(Self::from)
+                        }
+                    }
+                }
+            }
+        }
     );
 
     // Rewrite final without comma to one that includes comma
diff --git a/src/librustc_data_structures/interner.rs b/src/librustc_data_structures/interner.rs
new file mode 100644
index 0000000..29e5aef
--- /dev/null
+++ b/src/librustc_data_structures/interner.rs
@@ -0,0 +1,68 @@
+// 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::hash::Hash;
+use std::hash::BuildHasher;
+use std::hash::Hasher;
+use std::collections::HashMap;
+use std::collections::hash_map::RawEntryMut;
+use std::borrow::Borrow;
+
+pub trait HashInterner<K: Eq + Hash> {
+    fn intern_ref<Q: ?Sized, F: FnOnce() -> K>(&mut self, value: &Q, make: F) -> K
+        where K: Borrow<Q>,
+              Q: Hash + Eq;
+
+    fn intern<Q, F: FnOnce(Q) -> K>(&mut self, value: Q, make: F) -> K
+        where K: Borrow<Q>,
+              Q: Hash + Eq;
+}
+
+impl<K: Eq + Hash + Copy, S: BuildHasher> HashInterner<K> for HashMap<K, (), S> {
+    #[inline]
+    fn intern_ref<Q: ?Sized, F: FnOnce() -> K>(&mut self, value: &Q, make: F) -> K
+        where K: Borrow<Q>,
+              Q: Hash + Eq
+    {
+        let mut hasher = self.hasher().build_hasher();
+        value.hash(&mut hasher);
+        let hash = hasher.finish();
+        let entry = self.raw_entry_mut().from_key_hashed_nocheck(hash, value);
+
+        match entry {
+            RawEntryMut::Occupied(e) => *e.key(),
+            RawEntryMut::Vacant(e) => {
+                let v = make();
+                e.insert_hashed_nocheck(hash, v, ());
+                v
+            }
+        }
+    }
+
+    #[inline]
+    fn intern<Q, F: FnOnce(Q) -> K>(&mut self, value: Q, make: F) -> K
+        where K: Borrow<Q>,
+              Q: Hash + Eq
+    {
+        let mut hasher = self.hasher().build_hasher();
+        value.hash(&mut hasher);
+        let hash = hasher.finish();
+        let entry = self.raw_entry_mut().from_key_hashed_nocheck(hash, &value);
+
+        match entry {
+            RawEntryMut::Occupied(e) => *e.key(),
+            RawEntryMut::Vacant(e) => {
+                let v = make(value);
+                e.insert_hashed_nocheck(hash, v, ());
+                v
+            }
+        }
+    }
+}
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 135abeb..8e0ecb7 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -29,6 +29,7 @@
 #![feature(nll)]
 #![feature(allow_internal_unstable)]
 #![feature(vec_resize_with)]
+#![feature(hash_raw_entry)]
 
 #![cfg_attr(unix, feature(libc))]
 #![cfg_attr(test, feature(test))]
@@ -66,6 +67,7 @@
 pub mod fx;
 pub mod graph;
 pub mod indexed_vec;
+pub mod interner;
 pub mod obligation_forest;
 pub mod owning_ref;
 pub mod ptr_key;
@@ -79,7 +81,6 @@
 pub mod tiny_list;
 pub mod thin_vec;
 pub mod transitive_relation;
-pub mod tuple_slice;
 pub use ena::unify;
 pub mod vec_linked_list;
 pub mod work_queue;
diff --git a/src/librustc_data_structures/tuple_slice.rs b/src/librustc_data_structures/tuple_slice.rs
deleted file mode 100644
index b7c71dd..0000000
--- a/src/librustc_data_structures/tuple_slice.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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.
-
-use std::slice;
-
-/// Allows to view uniform tuples as slices
-pub trait TupleSlice<T> {
-    fn as_slice(&self) -> &[T];
-    fn as_mut_slice(&mut self) -> &mut [T];
-}
-
-macro_rules! impl_tuple_slice {
-    ($tuple_type:ty, $size:expr) => {
-        impl<T> TupleSlice<T> for $tuple_type {
-            fn as_slice(&self) -> &[T] {
-                unsafe {
-                    let ptr = &self.0 as *const T;
-                    slice::from_raw_parts(ptr, $size)
-                }
-            }
-
-            fn as_mut_slice(&mut self) -> &mut [T] {
-                unsafe {
-                    let ptr = &mut self.0 as *mut T;
-                    slice::from_raw_parts_mut(ptr, $size)
-                }
-            }
-        }
-    }
-}
-
-impl_tuple_slice!((T, T), 2);
-impl_tuple_slice!((T, T, T), 3);
-impl_tuple_slice!((T, T, T, T), 4);
-impl_tuple_slice!((T, T, T, T, T), 5);
-impl_tuple_slice!((T, T, T, T, T, T), 6);
-impl_tuple_slice!((T, T, T, T, T, T, T), 7);
-impl_tuple_slice!((T, T, T, T, T, T, T, T), 8);
-
-#[test]
-fn test_sliced_tuples() {
-    let t2 = (100, 101);
-    assert_eq!(t2.as_slice(), &[100, 101]);
-
-    let t3 = (102, 103, 104);
-    assert_eq!(t3.as_slice(), &[102, 103, 104]);
-
-    let t4 = (105, 106, 107, 108);
-    assert_eq!(t4.as_slice(), &[105, 106, 107, 108]);
-
-    let t5 = (109, 110, 111, 112, 113);
-    assert_eq!(t5.as_slice(), &[109, 110, 111, 112, 113]);
-
-    let t6 = (114, 115, 116, 117, 118, 119);
-    assert_eq!(t6.as_slice(), &[114, 115, 116, 117, 118, 119]);
-
-    let t7 = (120, 121, 122, 123, 124, 125, 126);
-    assert_eq!(t7.as_slice(), &[120, 121, 122, 123, 124, 125, 126]);
-
-    let t8 = (127, 128, 129, 130, 131, 132, 133, 134);
-    assert_eq!(t8.as_slice(), &[127, 128, 129, 130, 131, 132, 133, 134]);
-
-}
diff --git a/src/librustc_driver/README.md b/src/librustc_driver/README.md
index fef249a..c4d7395 100644
--- a/src/librustc_driver/README.md
+++ b/src/librustc_driver/README.md
@@ -7,4 +7,4 @@
 
 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
+[rustc guide]: https://rust-lang.github.io/rustc-guide/rustc-driver.html
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 7ad0124..48014a9 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -62,7 +62,7 @@
 use syntax_pos::{FileName, hygiene};
 use syntax_ext;
 
-use derive_registrar;
+use proc_macro_decls;
 use pretty::ReplaceBodyWithLoop;
 
 use profile;
@@ -91,7 +91,7 @@
     let config = ThreadPoolBuilder::new()
         .num_threads(Session::query_threads_from_opts(&opts))
         .deadlock_handler(|| unsafe { ty::query::handle_deadlock() })
-        .stack_size(16 * 1024 * 1024);
+        .stack_size(::STACK_SIZE);
 
     let with_pool = move |pool: &ThreadPool| {
         pool.install(move || f(opts))
@@ -356,10 +356,10 @@
 
     if sess.opts.debugging_opts.self_profile {
         sess.print_profiler_results();
+    }
 
-        if sess.opts.debugging_opts.profile_json {
-            sess.save_json_results();
-        }
+    if sess.opts.debugging_opts.profile_json {
+        sess.save_json_results();
     }
 
     controller_entry_point!(
@@ -1066,7 +1066,7 @@
             let num_crate_types = crate_types.len();
             let is_proc_macro_crate = crate_types.contains(&config::CrateType::ProcMacro);
             let is_test_crate = sess.opts.test;
-            syntax_ext::proc_macro_registrar::modify(
+            syntax_ext::proc_macro_decls::modify(
                 &sess.parse_sess,
                 &mut resolver,
                 krate,
@@ -1243,8 +1243,8 @@
         .set(time(sess, "looking for plugin registrar", || {
             plugin::build::find_plugin_registrar(sess.diagnostic(), &hir_map)
         }));
-    sess.derive_registrar_fn
-        .set(derive_registrar::find(&hir_map));
+    sess.proc_macro_decls_static
+        .set(proc_macro_decls::find(&hir_map));
 
     time(sess, "loop checking", || loops::check_crate(sess, &hir_map));
 
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index ec3cb95..45d107f 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -127,7 +127,7 @@
 pub mod profile;
 pub mod driver;
 pub mod pretty;
-mod derive_registrar;
+mod proc_macro_decls;
 
 pub mod target_features {
     use syntax::ast;
@@ -594,7 +594,7 @@
             } else {
                 None
             };
-            Some((Input::Str { name: FileName::Anon, input: src },
+            Some((Input::Str { name: FileName::anon_source_code(&src), input: src },
                   None, err))
         } else {
             Some((Input::File(PathBuf::from(ifile)),
@@ -1468,6 +1468,11 @@
     }
 }
 
+// Temporarily have stack size set to 32MB to deal with various crates with long method
+// chains or deep syntax trees.
+// FIXME(oli-obk): get https://github.com/rust-lang/rust/pull/55617 the finish line
+const STACK_SIZE: usize = 32 * 1024 * 1024; // 32MB
+
 /// Runs `f` in a suitable thread for running `rustc`; returns a `Result` with either the return
 /// value of `f` or -- if a panic occurs -- the panic value.
 ///
@@ -1477,9 +1482,6 @@
     where F: FnOnce() -> R + Send + 'static,
           R: Send + 'static,
 {
-    // Temporarily have stack size set to 16MB to deal with nom-using crates failing
-    const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB
-
     #[cfg(all(unix, not(target_os = "haiku")))]
     let spawn_thread = unsafe {
         // Fetch the current resource limits
@@ -1697,7 +1699,6 @@
     all_errors.extend_from_slice(&rustc_privacy::DIAGNOSTICS);
     // FIXME: need to figure out a way to get these back in here
     // all_errors.extend_from_slice(get_codegen_backend(sess).diagnostics());
-    all_errors.extend_from_slice(&rustc_codegen_utils::DIAGNOSTICS);
     all_errors.extend_from_slice(&rustc_metadata::DIAGNOSTICS);
     all_errors.extend_from_slice(&rustc_passes::DIAGNOSTICS);
     all_errors.extend_from_slice(&rustc_plugin::DIAGNOSTICS);
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index c7ba31e..fb8093d 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -530,7 +530,7 @@
                 s.s.space()?;
                 s.s.word("as")?;
                 s.s.space()?;
-                s.s.word(&self.tables.get().expr_ty(expr).to_string())?;
+                s.s.word(self.tables.get().expr_ty(expr).to_string())?;
                 s.pclose()
             }
             _ => Ok(()),
diff --git a/src/librustc_driver/derive_registrar.rs b/src/librustc_driver/proc_macro_decls.rs
similarity index 81%
rename from src/librustc_driver/derive_registrar.rs
rename to src/librustc_driver/proc_macro_decls.rs
index 9983efc..136a27b 100644
--- a/src/librustc_driver/derive_registrar.rs
+++ b/src/librustc_driver/proc_macro_decls.rs
@@ -17,19 +17,19 @@
 pub fn find(hir_map: &Map) -> Option<ast::NodeId> {
     let krate = hir_map.krate();
 
-    let mut finder = Finder { registrar: None };
+    let mut finder = Finder { decls: None };
     krate.visit_all_item_likes(&mut finder);
-    finder.registrar
+    finder.decls
 }
 
 struct Finder {
-    registrar: Option<ast::NodeId>,
+    decls: Option<ast::NodeId>,
 }
 
 impl<'v> ItemLikeVisitor<'v> for Finder {
     fn visit_item(&mut self, item: &hir::Item) {
-        if attr::contains_name(&item.attrs, "rustc_derive_registrar") {
-            self.registrar = Some(item.id);
+        if attr::contains_name(&item.attrs, "rustc_proc_macro_decls") {
+            self.decls = Some(item.id);
         }
     }
 
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 8865c7e..b8cd9bd 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -129,7 +129,7 @@
     let cstore = CStore::new(::get_codegen_backend(&sess).metadata_loader());
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     let input = config::Input::Str {
-        name: FileName::Anon,
+        name: FileName::anon_source_code(&source_string),
         input: source_string.to_string(),
     };
     let krate =
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 7e69e98..ab2ab25 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -1044,7 +1044,7 @@
                     buffer.append(buffer_msg_line_offset,
                                   &format!("{}:{}:{}",
                                            loc.file.name,
-                                           sm.doctest_offset_line(loc.line),
+                                           sm.doctest_offset_line(&loc.file.name, loc.line),
                                            loc.col.0 + 1),
                                   Style::LineAndColumn);
                     for _ in 0..max_line_num_len {
@@ -1054,7 +1054,7 @@
                     buffer.prepend(0,
                                    &format!("{}:{}:{}: ",
                                             loc.file.name,
-                                            sm.doctest_offset_line(loc.line),
+                                            sm.doctest_offset_line(&loc.file.name, loc.line),
                                             loc.col.0 + 1),
                                    Style::LineAndColumn);
                 }
@@ -1075,7 +1075,8 @@
                     };
                     format!("{}:{}{}",
                             annotated_file.file.name,
-                            sm.doctest_offset_line(first_line.line_index),
+                            sm.doctest_offset_line(
+                                &annotated_file.file.name, first_line.line_index),
                             col)
                 } else {
                     annotated_file.file.name.to_string()
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 0fb77a7..b6528cb 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -130,7 +130,7 @@
     fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span>;
     fn call_span_if_macro(&self, sp: Span) -> Span;
     fn ensure_source_file_source_present(&self, source_file: Lrc<SourceFile>) -> bool;
-    fn doctest_offset_line(&self, line: usize) -> usize;
+    fn doctest_offset_line(&self, file: &FileName, line: usize) -> usize;
 }
 
 impl CodeSuggestion {
diff --git a/src/librustc_fs_util/lib.rs b/src/librustc_fs_util/lib.rs
index ffe420b..1b0ff4f 100644
--- a/src/librustc_fs_util/lib.rs
+++ b/src/librustc_fs_util/lib.rs
@@ -116,13 +116,13 @@
 }
 
 #[cfg(unix)]
-pub fn path2cstr(p: &Path) -> CString {
-    use std::os::unix::prelude::*;
+pub fn path_to_c_string(p: &Path) -> CString {
+    use std::os::unix::ffi::OsStrExt;
     use std::ffi::OsStr;
     let p: &OsStr = p.as_ref();
     CString::new(p.as_bytes()).unwrap()
 }
 #[cfg(windows)]
-pub fn path2cstr(p: &Path) -> CString {
+pub fn path_to_c_string(p: &Path) -> CString {
     CString::new(p.to_str().unwrap()).unwrap()
 }
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index 4ff2529..17ac9a6 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -40,9 +40,9 @@
 use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
                  ATTR_EXPECTED_CGU_REUSE};
 
-const MODULE: &'static str = "module";
-const CFG: &'static str = "cfg";
-const KIND: &'static str = "kind";
+const MODULE: &str = "module";
+const CFG: &str = "cfg";
+const KIND: &str = "kind";
 
 pub fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.dep_graph.with_ignore(|| {
diff --git a/src/librustc_incremental/persist/file_format.rs b/src/librustc_incremental/persist/file_format.rs
index 98f7873..e5faba6 100644
--- a/src/librustc_incremental/persist/file_format.rs
+++ b/src/librustc_incremental/persist/file_format.rs
@@ -28,7 +28,7 @@
 use rustc_serialize::opaque::Encoder;
 
 /// The first few bytes of files generated by incremental compilation
-const FILE_MAGIC: &'static [u8] = b"RSIC";
+const FILE_MAGIC: &[u8] = b"RSIC";
 
 /// Change this if the header format changes
 const HEADER_FORMAT_VERSION: u16 = 0;
@@ -36,7 +36,7 @@
 /// A version string that hopefully is always different for compiler versions
 /// with different encodings of incremental compilation artifacts. Contains
 /// the git commit hash.
-const RUSTC_VERSION: Option<&'static str> = option_env!("CFG_VERSION");
+const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION");
 
 pub fn write_file_header(stream: &mut Encoder) {
     stream.emit_raw_bytes(FILE_MAGIC);
diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs
index 2a8a0ba..bc98798 100644
--- a/src/librustc_incremental/persist/fs.rs
+++ b/src/librustc_incremental/persist/fs.rs
@@ -128,10 +128,10 @@
 
 use rand::{RngCore, thread_rng};
 
-const LOCK_FILE_EXT: &'static str = ".lock";
-const DEP_GRAPH_FILENAME: &'static str = "dep-graph.bin";
-const WORK_PRODUCTS_FILENAME: &'static str = "work-products.bin";
-const QUERY_CACHE_FILENAME: &'static str = "query-cache.bin";
+const LOCK_FILE_EXT: &str = ".lock";
+const DEP_GRAPH_FILENAME: &str = "dep-graph.bin";
+const WORK_PRODUCTS_FILENAME: &str = "work-products.bin";
+const QUERY_CACHE_FILENAME: &str = "query-cache.bin";
 
 // We encode integers using the following base, so they are shorter than decimal
 // or hexadecimal numbers (we want short file and directory names). Since these
@@ -659,7 +659,7 @@
     let mut session_directories = FxHashSet::default();
     let mut lock_files = FxHashSet::default();
 
-    for dir_entry in try!(crate_directory.read_dir()) {
+    for dir_entry in crate_directory.read_dir()? {
         let dir_entry = match dir_entry {
             Ok(dir_entry) => dir_entry,
             _ => {
@@ -887,7 +887,7 @@
 /// into the '\\?\' format, which supports much longer paths.
 fn safe_remove_dir_all(p: &Path) -> io::Result<()> {
     if p.exists() {
-        let canonicalized = try!(p.canonicalize());
+        let canonicalized = p.canonicalize()?;
         std_fs::remove_dir_all(canonicalized)
     } else {
         Ok(())
@@ -896,7 +896,7 @@
 
 fn safe_remove_file(p: &Path) -> io::Result<()> {
     if p.exists() {
-        let canonicalized = try!(p.canonicalize());
+        let canonicalized = p.canonicalize()?;
         std_fs::remove_file(canonicalized)
     } else {
         Ok(())
diff --git a/src/librustc_incremental/persist/work_product.rs b/src/librustc_incremental/persist/work_product.rs
index cfe59b1..ddd28eb 100644
--- a/src/librustc_incremental/persist/work_product.rs
+++ b/src/librustc_incremental/persist/work_product.rs
@@ -29,7 +29,7 @@
         return None
     }
 
-    let saved_files: Option<Vec<_>> =
+    let saved_files =
         files.iter()
              .map(|&(kind, ref path)| {
                  let extension = match kind {
@@ -51,11 +51,7 @@
                      }
                  }
              })
-             .collect();
-    let saved_files = match saved_files {
-        None => return None,
-        Some(v) => v,
-    };
+             .collect::<Option<Vec<_>>>()?;
 
     let work_product = WorkProduct {
         cgu_name: cgu_name.to_string(),
diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml
index fe197e3..7fb7a06 100644
--- a/src/librustc_lint/Cargo.toml
+++ b/src/librustc_lint/Cargo.toml
@@ -12,7 +12,6 @@
 [dependencies]
 log = "0.4"
 rustc = { path = "../librustc" }
-rustc_mir = { path = "../librustc_mir"}
 rustc_target = { path = "../librustc_target" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 57cbecb..4d709d5 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -29,7 +29,6 @@
 #![feature(nll)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
-#![feature(macro_at_most_once_rep)]
 
 #[macro_use]
 extern crate syntax;
@@ -37,7 +36,6 @@
 extern crate rustc;
 #[macro_use]
 extern crate log;
-extern crate rustc_mir;
 extern crate rustc_target;
 extern crate syntax_pos;
 extern crate rustc_data_structures;
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index fab618d..c7eb06c 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -473,7 +473,7 @@
             match items[0].0.kind {
                 ast::UseTreeKind::Simple(rename, ..) => {
                     let orig_ident = items[0].0.prefix.segments.last().unwrap().ident;
-                    if orig_ident.name == keywords::SelfValue.name() {
+                    if orig_ident.name == keywords::SelfLower.name() {
                         return;
                     }
                     node_ident = rename.unwrap_or(orig_ident);
diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml
index 276e2a9..337c87c 100644
--- a/src/librustc_metadata/Cargo.toml
+++ b/src/librustc_metadata/Cargo.toml
@@ -12,7 +12,6 @@
 flate2 = "1.0"
 log = "0.4"
 memmap = "0.6"
-proc_macro = { path = "../libproc_macro" }
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index a14dd99..4ff29f5c 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -36,7 +36,6 @@
 
 use syntax::ast;
 use syntax::attr;
-use syntax::edition::Edition;
 use syntax::ext::base::SyntaxExtension;
 use syntax::symbol::Symbol;
 use syntax::visit;
@@ -231,7 +230,7 @@
 
         let dependencies: Vec<CrateNum> = cnum_map.iter().cloned().collect();
 
-        let proc_macros = crate_root.macro_derive_registrar.map(|_| {
+        let proc_macros = crate_root.proc_macro_decls_static.map(|_| {
             self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span)
         });
 
@@ -339,7 +338,7 @@
         match result {
             LoadResult::Previous(cnum) => {
                 let data = self.cstore.get_crate_data(cnum);
-                if data.root.macro_derive_registrar.is_some() {
+                if data.root.proc_macro_decls_static.is_some() {
                     dep_kind = DepKind::UnexportedMacrosOnly;
                 }
                 data.dep_kind.with_lock(|data_dep_kind| {
@@ -431,7 +430,7 @@
                           dep_kind: DepKind)
                           -> cstore::CrateNumMap {
         debug!("resolving deps of external crate");
-        if crate_root.macro_derive_registrar.is_some() {
+        if crate_root.proc_macro_decls_static.is_some() {
             return cstore::CrateNumMap::new();
         }
 
@@ -533,9 +532,8 @@
     fn load_derive_macros(&mut self, root: &CrateRoot, dylib: Option<PathBuf>, span: Span)
                           -> Vec<(ast::Name, Lrc<SyntaxExtension>)> {
         use std::{env, mem};
-        use proc_macro::TokenStream;
-        use proc_macro::__internal::Registry;
         use dynamic_lib::DynamicLibrary;
+        use proc_macro::bridge::client::ProcMacro;
         use syntax_ext::deriving::custom::ProcMacroDerive;
         use syntax_ext::proc_macro_impl::{AttrProcMacro, BangProcMacro};
 
@@ -550,61 +548,49 @@
             Err(err) => self.sess.span_fatal(span, &err),
         };
 
-        let sym = self.sess.generate_derive_registrar_symbol(root.disambiguator);
-        let registrar = unsafe {
+        let sym = self.sess.generate_proc_macro_decls_symbol(root.disambiguator);
+        let decls = unsafe {
             let sym = match lib.symbol(&sym) {
                 Ok(f) => f,
                 Err(err) => self.sess.span_fatal(span, &err),
             };
-            mem::transmute::<*mut u8, fn(&mut dyn Registry)>(sym)
+            *(sym as *const &[ProcMacro])
         };
 
-        struct MyRegistrar {
-            extensions: Vec<(ast::Name, Lrc<SyntaxExtension>)>,
-            edition: Edition,
-        }
-
-        impl Registry for MyRegistrar {
-            fn register_custom_derive(&mut self,
-                                      trait_name: &str,
-                                      expand: fn(TokenStream) -> TokenStream,
-                                      attributes: &[&'static str]) {
-                let attrs = attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
-                let derive = ProcMacroDerive::new(expand, attrs.clone());
-                let derive = SyntaxExtension::ProcMacroDerive(
-                    Box::new(derive), attrs, self.edition
-                );
-                self.extensions.push((Symbol::intern(trait_name), Lrc::new(derive)));
+        let extensions = decls.iter().map(|&decl| {
+            match decl {
+                ProcMacro::CustomDerive { trait_name, attributes, client } => {
+                    let attrs = attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
+                    (trait_name, SyntaxExtension::ProcMacroDerive(
+                        Box::new(ProcMacroDerive {
+                            client,
+                            attrs: attrs.clone(),
+                        }),
+                        attrs,
+                        root.edition,
+                    ))
+                }
+                ProcMacro::Attr { name, client } => {
+                    (name, SyntaxExtension::AttrProcMacro(
+                        Box::new(AttrProcMacro { client }),
+                        root.edition,
+                    ))
+                }
+                ProcMacro::Bang { name, client } => {
+                    (name, SyntaxExtension::ProcMacro {
+                        expander: Box::new(BangProcMacro { client }),
+                        allow_internal_unstable: false,
+                        edition: root.edition,
+                    })
+                }
             }
-
-            fn register_attr_proc_macro(&mut self,
-                                        name: &str,
-                                        expand: fn(TokenStream, TokenStream) -> TokenStream) {
-                let expand = SyntaxExtension::AttrProcMacro(
-                    Box::new(AttrProcMacro { inner: expand }), self.edition
-                );
-                self.extensions.push((Symbol::intern(name), Lrc::new(expand)));
-            }
-
-            fn register_bang_proc_macro(&mut self,
-                                        name: &str,
-                                        expand: fn(TokenStream) -> TokenStream) {
-                let expand = SyntaxExtension::ProcMacro {
-                    expander: Box::new(BangProcMacro { inner: expand }),
-                    allow_internal_unstable: false,
-                    edition: self.edition,
-                };
-                self.extensions.push((Symbol::intern(name), Lrc::new(expand)));
-            }
-        }
-
-        let mut my_registrar = MyRegistrar { extensions: Vec::new(), edition: root.edition };
-        registrar(&mut my_registrar);
+        }).map(|(name, ext)| (Symbol::intern(name), Lrc::new(ext))).collect();
 
         // Intentionally leak the dynamic library. We can't ever unload it
         // since the library can make things that will live arbitrarily long.
         mem::forget(lib);
-        my_registrar.extensions
+
+        extensions
     }
 
     /// Look for a plugin registrar. Returns library path, crate
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index c7bd174..d0fa63a 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -203,8 +203,8 @@
             DefId { krate: def_id.krate, index }
         })
     }
-    derive_registrar_fn => {
-        cdata.root.macro_derive_registrar.map(|index| {
+    proc_macro_decls_static => {
+        cdata.root.proc_macro_decls_static.map(|index| {
             DefId { krate: def_id.krate, index }
         })
     }
@@ -431,8 +431,9 @@
             use syntax::ext::base::SyntaxExtension;
             use syntax_ext::proc_macro_impl::BangProcMacro;
 
+            let client = ::proc_macro::bridge::client::Client::expand1(::proc_macro::quote);
             let ext = SyntaxExtension::ProcMacro {
-                expander: Box::new(BangProcMacro { inner: ::proc_macro::quote }),
+                expander: Box::new(BangProcMacro { client }),
                 allow_internal_unstable: true,
                 edition: data.root.edition,
             };
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 5421972..2736c60 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -496,8 +496,8 @@
                 .plugin_registrar_fn
                 .get()
                 .map(|id| tcx.hir.local_def_id(id).index),
-            macro_derive_registrar: if is_proc_macro {
-                let id = tcx.sess.derive_registrar_fn.get().unwrap();
+            proc_macro_decls_static: if is_proc_macro {
+                let id = tcx.sess.proc_macro_decls_static.get().unwrap();
                 Some(tcx.hir.local_def_id(id).index)
             } else {
                 None
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 0322c88..ee99f74 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -14,7 +14,6 @@
 
 #![feature(box_patterns)]
 #![feature(libc)]
-#![feature(macro_at_most_once_rep)]
 #![feature(nll)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 528c96f..d4e5169 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -713,7 +713,7 @@
 
         let root = metadata.get_root();
         if let Some(is_proc_macro) = self.is_proc_macro {
-            if root.macro_derive_registrar.is_some() != is_proc_macro {
+            if root.proc_macro_decls_static.is_some() != is_proc_macro {
                 return None;
             }
         }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index da2a8ae..fc3af6c 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -52,7 +52,7 @@
 /// This header is followed by the position of the `CrateRoot`,
 /// which is encoded as a 32-bit big-endian unsigned integer,
 /// and further followed by the rustc version string.
-pub const METADATA_HEADER: &'static [u8; 12] =
+pub const METADATA_HEADER: &[u8; 12] =
     &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
 
 /// A value of type T referred to by its absolute position
@@ -196,7 +196,7 @@
     pub has_panic_handler: bool,
     pub has_default_lib_allocator: bool,
     pub plugin_registrar_fn: Option<DefIndex>,
-    pub macro_derive_registrar: Option<DefIndex>,
+    pub proc_macro_decls_static: Option<DefIndex>,
 
     pub crate_deps: LazySeq<CrateDep>,
     pub dylib_dependency_formats: LazySeq<Option<LinkagePreference>>,
diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs
index fd7dc7f..947c32d 100644
--- a/src/librustc_mir/borrow_check/borrow_set.rs
+++ b/src/librustc_mir/borrow_check/borrow_set.rs
@@ -16,7 +16,7 @@
 use rustc::mir::visit::{
     PlaceContext, Visitor, NonUseContext, MutatingUseContext, NonMutatingUseContext
 };
-use rustc::mir::{self, Location, Mir, Place, Local};
+use rustc::mir::{self, Location, Mir, Local};
 use rustc::ty::{RegionVid, TyCtxt};
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_data_structures::indexed_vec::IndexVec;
@@ -41,10 +41,6 @@
     /// only need to store one borrow index
     crate activation_map: FxHashMap<Location, Vec<BorrowIndex>>,
 
-    /// Every borrow has a region; this maps each such regions back to
-    /// its borrow-indexes.
-    crate region_map: FxHashMap<RegionVid, FxHashSet<BorrowIndex>>,
-
     /// Map from local to all the borrows on that local
     crate local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
 
@@ -149,7 +145,6 @@
             idx_vec: IndexVec::new(),
             location_map: Default::default(),
             activation_map: Default::default(),
-            region_map: Default::default(),
             local_map: Default::default(),
             pending_activations: Default::default(),
             locals_state_at_exit:
@@ -164,7 +159,6 @@
             borrows: visitor.idx_vec,
             location_map: visitor.location_map,
             activation_map: visitor.activation_map,
-            region_map: visitor.region_map,
             local_map: visitor.local_map,
             locals_state_at_exit: visitor.locals_state_at_exit,
         }
@@ -184,7 +178,6 @@
     idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>,
     location_map: FxHashMap<Location, BorrowIndex>,
     activation_map: FxHashMap<Location, Vec<BorrowIndex>>,
-    region_map: FxHashMap<RegionVid, FxHashSet<BorrowIndex>>,
     local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
 
     /// When we encounter a 2-phase borrow statement, it will always
@@ -229,7 +222,6 @@
 
             self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx);
 
-            self.region_map.entry(region).or_default().insert(idx);
             if let Some(local) = borrowed_place.root_local() {
                 self.local_map.entry(local).or_default().insert(idx);
             }
@@ -238,68 +230,68 @@
         self.super_assign(block, assigned_place, rvalue, location)
     }
 
-    fn visit_place(
+    fn visit_local(
         &mut self,
-        place: &mir::Place<'tcx>,
+        temp: &Local,
         context: PlaceContext<'tcx>,
         location: Location,
     ) {
-        self.super_place(place, context, location);
+        if !context.is_use() {
+            return;
+        }
 
-        // We found a use of some temporary TEMP...
-        if let Place::Local(temp) = place {
-            // ... check whether we (earlier) saw a 2-phase borrow like
-            //
-            //     TMP = &mut place
-            if let Some(&borrow_index) = self.pending_activations.get(temp) {
-                let borrow_data = &mut self.idx_vec[borrow_index];
+        // We found a use of some temporary TMP
+        // check whether we (earlier) saw a 2-phase borrow like
+        //
+        //     TMP = &mut place
+        if let Some(&borrow_index) = self.pending_activations.get(temp) {
+            let borrow_data = &mut self.idx_vec[borrow_index];
 
-                // Watch out: the use of TMP in the borrow itself
-                // doesn't count as an activation. =)
-                if borrow_data.reserve_location == location &&
-                    context == PlaceContext::MutatingUse(MutatingUseContext::Store)
-                {
-                    return;
-                }
-
-                if let TwoPhaseActivation::ActivatedAt(other_location) =
-                        borrow_data.activation_location {
-                    span_bug!(
-                        self.mir.source_info(location).span,
-                        "found two uses for 2-phase borrow temporary {:?}: \
-                         {:?} and {:?}",
-                        temp,
-                        location,
-                        other_location,
-                    );
-                }
-
-                // Otherwise, this is the unique later use
-                // that we expect.
-                borrow_data.activation_location = match context {
-                    // The use of TMP in a shared borrow does not
-                    // count as an actual activation.
-                    PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow(..)) |
-                    PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow(..)) =>
-                        TwoPhaseActivation::NotActivated,
-                    _ => {
-                        // Double check: This borrow is indeed a two-phase borrow (that is,
-                        // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and
-                        // we've not found any other activations (checked above).
-                        assert_eq!(
-                            borrow_data.activation_location,
-                            TwoPhaseActivation::NotActivated,
-                            "never found an activation for this borrow!",
-                        );
-
-                        self.activation_map
-                            .entry(location)
-                            .or_default()
-                            .push(borrow_index);
-                        TwoPhaseActivation::ActivatedAt(location)
-                    }
-                };
+            // Watch out: the use of TMP in the borrow itself
+            // doesn't count as an activation. =)
+            if borrow_data.reserve_location == location &&
+                context == PlaceContext::MutatingUse(MutatingUseContext::Store)
+            {
+                return;
             }
+
+            if let TwoPhaseActivation::ActivatedAt(other_location) =
+                    borrow_data.activation_location {
+                span_bug!(
+                    self.mir.source_info(location).span,
+                    "found two uses for 2-phase borrow temporary {:?}: \
+                     {:?} and {:?}",
+                    temp,
+                    location,
+                    other_location,
+                );
+            }
+
+            // Otherwise, this is the unique later use
+            // that we expect.
+            borrow_data.activation_location = match context {
+                // The use of TMP in a shared borrow does not
+                // count as an actual activation.
+                PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow(..)) |
+                PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow(..)) =>
+                    TwoPhaseActivation::NotActivated,
+                _ => {
+                    // Double check: This borrow is indeed a two-phase borrow (that is,
+                    // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and
+                    // we've not found any other activations (checked above).
+                    assert_eq!(
+                        borrow_data.activation_location,
+                        TwoPhaseActivation::NotActivated,
+                        "never found an activation for this borrow!",
+                    );
+
+                    self.activation_map
+                        .entry(location)
+                        .or_default()
+                        .push(borrow_index);
+                    TwoPhaseActivation::ActivatedAt(location)
+                }
+            };
         }
     }
 
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 4ccd26b..ba26ed3 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -344,6 +344,13 @@
 
         let first_borrow_desc;
 
+        let explanation = self.explain_why_borrow_contains_point(context, issued_borrow, None);
+        let second_borrow_desc = if explanation.is_explained() {
+            "second "
+        } else {
+            ""
+        };
+
         // FIXME: supply non-"" `opt_via` when appropriate
         let mut err = match (
             gen_borrow_kind,
@@ -454,6 +461,7 @@
                     issued_span,
                     "",
                     None,
+                    second_borrow_desc,
                     Origin::Mir,
                 )
             }
@@ -469,6 +477,7 @@
                     issued_span,
                     "",
                     None,
+                    second_borrow_desc,
                     Origin::Mir,
                 )
             }
@@ -513,7 +522,7 @@
             );
         }
 
-        self.explain_why_borrow_contains_point(context, issued_borrow, None)
+        explanation
             .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, first_borrow_desc);
 
         err.buffer(&mut self.errors_buffer);
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 7afe2c6..4bcabfe 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -263,7 +263,7 @@
                             // Deliberately fall into this case for all implicit self types,
                             // so that we don't fall in to the next case with them.
                             *kind == mir::ImplicitSelfKind::MutRef
-                        } else if Some(keywords::SelfValue.name()) == local_decl.name {
+                        } else if Some(keywords::SelfLower.name()) == local_decl.name {
                             // Otherwise, check if the name is the self kewyord - in which case
                             // we have an explicit self. Do the same thing in this case and check
                             // for a `self: &mut Self` to suggest removing the `&mut`.
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index bb9a29b..477b789 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -52,6 +52,12 @@
 }
 
 impl BorrowExplanation {
+    pub(in borrow_check) fn is_explained(&self) -> bool {
+        match self {
+            BorrowExplanation::Unexplained => false,
+            _ => true,
+        }
+    }
     pub(in borrow_check) fn add_explanation_to_diagnostic<'cx, 'gcx, 'tcx>(
         &self,
         tcx: TyCtxt<'cx, 'gcx, 'tcx>,
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 6a1dc50..fbde699 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -1208,7 +1208,7 @@
                         blame_span: blame_span_category.1,
                         category: blame_span_category.0,
                     });
-                    return;
+                    continue;
                 }
             }
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
index cf4f913..225e284 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
@@ -10,10 +10,11 @@
 
 use borrow_check::nll::constraints::OutlivesConstraint;
 use borrow_check::nll::type_check::{BorrowCheckContext, Locations};
-use rustc::infer::nll_relate::{TypeRelating, TypeRelatingDelegate};
+use rustc::infer::nll_relate::{TypeRelating, TypeRelatingDelegate, NormalizationStrategy};
 use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
 use rustc::mir::ConstraintCategory;
 use rustc::traits::query::Fallible;
+use rustc::traits::DomainGoal;
 use rustc::ty::relate::TypeRelation;
 use rustc::ty::{self, Ty};
 
@@ -38,7 +39,7 @@
     TypeRelating::new(
         infcx,
         NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category),
-        v,
+        v
     ).relate(&a, &b)?;
     Ok(())
 }
@@ -115,4 +116,16 @@
                 });
         }
     }
+
+    fn push_domain_goal(&mut self, _: DomainGoal<'tcx>) {
+        bug!("should never be invoked with eager normalization")
+    }
+
+    fn normalization() -> NormalizationStrategy {
+        NormalizationStrategy::Eager
+    }
+
+    fn forbid_inference_vars() -> bool {
+        true
+    }
 }
diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs
index f73e08e..7d583b4 100644
--- a/src/librustc_mir/borrow_check/prefixes.rs
+++ b/src/librustc_mir/borrow_check/prefixes.rs
@@ -87,10 +87,7 @@
 impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> {
     type Item = &'cx Place<'tcx>;
     fn next(&mut self) -> Option<Self::Item> {
-        let mut cursor = match self.next {
-            None => return None,
-            Some(place) => place,
-        };
+        let mut cursor = self.next?;
 
         // Post-processing `place`: Enqueue any remaining
         // work. Also, `place` may not be a prefix itself, but
diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs
index 8f50a1e..2db9fb9 100644
--- a/src/librustc_mir/build/expr/as_temp.rs
+++ b/src/librustc_mir/build/expr/as_temp.rs
@@ -85,9 +85,15 @@
 
         unpack!(block = this.into(&Place::Local(temp), block, expr));
 
-        // In constants, temp_lifetime is None. We should not need to drop
-        // anything because no values with a destructor can be created in
-        // a constant at this time, even if the type may need dropping.
+        // In constants, temp_lifetime is None for temporaries that live for the
+        // 'static lifetime. Thus we do not drop these temporaries and simply leak them.
+        // This is equivalent to what `let x = &foo();` does in functions. The temporary
+        // is lifted to their surrounding scope. In a function that means the temporary lives
+        // until just before the function returns. In constants that means it outlives the
+        // constant's initialization value computation. Anything outliving a constant
+        // must have the `'static` lifetime and live forever.
+        // Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything
+        // within a block will keep the regular drops just like runtime code.
         if let Some(temp_lifetime) = temp_lifetime {
             this.schedule_drop_storage_and_value(
                 expr_span,
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index d95a74b..90a204c 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -91,8 +91,9 @@
             // types/lifetimes replaced)
             let fn_hir_id = tcx.hir.node_to_hir_id(id);
             let fn_sig = cx.tables().liberated_fn_sigs()[fn_hir_id].clone();
+            let fn_def_id = tcx.hir.local_def_id(id);
 
-            let ty = tcx.type_of(tcx.hir.local_def_id(id));
+            let ty = tcx.type_of(fn_def_id);
             let mut abi = fn_sig.abi;
             let implicit_argument = match ty.sty {
                 ty::Closure(..) => {
@@ -108,9 +109,15 @@
                 _ => None,
             };
 
-            // FIXME: safety in closures
             let safety = match fn_sig.unsafety {
                 hir::Unsafety::Normal => Safety::Safe,
+                hir::Unsafety::Unsafe if tcx.is_min_const_fn(fn_def_id) => {
+                    // As specified in #55607, a `const unsafe fn` differs
+                    // from an `unsafe fn` in that its body is still considered
+                    // safe code by default.
+                    assert!(implicit_argument.is_none());
+                    Safety::Safe
+                },
                 hir::Unsafety::Unsafe => Safety::FnUnsafe,
             };
 
diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs
index 6896c91..f6a9d46 100644
--- a/src/librustc_mir/dataflow/graphviz.rs
+++ b/src/librustc_mir/dataflow/graphviz.rs
@@ -137,8 +137,8 @@
                                          block: BasicBlock,
                                          mir: &Mir) -> io::Result<()> {
         // Header rows
-        const HDRS: [&'static str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"];
-        const HDR_FMT: &'static str = "bgcolor=\"grey\"";
+        const HDRS: [&str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"];
+        const HDR_FMT: &str = "bgcolor=\"grey\"";
         write!(w, "<table><tr><td rowspan=\"{}\">", HDRS.len())?;
         write!(w, "{:?}", block.index())?;
         write!(w, "</td></tr><tr>")?;
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index 27bc28a..3a9e4fc 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -246,7 +246,7 @@
                 // re-consider the current implementations of the
                 // propagate_call_return method.
 
-                if let mir::Rvalue::Ref(region, _, ref place) = **rhs {
+                if let mir::Rvalue::Ref(_, _, ref place) = **rhs {
                     if place.ignore_borrow(
                         self.tcx,
                         self.mir,
@@ -258,13 +258,6 @@
                         panic!("could not find BorrowIndex for location {:?}", location);
                     });
 
-                    assert!(self.borrow_set.region_map
-                        .get(&region.to_region_vid())
-                        .unwrap_or_else(|| {
-                            panic!("could not find BorrowIndexs for RegionVid {:?}", region);
-                        })
-                        .contains(&index)
-                    );
                     sets.gen(*index);
 
                     // Issue #46746: Two-phase borrows handles
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 3796b1c..7fe27e9 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -128,7 +128,7 @@
                                 proj: &PlaceProjection<'tcx>)
                                 -> Result<MovePathIndex, MoveError<'tcx>>
     {
-        let base = try!(self.move_path_for(&proj.base));
+        let base = self.move_path_for(&proj.base)?;
         let mir = self.builder.mir;
         let tcx = self.builder.tcx;
         let place_ty = proj.base.ty(mir, tcx).to_ty(tcx);
diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs
index 56a9daf..ec5617d 100644
--- a/src/librustc_mir/diagnostics.rs
+++ b/src/librustc_mir/diagnostics.rs
@@ -606,7 +606,7 @@
 const C: i32 = 2;
 
 // these three are not allowed:
-const CR: &'static mut i32 = &mut C;
+const CR: &mut i32 = &mut C;
 static STATIC_REF: &'static mut i32 = &mut X;
 static CONST_REF: &'static mut i32 = &mut C;
 ```
@@ -1163,7 +1163,7 @@
 use std::cell::Cell;
 
 const A: Cell<usize> = Cell::new(1);
-const B: &'static Cell<usize> = &A;
+const B: &Cell<usize> = &A;
 // error: cannot borrow a constant which may contain interior mutability,
 //        create a static instead
 
@@ -1171,10 +1171,10 @@
 struct C { a: Cell<usize> }
 
 const D: C = C { a: Cell::new(1) };
-const E: &'static Cell<usize> = &D.a; // error
+const E: &Cell<usize> = &D.a; // error
 
 // or:
-const F: &'static C = &D; // error
+const F: &C = &D; // error
 ```
 
 This is because cell types do operations that are not thread-safe. Due to this,
diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir/hair/constant.rs
new file mode 100644
index 0000000..c98ef31
--- /dev/null
+++ b/src/librustc_mir/hair/constant.rs
@@ -0,0 +1,102 @@
+use syntax::ast;
+use rustc::ty::{self, Ty, TyCtxt, ParamEnv};
+use syntax_pos::symbol::Symbol;
+use rustc::mir::interpret::{ConstValue, Scalar};
+
+#[derive(PartialEq)]
+crate enum LitToConstError {
+    UnparseableFloat,
+    Reported,
+}
+
+crate fn lit_to_const<'a, 'gcx, 'tcx>(
+    lit: &'tcx ast::LitKind,
+    tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    ty: Ty<'tcx>,
+    neg: bool,
+) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
+    use syntax::ast::*;
+
+    let trunc = |n| {
+        let param_ty = ParamEnv::reveal_all().and(tcx.lift_to_global(&ty).unwrap());
+        let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size;
+        trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
+        let shift = 128 - width.bits();
+        let result = (n << shift) >> shift;
+        trace!("trunc result: {}", result);
+        Ok(ConstValue::Scalar(Scalar::Bits {
+            bits: result,
+            size: width.bytes() as u8,
+        }))
+    };
+
+    use rustc::mir::interpret::*;
+    let lit = match *lit {
+        LitKind::Str(ref s, _) => {
+            let s = s.as_str();
+            let id = tcx.allocate_bytes(s.as_bytes());
+            ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
+        },
+        LitKind::ByteStr(ref data) => {
+            let id = tcx.allocate_bytes(data);
+            ConstValue::Scalar(Scalar::Ptr(id.into()))
+        },
+        LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bits {
+            bits: n as u128,
+            size: 1,
+        }),
+        LitKind::Int(n, _) if neg => {
+            let n = n as i128;
+            let n = n.overflowing_neg().0;
+            trunc(n as u128)?
+        },
+        LitKind::Int(n, _) => trunc(n)?,
+        LitKind::Float(n, fty) => {
+            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
+        }
+        LitKind::FloatUnsuffixed(n) => {
+            let fty = match ty.sty {
+                ty::Float(fty) => fty,
+                _ => bug!()
+            };
+            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
+        }
+        LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
+        LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
+    };
+    Ok(ty::Const::from_const_value(tcx, lit, ty))
+}
+
+fn parse_float<'tcx>(
+    num: Symbol,
+    fty: ast::FloatTy,
+    neg: bool,
+) -> Result<ConstValue<'tcx>, ()> {
+    let num = num.as_str();
+    use rustc_apfloat::ieee::{Single, Double};
+    use rustc_apfloat::Float;
+    let (bits, size) = match fty {
+        ast::FloatTy::F32 => {
+            num.parse::<f32>().map_err(|_| ())?;
+            let mut f = num.parse::<Single>().unwrap_or_else(|e| {
+                panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
+            });
+            if neg {
+                f = -f;
+            }
+            (f.to_bits(), 4)
+        }
+        ast::FloatTy::F64 => {
+            num.parse::<f64>().map_err(|_| ())?;
+            let mut f = num.parse::<Double>().unwrap_or_else(|e| {
+                panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
+            });
+            if neg {
+                f = -f;
+            }
+            (f.to_bits(), 8)
+        }
+    };
+
+    Ok(ConstValue::Scalar(Scalar::Bits { bits, size }))
+}
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index 733580b..c414088 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -26,12 +26,12 @@
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::subst::{Kind, Substs};
 use rustc::ty::layout::VariantIdx;
-use syntax::ast::{self, LitKind};
+use syntax::ast;
 use syntax::attr;
 use syntax::symbol::Symbol;
 use rustc::hir;
 use rustc_data_structures::sync::Lrc;
-use hair::pattern::parse_float;
+use hair::constant::{lit_to_const, LitToConstError};
 
 #[derive(Clone)]
 pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
@@ -131,7 +131,6 @@
         ty::Const::from_bool(self.tcx, false)
     }
 
-    // FIXME: Combine with rustc_mir::hair::pattern::lit_to_const
     pub fn const_eval_literal(
         &mut self,
         lit: &'tcx ast::LitKind,
@@ -141,61 +140,19 @@
     ) -> &'tcx ty::Const<'tcx> {
         trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg);
 
-        let parse_float = |num, fty| -> ConstValue<'tcx> {
-            parse_float(num, fty, neg).unwrap_or_else(|_| {
+        match lit_to_const(lit, self.tcx, ty, neg) {
+            Ok(c) => c,
+            Err(LitToConstError::UnparseableFloat) => {
                 // FIXME(#31407) this is only necessary because float parsing is buggy
-                self.tcx.sess.span_fatal(sp, "could not evaluate float literal (see issue #31407)");
-            })
-        };
-
-        let trunc = |n| {
-            let param_ty = self.param_env.and(self.tcx.lift_to_global(&ty).unwrap());
-            let width = self.tcx.layout_of(param_ty).unwrap().size;
-            trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
-            let shift = 128 - width.bits();
-            let result = (n << shift) >> shift;
-            trace!("trunc result: {}", result);
-            ConstValue::Scalar(Scalar::Bits {
-                bits: result,
-                size: width.bytes() as u8,
-            })
-        };
-
-        use rustc::mir::interpret::*;
-        let lit = match *lit {
-            LitKind::Str(ref s, _) => {
-                let s = s.as_str();
-                let id = self.tcx.allocate_bytes(s.as_bytes());
-                ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &self.tcx)
+                self.tcx.sess.span_err(sp, "could not evaluate float literal (see issue #31407)");
+                // create a dummy value and continue compiling
+                Const::from_bits(self.tcx, 0, self.param_env.and(ty))
             },
-            LitKind::ByteStr(ref data) => {
-                let id = self.tcx.allocate_bytes(data);
-                ConstValue::Scalar(Scalar::Ptr(id.into()))
-            },
-            LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bits {
-                bits: n as u128,
-                size: 1,
-            }),
-            LitKind::Int(n, _) if neg => {
-                let n = n as i128;
-                let n = n.overflowing_neg().0;
-                trunc(n as u128)
-            },
-            LitKind::Int(n, _) => trunc(n),
-            LitKind::Float(n, fty) => {
-                parse_float(n, fty)
+            Err(LitToConstError::Reported) => {
+                // create a dummy value and continue compiling
+                Const::from_bits(self.tcx, 0, self.param_env.and(ty))
             }
-            LitKind::FloatUnsuffixed(n) => {
-                let fty = match ty.sty {
-                    ty::Float(fty) => fty,
-                    _ => bug!()
-                };
-                parse_float(n, fty)
-            }
-            LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
-            LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
-        };
-        ty::Const::from_const_value(self.tcx, lit, ty)
+        }
     }
 
     pub fn pattern_from_hir(&mut self, p: &hir::Pat) -> Pattern<'tcx> {
diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs
index 3078f10..e604b11 100644
--- a/src/librustc_mir/hair/mod.rs
+++ b/src/librustc_mir/hair/mod.rs
@@ -26,6 +26,7 @@
 use self::cx::Cx;
 
 pub mod cx;
+mod constant;
 
 pub mod pattern;
 pub use self::pattern::{BindingMode, Pattern, PatternKind, FieldPattern};
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index fd869d6..5db7b6c 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -309,6 +309,7 @@
     /// outside it's module and should not be matchable with an empty match
     /// statement.
     pub module: DefId,
+    param_env: ty::ParamEnv<'tcx>,
     pub pattern_arena: &'a TypedArena<Pattern<'tcx>>,
     pub byte_array_map: FxHashMap<*const Pattern<'tcx>, Vec<&'a Pattern<'tcx>>>,
 }
@@ -316,6 +317,7 @@
 impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
     pub fn create_and_enter<F, R>(
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
         module: DefId,
         f: F) -> R
         where F: for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R
@@ -324,53 +326,13 @@
 
         f(MatchCheckCtxt {
             tcx,
+            param_env,
             module,
             pattern_arena: &pattern_arena,
             byte_array_map: FxHashMap::default(),
         })
     }
 
-    // convert a byte-string pattern to a list of u8 patterns.
-    fn lower_byte_str_pattern<'p>(&mut self, pat: &'p Pattern<'tcx>) -> Vec<&'p Pattern<'tcx>>
-            where 'a: 'p
-    {
-        let pattern_arena = &*self.pattern_arena;
-        let tcx = self.tcx;
-        self.byte_array_map.entry(pat).or_insert_with(|| {
-            match pat.kind {
-                box PatternKind::Constant {
-                    value: const_val
-                } => {
-                    if let Some(ptr) = const_val.to_ptr() {
-                        let is_array_ptr = const_val.ty
-                            .builtin_deref(true)
-                            .and_then(|t| t.ty.builtin_index())
-                            .map_or(false, |t| t == tcx.types.u8);
-                        assert!(is_array_ptr);
-                        let alloc = tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
-                        assert_eq!(ptr.offset.bytes(), 0);
-                        // FIXME: check length
-                        alloc.bytes.iter().map(|b| {
-                            &*pattern_arena.alloc(Pattern {
-                                ty: tcx.types.u8,
-                                span: pat.span,
-                                kind: box PatternKind::Constant {
-                                    value: ty::Const::from_bits(
-                                        tcx,
-                                        *b as u128,
-                                        ty::ParamEnv::empty().and(tcx.types.u8))
-                                }
-                            })
-                        }).collect()
-                    } else {
-                        bug!("not a byte str: {:?}", const_val)
-                    }
-                }
-                _ => span_bug!(pat.span, "unexpected byte array pattern {:?}", pat)
-            }
-        }).clone()
-    }
-
     fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
         if self.tcx.features().exhaustive_patterns {
             self.tcx.is_ty_uninhabited_from(self.module, ty)
@@ -622,7 +584,6 @@
                                   -> Vec<Constructor<'tcx>>
 {
     debug!("all_constructors({:?})", pcx.ty);
-    let exhaustive_integer_patterns = cx.tcx.features().exhaustive_integer_patterns;
     let ctors = match pcx.ty.sty {
         ty::Bool => {
             [true, false].iter().map(|&b| {
@@ -652,7 +613,7 @@
                 .map(|v| Variant(v.did))
                 .collect()
         }
-        ty::Char if exhaustive_integer_patterns => {
+        ty::Char => {
             vec![
                 // The valid Unicode Scalar Value ranges.
                 ConstantRange('\u{0000}' as u128,
@@ -667,14 +628,14 @@
                 ),
             ]
         }
-        ty::Int(ity) if exhaustive_integer_patterns => {
+        ty::Int(ity) => {
             // FIXME(49937): refactor these bit manipulations into interpret.
             let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128;
             let min = 1u128 << (bits - 1);
             let max = (1u128 << (bits - 1)) - 1;
             vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)]
         }
-        ty::Uint(uty) if exhaustive_integer_patterns => {
+        ty::Uint(uty) => {
             // FIXME(49937): refactor these bit manipulations into interpret.
             let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128;
             let max = !0u128 >> (128 - bits);
@@ -813,8 +774,17 @@
     fn from_ctor(tcx: TyCtxt<'_, 'tcx, 'tcx>,
                  ctor: &Constructor<'tcx>)
                  -> Option<IntRange<'tcx>> {
+        // Floating-point ranges are permitted and we don't want
+        // to consider them when constructing integer ranges.
+        fn is_integral<'tcx>(ty: Ty<'tcx>) -> bool {
+            match ty.sty {
+                ty::Char | ty::Int(_) | ty::Uint(_) => true,
+                _ => false,
+            }
+        }
+
         match ctor {
-            ConstantRange(lo, hi, ty, end) => {
+            ConstantRange(lo, hi, ty, end) if is_integral(ty) => {
                 // Perform a shift if the underlying types are signed,
                 // which makes the interval arithmetic simpler.
                 let bias = IntRange::signed_bias(tcx, ty);
@@ -827,7 +797,7 @@
                     Some(IntRange { range: lo..=(hi - offset), ty })
                 }
             }
-            ConstantValue(val) => {
+            ConstantValue(val) if is_integral(val.ty) => {
                 let ty = val.ty;
                 if let Some(val) = val.assert_bits(tcx, ty::ParamEnv::empty().and(ty)) {
                     let bias = IntRange::signed_bias(tcx, ty);
@@ -837,9 +807,7 @@
                     None
                 }
             }
-            Single | Variant(_) | Slice(_) => {
-                None
-            }
+            _ => None,
         }
     }
 
@@ -971,12 +939,10 @@
                 // If a constructor appears in a `match` arm, we can
                 // eliminate it straight away.
                 refined_ctors = vec![]
-            } else if tcx.features().exhaustive_integer_patterns {
-                if let Some(interval) = IntRange::from_ctor(tcx, used_ctor) {
-                    // Refine the required constructors for the type by subtracting
-                    // the range defined by the current constructor pattern.
-                    refined_ctors = interval.subtract_from(tcx, refined_ctors);
-                }
+            } else if let Some(interval) = IntRange::from_ctor(tcx, used_ctor) {
+                // Refine the required constructors for the type by subtracting
+                // the range defined by the current constructor pattern.
+                refined_ctors = interval.subtract_from(tcx, refined_ctors);
             }
 
             // If the constructor patterns that have been considered so far
@@ -1132,7 +1098,8 @@
 
         // For privately empty and non-exhaustive enums, we work as if there were an "extra"
         // `_` constructor for the type, so we can never match over all constructors.
-        let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive;
+        let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive ||
+            (pcx.ty.is_pointer_sized() && !cx.tcx.features().precise_pointer_size_matching);
 
         if cheap_missing_ctors == MissingCtors::Empty && !is_non_exhaustive {
             split_grouped_constructors(cx.tcx, all_ctors, matrix, pcx.ty).into_iter().map(|c| {
@@ -1393,11 +1360,6 @@
                 ConstValue::Scalar(val) | ConstValue::ScalarPair(val, _) => val,
             };
             if let Ok(ptr) = val.to_ptr() {
-                let is_array_ptr = const_val.ty
-                    .builtin_deref(true)
-                    .and_then(|t| t.ty.builtin_index())
-                    .map_or(false, |t| t == tcx.types.u8);
-                assert!(is_array_ptr);
                 tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id).bytes.as_ref()
             } else {
                 bug!("unexpected non-ptr ConstantValue")
@@ -1433,17 +1395,16 @@
 // Whether to evaluate a constructor using exhaustive integer matching. This is true if the
 // constructor is a range or constant with an integer type.
 fn should_treat_range_exhaustively(tcx: TyCtxt<'_, 'tcx, 'tcx>, ctor: &Constructor<'tcx>) -> bool {
-    if tcx.features().exhaustive_integer_patterns {
-        let ty = match ctor {
-            ConstantValue(value) => value.ty,
-            ConstantRange(_, _, ty, _) => ty,
-            _ => return false,
-        };
-        if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
-            return true;
-        }
+    let ty = match ctor {
+        ConstantValue(value) => value.ty,
+        ConstantRange(_, _, ty, _) => ty,
+        _ => return false,
+    };
+    if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
+        !ty.is_pointer_sized() || tcx.features().precise_pointer_size_matching
+    } else {
+        false
     }
-    false
 }
 
 /// For exhaustive integer matching, some constructors are grouped within other constructors
@@ -1705,26 +1666,63 @@
         PatternKind::Constant { value } => {
             match *constructor {
                 Slice(..) => {
-                    if let Some(ptr) = value.to_ptr() {
-                        let is_array_ptr = value.ty
-                            .builtin_deref(true)
-                            .and_then(|t| t.ty.builtin_index())
-                            .map_or(false, |t| t == cx.tcx.types.u8);
-                        assert!(is_array_ptr);
-                        let data_len = cx.tcx
-                            .alloc_map
-                            .lock()
-                            .unwrap_memory(ptr.alloc_id)
-                            .bytes
-                            .len();
-                        if wild_patterns.len() == data_len {
-                            Some(cx.lower_byte_str_pattern(pat))
-                        } else {
-                            None
+                    // we extract an `Option` for the pointer because slices of zero elements don't
+                    // necessarily point to memory, they are usually just integers. The only time
+                    // they should be pointing to memory is when they are subslices of nonzero
+                    // slices
+                    let (opt_ptr, n, ty) = match value.ty.builtin_deref(false).unwrap().ty.sty {
+                        ty::TyKind::Array(t, n) => (value.to_ptr(), n.unwrap_usize(cx.tcx), t),
+                        ty::TyKind::Slice(t) => {
+                            match value.val {
+                                ConstValue::ScalarPair(ptr, n) => (
+                                    ptr.to_ptr().ok(),
+                                    n.to_bits(cx.tcx.data_layout.pointer_size).unwrap() as u64,
+                                    t,
+                                ),
+                                _ => span_bug!(
+                                    pat.span,
+                                    "slice pattern constant must be scalar pair but is {:?}",
+                                    value,
+                                ),
+                            }
+                        },
+                        _ => span_bug!(
+                            pat.span,
+                            "unexpected const-val {:?} with ctor {:?}",
+                            value,
+                            constructor,
+                        ),
+                    };
+                    if wild_patterns.len() as u64 == n {
+                        // convert a constant slice/array pattern to a list of patterns.
+                        match (n, opt_ptr) {
+                            (0, _) => Some(Vec::new()),
+                            (_, Some(ptr)) => {
+                                let alloc = cx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
+                                let layout = cx.tcx.layout_of(cx.param_env.and(ty)).ok()?;
+                                (0..n).map(|i| {
+                                    let ptr = ptr.offset(layout.size * i, &cx.tcx).ok()?;
+                                    let scalar = alloc.read_scalar(
+                                        &cx.tcx, ptr, layout.size,
+                                    ).ok()?;
+                                    let scalar = scalar.not_undef().ok()?;
+                                    let value = ty::Const::from_scalar(cx.tcx, scalar, ty);
+                                    let pattern = Pattern {
+                                        ty,
+                                        span: pat.span,
+                                        kind: box PatternKind::Constant { value },
+                                    };
+                                    Some(&*cx.pattern_arena.alloc(pattern))
+                                }).collect()
+                            },
+                            (_, None) => span_bug!(
+                                pat.span,
+                                "non zero length slice with const-val {:?}",
+                                value,
+                            ),
                         }
                     } else {
-                        span_bug!(pat.span,
-                        "unexpected const-val {:?} with ctor {:?}", value, constructor)
+                        None
                     }
                 }
                 _ => {
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index bafabe4..db6d9b6 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -193,7 +193,7 @@
         }
 
         let module = self.tcx.hir.get_module_parent(scrut.id);
-        MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| {
+        MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
             let mut have_errors = false;
 
             let inlined_arms : Vec<(Vec<_>, _)> = arms.iter().map(|arm| (
@@ -234,7 +234,7 @@
                 if !scrutinee_is_uninhabited {
                     // We know the type is inhabited, so this must be wrong
                     let mut err = create_e0004(self.tcx.sess, scrut.span,
-                                               format!("non-exhaustive patterns: type {} \
+                                               format!("non-exhaustive patterns: type `{}` \
                                                         is non-empty",
                                                        pat_ty));
                     span_help!(&mut err, scrut.span,
@@ -268,7 +268,7 @@
 
     fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) {
         let module = self.tcx.hir.get_module_parent(pat.id);
-        MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| {
+        MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
             let mut patcx = PatternContext::new(self.tcx,
                                                 self.param_env.and(self.identity_substs),
                                                 self.tables);
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 941744c..61d8297 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -19,6 +19,7 @@
 use const_eval::{const_field, const_variant_index};
 
 use hair::util::UserAnnotatedTyHelpers;
+use hair::constant::*;
 
 use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
 use rustc::mir::{ProjectionElem, UserTypeAnnotation, UserTypeProjection, UserTypeProjections};
@@ -37,7 +38,6 @@
 use syntax::ast;
 use syntax::ptr::P;
 use syntax_pos::Span;
-use syntax_pos::symbol::Symbol;
 
 #[derive(Clone, Debug)]
 pub enum PatternError {
@@ -891,12 +891,11 @@
                         );
                         *self.const_to_pat(instance, val, expr.hir_id, lit.span).kind
                     },
-                    Err(e) => {
-                        if e == LitToConstError::UnparseableFloat {
-                            self.errors.push(PatternError::FloatBug);
-                        }
+                    Err(LitToConstError::UnparseableFloat) => {
+                        self.errors.push(PatternError::FloatBug);
                         PatternKind::Wild
                     },
+                    Err(LitToConstError::Reported) => PatternKind::Wild,
                 }
             },
             hir::ExprKind::Path(ref qpath) => *self.lower_path(qpath, expr.hir_id, expr.span).kind,
@@ -914,12 +913,11 @@
                         );
                         *self.const_to_pat(instance, val, expr.hir_id, lit.span).kind
                     },
-                    Err(e) => {
-                        if e == LitToConstError::UnparseableFloat {
-                            self.errors.push(PatternError::FloatBug);
-                        }
+                    Err(LitToConstError::UnparseableFloat) => {
+                        self.errors.push(PatternError::FloatBug);
                         PatternKind::Wild
                     },
+                    Err(LitToConstError::Reported) => PatternKind::Wild,
                 }
             }
             _ => span_bug!(expr.span, "not a literal: {:?}", expr),
@@ -1294,124 +1292,3 @@
 
     fallback()
 }
-
-#[derive(PartialEq)]
-enum LitToConstError {
-    UnparseableFloat,
-    Propagated,
-}
-
-// FIXME: Combine with rustc_mir::hair::cx::const_eval_literal
-fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind,
-                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          ty: Ty<'tcx>,
-                          neg: bool)
-                          -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
-    use syntax::ast::*;
-
-    use rustc::mir::interpret::*;
-    let lit = match *lit {
-        LitKind::Str(ref s, _) => {
-            let s = s.as_str();
-            let id = tcx.allocate_bytes(s.as_bytes());
-            ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
-        },
-        LitKind::ByteStr(ref data) => {
-            let id = tcx.allocate_bytes(data);
-            ConstValue::Scalar(Scalar::Ptr(id.into()))
-        },
-        LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bits {
-            bits: n as u128,
-            size: 1,
-        }),
-        LitKind::Int(n, _) => {
-            enum Int {
-                Signed(IntTy),
-                Unsigned(UintTy),
-            }
-            let ity = match ty.sty {
-                ty::Int(IntTy::Isize) => Int::Signed(tcx.sess.target.isize_ty),
-                ty::Int(other) => Int::Signed(other),
-                ty::Uint(UintTy::Usize) => Int::Unsigned(tcx.sess.target.usize_ty),
-                ty::Uint(other) => Int::Unsigned(other),
-                ty::Error => { // Avoid ICE (#51963)
-                    return Err(LitToConstError::Propagated);
-                }
-                _ => bug!("literal integer type with bad type ({:?})", ty.sty),
-            };
-            // This converts from LitKind::Int (which is sign extended) to
-            // Scalar::Bytes (which is zero extended)
-            let n = match ity {
-                // FIXME(oli-obk): are these casts correct?
-                Int::Signed(IntTy::I8) if neg =>
-                    (n as i8).overflowing_neg().0 as u8 as u128,
-                Int::Signed(IntTy::I16) if neg =>
-                    (n as i16).overflowing_neg().0 as u16 as u128,
-                Int::Signed(IntTy::I32) if neg =>
-                    (n as i32).overflowing_neg().0 as u32 as u128,
-                Int::Signed(IntTy::I64) if neg =>
-                    (n as i64).overflowing_neg().0 as u64 as u128,
-                Int::Signed(IntTy::I128) if neg =>
-                    (n as i128).overflowing_neg().0 as u128,
-                Int::Signed(IntTy::I8) | Int::Unsigned(UintTy::U8) => n as u8 as u128,
-                Int::Signed(IntTy::I16) | Int::Unsigned(UintTy::U16) => n as u16 as u128,
-                Int::Signed(IntTy::I32) | Int::Unsigned(UintTy::U32) => n as u32 as u128,
-                Int::Signed(IntTy::I64) | Int::Unsigned(UintTy::U64) => n as u64 as u128,
-                Int::Signed(IntTy::I128)| Int::Unsigned(UintTy::U128) => n,
-                _ => bug!(),
-            };
-            let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size.bytes() as u8;
-            ConstValue::Scalar(Scalar::Bits {
-                bits: n,
-                size,
-            })
-        },
-        LitKind::Float(n, fty) => {
-            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
-        }
-        LitKind::FloatUnsuffixed(n) => {
-            let fty = match ty.sty {
-                ty::Float(fty) => fty,
-                _ => bug!()
-            };
-            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
-        }
-        LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
-        LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
-    };
-    Ok(ty::Const::from_const_value(tcx, lit, ty))
-}
-
-pub fn parse_float<'tcx>(
-    num: Symbol,
-    fty: ast::FloatTy,
-    neg: bool,
-) -> Result<ConstValue<'tcx>, ()> {
-    let num = num.as_str();
-    use rustc_apfloat::ieee::{Single, Double};
-    use rustc_apfloat::Float;
-    let (bits, size) = match fty {
-        ast::FloatTy::F32 => {
-            num.parse::<f32>().map_err(|_| ())?;
-            let mut f = num.parse::<Single>().unwrap_or_else(|e| {
-                panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
-            });
-            if neg {
-                f = -f;
-            }
-            (f.to_bits(), 4)
-        }
-        ast::FloatTy::F64 => {
-            num.parse::<f64>().map_err(|_| ())?;
-            let mut f = num.parse::<Double>().unwrap_or_else(|e| {
-                panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
-            });
-            if neg {
-                f = -f;
-            }
-            (f.to_bits(), 8)
-        }
-    };
-
-    Ok(ConstValue::Scalar(Scalar::Bits { bits, size }))
-}
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index d7a3a27..f43cfb9 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -204,6 +204,7 @@
     fn retag(
         _ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
         _fn_entry: bool,
+        _two_phase: bool,
         _place: PlaceTy<'tcx, Self::PointerTag>,
     ) -> EvalResult<'tcx> {
         Ok(())
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 1b47530..164a968 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -115,6 +115,16 @@
         }
     }
 
+    #[inline]
+    pub fn with_tag(self, new_tag: Tag) -> Self
+    {
+        MemPlace {
+            ptr: self.ptr.with_tag(new_tag),
+            align: self.align,
+            meta: self.meta,
+        }
+    }
+
     #[inline(always)]
     pub fn from_scalar_ptr(ptr: Scalar<Tag>, align: Align) -> Self {
         MemPlace {
@@ -187,6 +197,16 @@
         }
     }
 
+    #[inline]
+    pub fn with_tag(self, new_tag: Tag) -> Self
+    {
+        MPlaceTy {
+            mplace: self.mplace.with_tag(new_tag),
+            layout: self.layout,
+        }
+    }
+
+    #[inline]
     pub fn offset(
         self,
         offset: Size,
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 8814118..84cc512 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -119,9 +119,9 @@
             FakeRead(..) => {}
 
             // Stacked Borrows.
-            Retag { fn_entry, ref place } => {
+            Retag { fn_entry, two_phase, ref place } => {
                 let dest = self.eval_place(place)?;
-                M::retag(self, fn_entry, dest)?;
+                M::retag(self, fn_entry, two_phase, dest)?;
             }
             EscapeToRaw(ref op) => {
                 let op = self.eval_operand(op, None)?;
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 617d204..300f3d6 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -182,6 +182,7 @@
     }
 
     fn check_argument_compat(
+        rust_abi: bool,
         caller: TyLayout<'tcx>,
         callee: TyLayout<'tcx>,
     ) -> bool {
@@ -189,13 +190,20 @@
             // No question
             return true;
         }
+        if !rust_abi {
+            // Don't risk anything
+            return false;
+        }
         // Compare layout
         match (&caller.abi, &callee.abi) {
+            // Different valid ranges are okay (once we enforce validity,
+            // that will take care to make it UB to leave the range, just
+            // like for transmute).
             (layout::Abi::Scalar(ref caller), layout::Abi::Scalar(ref callee)) =>
-                // Different valid ranges are okay (once we enforce validity,
-                // that will take care to make it UB to leave the range, just
-                // like for transmute).
                 caller.value == callee.value,
+            (layout::Abi::ScalarPair(ref caller1, ref caller2),
+             layout::Abi::ScalarPair(ref callee1, ref callee2)) =>
+                caller1.value == callee1.value && caller2.value == callee2.value,
             // Be conservative
             _ => false
         }
@@ -204,22 +212,22 @@
     /// Pass a single argument, checking the types for compatibility.
     fn pass_argument(
         &mut self,
-        skip_zst: bool,
+        rust_abi: bool,
         caller_arg: &mut impl Iterator<Item=OpTy<'tcx, M::PointerTag>>,
         callee_arg: PlaceTy<'tcx, M::PointerTag>,
     ) -> EvalResult<'tcx> {
-        if skip_zst && callee_arg.layout.is_zst() {
+        if rust_abi && callee_arg.layout.is_zst() {
             // Nothing to do.
             trace!("Skipping callee ZST");
             return Ok(());
         }
         let caller_arg = caller_arg.next()
             .ok_or_else(|| EvalErrorKind::FunctionArgCountMismatch)?;
-        if skip_zst {
+        if rust_abi {
             debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out");
         }
         // Now, check
-        if !Self::check_argument_compat(caller_arg.layout, callee_arg.layout) {
+        if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) {
             return err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty));
         }
         // We allow some transmutes here
@@ -319,7 +327,7 @@
                     // Figure out how to pass which arguments.
                     // We have two iterators: Where the arguments come from,
                     // and where they go to.
-                    let skip_zst = match caller_abi {
+                    let rust_abi = match caller_abi {
                         Abi::Rust | Abi::RustCall => true,
                         _ => false
                     };
@@ -344,7 +352,7 @@
                         };
                     // Skip ZSTs
                     let mut caller_iter = caller_args.iter()
-                        .filter(|op| !skip_zst || !op.layout.is_zst())
+                        .filter(|op| !rust_abi || !op.layout.is_zst())
                         .map(|op| *op);
 
                     // Now we have to spread them out across the callee's locals,
@@ -359,11 +367,11 @@
                             // Must be a tuple
                             for i in 0..dest.layout.fields.count() {
                                 let dest = self.place_field(dest, i as u64)?;
-                                self.pass_argument(skip_zst, &mut caller_iter, dest)?;
+                                self.pass_argument(rust_abi, &mut caller_iter, dest)?;
                             }
                         } else {
                             // Normal argument
-                            self.pass_argument(skip_zst, &mut caller_iter, dest)?;
+                            self.pass_argument(rust_abi, &mut caller_iter, dest)?;
                         }
                     }
                     // Now we should have no more caller args
@@ -374,7 +382,11 @@
                     // Don't forget to check the return type!
                     if let Some(caller_ret) = dest {
                         let callee_ret = self.eval_place(&mir::Place::Local(mir::RETURN_PLACE))?;
-                        if !Self::check_argument_compat(caller_ret.layout, callee_ret.layout) {
+                        if !Self::check_argument_compat(
+                            rust_abi,
+                            caller_ret.layout,
+                            callee_ret.layout,
+                        ) {
                             return err!(FunctionRetMismatch(
                                 caller_ret.layout.ty, callee_ret.layout.ty
                             ));
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index 6dba020..528942d 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -585,7 +585,7 @@
     // smallest into each other) we're sure to start off with a deterministic
     // order (sorted by name). This'll mean that if two cgus have the same size
     // the stable sort below will keep everything nice and deterministic.
-    codegen_units.sort_by_key(|cgu| cgu.name().clone());
+    codegen_units.sort_by_key(|cgu| *cgu.name());
 
     // Merge the two smallest codegen units until the target size is reached.
     while codegen_units.len() > target_cgu_count {
@@ -985,7 +985,7 @@
                 output.push_str(" @@");
                 let mut empty = Vec::new();
                 let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
-                cgus.as_mut_slice().sort_by_key(|&(ref name, _)| name.clone());
+                cgus.sort_by_key(|(name, _)| *name);
                 cgus.dedup();
                 for &(ref cgu_name, (linkage, _)) in cgus.iter() {
                     output.push_str(" ");
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 93bf1b3..3a53cc6 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -226,9 +226,18 @@
         // The first argument (index 0), but add 1 for the return value.
         let dropee_ptr = Place::Local(Local::new(1+0));
         if tcx.sess.opts.debugging_opts.mir_emit_retag {
-            // We use raw ptr operations, better prepare the alias tracking for that
+            // Function arguments should be retagged
             mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
                 source_info,
+                kind: StatementKind::Retag {
+                    fn_entry: true,
+                    two_phase: false,
+                    place: dropee_ptr.clone(),
+                },
+            });
+            // We use raw ptr operations, better prepare the alias tracking for that
+            mir.basic_blocks_mut()[START_BLOCK].statements.insert(1, Statement {
+                source_info,
                 kind: StatementKind::EscapeToRaw(Operand::Copy(dropee_ptr.clone())),
             })
         }
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index be7e34e..811b854 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -118,7 +118,7 @@
             basic_blocks[START_BLOCK].statements.splice(0..0,
                 places.into_iter().map(|place| Statement {
                     source_info,
-                    kind: StatementKind::Retag { fn_entry: true, place },
+                    kind: StatementKind::Retag { fn_entry: true, two_phase: false, place },
                 })
             );
         }
@@ -154,7 +154,7 @@
         for (source_info, dest_place, dest_block) in returns {
             basic_blocks[dest_block].statements.insert(0, Statement {
                 source_info,
-                kind: StatementKind::Retag { fn_entry: false, place: dest_place },
+                kind: StatementKind::Retag { fn_entry: false, two_phase: false, place: dest_place },
             });
         }
 
@@ -191,12 +191,21 @@
                     // Assignments of reference or ptr type are the ones where we may have
                     // to update tags.  This includes `x = &[mut] ...` and hence
                     // we also retag after taking a reference!
-                    StatementKind::Assign(ref place, _) if needs_retag(place) => {
+                    StatementKind::Assign(ref place, box ref rvalue) if needs_retag(place) => {
+                        let two_phase = match rvalue {
+                            Rvalue::Ref(_, borrow_kind, _) =>
+                                borrow_kind.allows_two_phase_borrow(),
+                            _ => false
+                        };
                         // Insert a retag after the assignment.
                         let source_info = block_data.statements[i].source_info;
                         block_data.statements.insert(i+1, Statement {
                             source_info,
-                            kind: StatementKind::Retag { fn_entry: false, place: place.clone() },
+                            kind: StatementKind::Retag {
+                                fn_entry: false,
+                                two_phase,
+                                place: place.clone(),
+                            },
                         });
                     }
                     // Do nothing for the rest
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 3404772..75f8045 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -23,6 +23,9 @@
 
 use syntax::ast;
 use syntax::symbol::Symbol;
+use syntax::feature_gate::{emit_feature_err, GateIssue};
+
+use std::ops::Bound;
 
 use util;
 
@@ -34,6 +37,7 @@
     source_info: SourceInfo,
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
+    /// mark an `unsafe` block as used, so we don't lint it
     used_unsafe: FxHashSet<ast::NodeId>,
     inherited_blocks: Vec<(ast::NodeId, bool)>,
 }
@@ -93,7 +97,7 @@
                 if let hir::Unsafety::Unsafe = sig.unsafety() {
                     self.require_unsafe("call to unsafe function",
                         "consult the function's documentation for information on how to avoid \
-                         undefined behavior")
+                         undefined behavior", UnsafetyViolationKind::GatedConstFnCall)
                 }
             }
         }
@@ -121,7 +125,8 @@
 
             StatementKind::InlineAsm { .. } => {
                 self.require_unsafe("use of inline assembly",
-                    "inline assembly is entirely unchecked and can cause undefined behavior")
+                    "inline assembly is entirely unchecked and can cause undefined behavior",
+                    UnsafetyViolationKind::General)
             },
         }
         self.super_statement(block, statement, location);
@@ -134,8 +139,18 @@
         if let &Rvalue::Aggregate(box ref aggregate, _) = rvalue {
             match aggregate {
                 &AggregateKind::Array(..) |
-                &AggregateKind::Tuple |
-                &AggregateKind::Adt(..) => {}
+                &AggregateKind::Tuple => {}
+                &AggregateKind::Adt(ref def, ..) => {
+                    match self.tcx.layout_scalar_valid_range(def.did) {
+                        (Bound::Unbounded, Bound::Unbounded) => {},
+                        _ => self.require_unsafe(
+                            "initializing type with `rustc_layout_scalar_valid_range` attr",
+                            "initializing a layout restricted type's field with a value outside \
+                            the valid range is undefined behavior",
+                            UnsafetyViolationKind::GeneralAndConstFn,
+                        ),
+                    }
+                }
                 &AggregateKind::Closure(def_id, _) |
                 &AggregateKind::Generator(def_id, _, _) => {
                     let UnsafetyCheckResult {
@@ -152,28 +167,43 @@
                     place: &Place<'tcx>,
                     context: PlaceContext<'tcx>,
                     location: Location) {
-        if context.is_borrow() {
-            if util::is_disaligned(self.tcx, self.mir, self.param_env, place) {
-                let source_info = self.source_info;
-                let lint_root =
-                    self.source_scope_local_data[source_info.scope].lint_root;
-                self.register_violations(&[UnsafetyViolation {
-                    source_info,
-                    description: Symbol::intern("borrow of packed field").as_interned_str(),
-                    details:
-                        Symbol::intern("fields of packed structs might be misaligned: \
-                                        dereferencing a misaligned pointer or even just creating a \
-                                        misaligned reference is undefined behavior")
-                            .as_interned_str(),
-                    kind: UnsafetyViolationKind::BorrowPacked(lint_root)
-                }], &[]);
-            }
-        }
-
         match place {
             &Place::Projection(box Projection {
                 ref base, ref elem
             }) => {
+                if context.is_borrow() {
+                    if util::is_disaligned(self.tcx, self.mir, self.param_env, place) {
+                        let source_info = self.source_info;
+                        let lint_root =
+                            self.source_scope_local_data[source_info.scope].lint_root;
+                        self.register_violations(&[UnsafetyViolation {
+                            source_info,
+                            description: Symbol::intern("borrow of packed field").as_interned_str(),
+                            details:
+                                Symbol::intern("fields of packed structs might be misaligned: \
+                                                dereferencing a misaligned pointer or even just \
+                                                creating a misaligned reference is undefined \
+                                                behavior")
+                                    .as_interned_str(),
+                            kind: UnsafetyViolationKind::BorrowPacked(lint_root)
+                        }], &[]);
+                    }
+                }
+                let is_borrow_of_interior_mut = context.is_borrow() && !base
+                    .ty(self.mir, self.tcx)
+                    .to_ty(self.tcx)
+                    .is_freeze(self.tcx, self.param_env, self.source_info.span);
+                // prevent
+                // * `&mut x.field`
+                // * `x.field = y;`
+                // * `&x.field` if `field`'s type has interior mutability
+                // because either of these would allow modifying the layout constrained field and
+                // insert values that violate the layout constraints.
+                if context.is_mutating_use() || is_borrow_of_interior_mut {
+                    self.check_mut_borrowing_layout_constrained_field(
+                        place, context.is_mutating_use(),
+                    );
+                }
                 let old_source_info = self.source_info;
                 if let &Place::Local(local) = base {
                     if self.mir.local_decls[local].internal {
@@ -189,7 +219,7 @@
                         self.require_unsafe("dereference of raw pointer",
                             "raw pointers may be NULL, dangling or unaligned; they can violate \
                              aliasing rules and cause data races: all of these are undefined \
-                             behavior")
+                             behavior", UnsafetyViolationKind::General)
                     }
                     ty::Adt(adt, _) => {
                         if adt.is_union() {
@@ -212,14 +242,15 @@
                                         "assignment to non-`Copy` union field",
                                         "the previous content of the field will be dropped, which \
                                          causes undefined behavior if the field was not properly \
-                                         initialized")
+                                         initialized", UnsafetyViolationKind::General)
                                 } else {
                                     // write to non-move union, safe
                                 }
                             } else {
                                 self.require_unsafe("access to union field",
                                     "the field may not be properly initialized: using \
-                                     uninitialized data will cause undefined behavior")
+                                     uninitialized data will cause undefined behavior",
+                                     UnsafetyViolationKind::General)
                             }
                         }
                     }
@@ -237,7 +268,8 @@
                 if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) {
                     self.require_unsafe("use of mutable static",
                         "mutable statics can be mutated by multiple threads: aliasing violations \
-                         or data races will cause undefined behavior");
+                         or data races will cause undefined behavior",
+                         UnsafetyViolationKind::General);
                 } else if self.tcx.is_foreign_item(def_id) {
                     let source_info = self.source_info;
                     let lint_root =
@@ -260,45 +292,96 @@
 }
 
 impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
-    fn require_unsafe(&mut self,
-                      description: &'static str,
-                      details: &'static str)
-    {
+    fn require_unsafe(
+        &mut self,
+        description: &'static str,
+        details: &'static str,
+        kind: UnsafetyViolationKind,
+    ) {
         let source_info = self.source_info;
         self.register_violations(&[UnsafetyViolation {
             source_info,
             description: Symbol::intern(description).as_interned_str(),
             details: Symbol::intern(details).as_interned_str(),
-            kind: UnsafetyViolationKind::General,
+            kind,
         }], &[]);
     }
 
     fn register_violations(&mut self,
                            violations: &[UnsafetyViolation],
                            unsafe_blocks: &[(ast::NodeId, bool)]) {
-        if self.min_const_fn {
-            for violation in violations {
-                let mut violation = violation.clone();
-                violation.kind = UnsafetyViolationKind::MinConstFn;
-                if !self.violations.contains(&violation) {
-                    self.violations.push(violation)
-                }
-            }
-        }
-        let within_unsafe = match self.source_scope_local_data[self.source_info.scope].safety {
-            Safety::Safe => {
+        let safety = self.source_scope_local_data[self.source_info.scope].safety;
+        let within_unsafe = match (safety, self.min_const_fn) {
+            // Erring on the safe side, pun intended
+            (Safety::BuiltinUnsafe, true) |
+            // mir building encodes const fn bodies as safe, even for `const unsafe fn`
+            (Safety::FnUnsafe, true) => bug!("const unsafe fn body treated as inherently unsafe"),
+            // `unsafe` blocks are required in safe code
+            (Safety::Safe, _) => {
                 for violation in violations {
-                    if !self.violations.contains(violation) {
-                        self.violations.push(violation.clone())
+                    let mut violation = violation.clone();
+                    match violation.kind {
+                        UnsafetyViolationKind::GeneralAndConstFn |
+                        UnsafetyViolationKind::General => {},
+                        UnsafetyViolationKind::BorrowPacked(_) |
+                        UnsafetyViolationKind::ExternStatic(_) => if self.min_const_fn {
+                            // const fns don't need to be backwards compatible and can
+                            // emit these violations as a hard error instead of a backwards
+                            // compat lint
+                            violation.kind = UnsafetyViolationKind::General;
+                        },
+                        UnsafetyViolationKind::GatedConstFnCall => {
+                            // safe code can't call unsafe const fns, this `UnsafetyViolationKind`
+                            // is only relevant for `Safety::ExplicitUnsafe` in `unsafe const fn`s
+                            violation.kind = UnsafetyViolationKind::General;
+                        }
+                    }
+                    if !self.violations.contains(&violation) {
+                        self.violations.push(violation)
                     }
                 }
                 false
             }
-            Safety::BuiltinUnsafe | Safety::FnUnsafe => true,
-            Safety::ExplicitUnsafe(node_id) => {
+            // regular `unsafe` function bodies allow unsafe without additional unsafe blocks
+            (Safety::BuiltinUnsafe, false) | (Safety::FnUnsafe, false) => true,
+            (Safety::ExplicitUnsafe(node_id), _) => {
+                // mark unsafe block as used if there are any unsafe operations inside
                 if !violations.is_empty() {
                     self.used_unsafe.insert(node_id);
                 }
+                // only some unsafety is allowed in const fn
+                if self.min_const_fn {
+                    let min_const_unsafe_fn = self.tcx.features().min_const_unsafe_fn;
+                    for violation in violations {
+                        match violation.kind {
+                            UnsafetyViolationKind::GatedConstFnCall if min_const_unsafe_fn => {
+                                // these function calls to unsafe functions are allowed
+                                // if `#![feature(min_const_unsafe_fn)]` is active
+                            },
+                            UnsafetyViolationKind::GatedConstFnCall => {
+                                // without the feature gate, we report errors
+                                if !self.violations.contains(&violation) {
+                                    self.violations.push(violation.clone())
+                                }
+                            }
+                            // these unsafe things are stable in const fn
+                            UnsafetyViolationKind::GeneralAndConstFn => {},
+                            // these things are forbidden in const fns
+                            UnsafetyViolationKind::General |
+                            UnsafetyViolationKind::BorrowPacked(_) |
+                            UnsafetyViolationKind::ExternStatic(_) => {
+                                let mut violation = violation.clone();
+                                // const fns don't need to be backwards compatible and can
+                                // emit these violations as a hard error instead of a backwards
+                                // compat lint
+                                violation.kind = UnsafetyViolationKind::General;
+                                if !self.violations.contains(&violation) {
+                                    self.violations.push(violation)
+                                }
+                            },
+                        }
+                    }
+                }
                 true
             }
         };
@@ -306,6 +389,53 @@
             (node_id, is_used && !within_unsafe)
         }));
     }
+    fn check_mut_borrowing_layout_constrained_field(
+        &mut self,
+        mut place: &Place<'tcx>,
+        is_mut_use: bool,
+    ) {
+        while let &Place::Projection(box Projection {
+            ref base, ref elem
+        }) = place {
+            match *elem {
+                ProjectionElem::Field(..) => {
+                    let ty = base.ty(&self.mir.local_decls, self.tcx).to_ty(self.tcx);
+                    match ty.sty {
+                        ty::Adt(def, _) => match self.tcx.layout_scalar_valid_range(def.did) {
+                            (Bound::Unbounded, Bound::Unbounded) => {},
+                            _ => {
+                                let (description, details) = if is_mut_use {
+                                    (
+                                        "mutation of layout constrained field",
+                                        "mutating layout constrained fields cannot statically be \
+                                        checked for valid values",
+                                    )
+                                } else {
+                                    (
+                                        "borrow of layout constrained field with interior \
+                                        mutability",
+                                        "references to fields of layout constrained fields \
+                                        lose the constraints. Coupled with interior mutability, \
+                                        the field can be changed to invalid values",
+                                    )
+                                };
+                                let source_info = self.source_info;
+                                self.register_violations(&[UnsafetyViolation {
+                                    source_info,
+                                    description: Symbol::intern(description).as_interned_str(),
+                                    details: Symbol::intern(details).as_interned_str(),
+                                    kind: UnsafetyViolationKind::GeneralAndConstFn,
+                                }], &[]);
+                            }
+                        },
+                        _ => {}
+                    }
+                }
+                _ => {}
+            }
+            place = base;
+        }
+    }
 }
 
 pub(crate) fn provide(providers: &mut Providers) {
@@ -384,7 +514,7 @@
 
     let param_env = tcx.param_env(def_id);
     let mut checker = UnsafetyChecker::new(
-        tcx.is_const_fn(def_id) && tcx.is_min_const_fn(def_id),
+        tcx.is_min_const_fn(def_id),
         mir, source_scope_local_data, tcx, param_env);
     checker.visit_mir(mir);
 
@@ -486,6 +616,22 @@
     } in violations.iter() {
         // Report an error.
         match kind {
+            UnsafetyViolationKind::General if tcx.is_min_const_fn(def_id) => {
+                let mut err = tcx.sess.struct_span_err(
+                    source_info.span,
+                    &format!("{} is unsafe and unsafe operations \
+                            are not allowed in const fn", description));
+                err.span_label(source_info.span, &description.as_str()[..])
+                    .note(&details.as_str()[..]);
+                if tcx.fn_sig(def_id).unsafety() == hir::Unsafety::Unsafe {
+                    err.note(
+                        "unsafe action within a `const unsafe fn` still require an `unsafe` \
+                        block in contrast to regular `unsafe fn`."
+                    );
+                }
+                err.emit();
+            }
+            UnsafetyViolationKind::GeneralAndConstFn |
             UnsafetyViolationKind::General => {
                 struct_span_err!(
                     tcx.sess, source_info.span, E0133,
@@ -494,14 +640,15 @@
                     .note(&details.as_str()[..])
                     .emit();
             }
-            UnsafetyViolationKind::MinConstFn => {
-                tcx.sess.struct_span_err(
+            UnsafetyViolationKind::GatedConstFnCall => {
+                emit_feature_err(
+                    &tcx.sess.parse_sess,
+                    "min_const_unsafe_fn",
                     source_info.span,
-                    &format!("{} is unsafe and unsafe operations \
-                            are not allowed in const fn", description))
-                    .span_label(source_info.span, &description.as_str()[..])
-                    .note(&details.as_str()[..])
-                    .emit();
+                    GateIssue::Language,
+                    "calls to `const unsafe fn` in const fns are unstable",
+                );
+
             }
             UnsafetyViolationKind::ExternStatic(lint_node_id) => {
                 tcx.lint_node_note(SAFE_EXTERN_STATICS,
diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs
index c0edd39..6d7fc40 100644
--- a/src/librustc_mir/transform/cleanup_post_borrowck.rs
+++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs
@@ -10,17 +10,25 @@
 
 //! This module provides two passes:
 //!
-//!   - [CleanAscribeUserType], that replaces all
-//!     [StatementKind::AscribeUserType] statements with [StatementKind::Nop].
-//!   - [CleanFakeReadsAndBorrows], that replaces all [FakeRead] statements and
-//!     borrows that are read by [FakeReadCause::ForMatchGuard] fake reads with
-//!     [StatementKind::Nop].
+//!   - [`CleanAscribeUserType`], that replaces all [`AscribeUserType`]
+//!     statements with [`Nop`].
+//!   - [`CleanFakeReadsAndBorrows`], that replaces all [`FakeRead`] statements
+//!     and borrows that are read by [`ForMatchGuard`] fake reads with [`Nop`].
 //!
-//! The [CleanFakeReadsAndBorrows] "pass" is actually implemented as two
+//! The `CleanFakeReadsAndBorrows` "pass" is actually implemented as two
 //! traversals (aka visits) of the input MIR. The first traversal,
-//! [DeleteAndRecordFakeReads], deletes the fake reads and finds the temporaries
-//! read by [ForMatchGuard] reads, and [DeleteFakeBorrows] deletes the
-//! initialization of those temporaries.
+//! [`DeleteAndRecordFakeReads`], deletes the fake reads and finds the
+//! temporaries read by [`ForMatchGuard`] reads, and [`DeleteFakeBorrows`]
+//! deletes the initialization of those temporaries.
+//!
+//! [`CleanAscribeUserType`]: cleanup_post_borrowck::CleanAscribeUserType
+//! [`CleanFakeReadsAndBorrows`]: cleanup_post_borrowck::CleanFakeReadsAndBorrows
+//! [`DeleteAndRecordFakeReads`]: cleanup_post_borrowck::DeleteAndRecordFakeReads
+//! [`DeleteFakeBorrows`]: cleanup_post_borrowck::DeleteFakeBorrows
+//! [`AscribeUserType`]: rustc::mir::StatementKind::AscribeUserType
+//! [`Nop`]: rustc::mir::StatementKind::Nop
+//! [`FakeRead`]: rustc::mir::StatementKind::FakeRead
+//! [`ForMatchGuard`]: rustc::mir::FakeReadCause::ForMatchGuard
 
 use rustc_data_structures::fx::FxHashSet;
 
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 1cce0de..ab71cef 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -707,8 +707,14 @@
         self.in_cleanup_block = false;
     }
 
-    fn visit_retag(&mut self, fn_entry: &mut bool, place: &mut Place<'tcx>, loc: Location) {
-        self.super_retag(fn_entry, place, loc);
+    fn visit_retag(
+        &mut self,
+        fn_entry: &mut bool,
+        two_phase: &mut bool,
+        place: &mut Place<'tcx>,
+        loc: Location,
+    ) {
+        self.super_retag(fn_entry, two_phase, place, loc);
 
         // We have to patch all inlined retags to be aware that they are no longer
         // happening on function entry.
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index fc2c6c3..bcee6d7 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -357,7 +357,7 @@
                 TerminatorKind::FalseUnwind { .. } => None,
 
                 TerminatorKind::Return => {
-                    if !self.tcx.sess.features_untracked().const_let {
+                    if !self.tcx.features().const_let {
                         // Check for unused values. This usually means
                         // there are extra statements in the AST.
                         for temp in mir.temps_iter() {
@@ -464,7 +464,7 @@
             LocalKind::ReturnPointer => {
                 self.not_const();
             }
-            LocalKind::Var if !self.tcx.sess.features_untracked().const_let => {
+            LocalKind::Var if !self.tcx.features().const_let => {
                 if self.mode != Mode::Fn {
                     emit_feature_err(&self.tcx.sess.parse_sess, "const_let",
                                     self.span, GateIssue::Language,
@@ -558,7 +558,7 @@
                                 Mode::Fn => {},
                                 _ => {
                                     if let ty::RawPtr(_) = base_ty.sty {
-                                        if !this.tcx.sess.features_untracked().const_raw_ptr_deref {
+                                        if !this.tcx.features().const_raw_ptr_deref {
                                             emit_feature_err(
                                                 &this.tcx.sess.parse_sess, "const_raw_ptr_deref",
                                                 this.span, GateIssue::Language,
@@ -581,7 +581,7 @@
                                     match this.mode {
                                         Mode::Fn => this.not_const(),
                                         Mode::ConstFn => {
-                                            if !this.tcx.sess.features_untracked().const_fn_union {
+                                            if !this.tcx.features().const_fn_union {
                                                 emit_feature_err(
                                                     &this.tcx.sess.parse_sess, "const_fn_union",
                                                     this.span, GateIssue::Language,
@@ -807,7 +807,7 @@
                         if let Mode::Fn = self.mode {
                             // in normal functions, mark such casts as not promotable
                             self.add(Qualif::NOT_CONST);
-                        } else if !self.tcx.sess.features_untracked().const_raw_ptr_to_usize_cast {
+                        } else if !self.tcx.features().const_raw_ptr_to_usize_cast {
                             // in const fn and constants require the feature gate
                             // FIXME: make it unsafe inside const fn and constants
                             emit_feature_err(
@@ -834,7 +834,7 @@
                     if let Mode::Fn = self.mode {
                         // raw pointer operations are not allowed inside promoteds
                         self.add(Qualif::NOT_CONST);
-                    } else if !self.tcx.sess.features_untracked().const_compare_raw_pointers {
+                    } else if !self.tcx.features().const_compare_raw_pointers {
                         // require the feature gate inside constants and const fn
                         // FIXME: make it unsafe to use these operations
                         emit_feature_err(
@@ -895,145 +895,160 @@
             let mut is_shuffle = false;
             let mut is_const_fn = false;
             let mut is_promotable_const_fn = false;
-            if let ty::FnDef(def_id, _) = fn_ty.sty {
-                callee_def_id = Some(def_id);
-                match self.tcx.fn_sig(def_id).abi() {
-                    Abi::RustIntrinsic |
-                    Abi::PlatformIntrinsic => {
-                        assert!(!self.tcx.is_const_fn(def_id));
-                        match &self.tcx.item_name(def_id).as_str()[..] {
-                            | "size_of"
-                            | "min_align_of"
-                            | "needs_drop"
-                            | "type_id"
-                            | "bswap"
-                            | "bitreverse"
-                            | "ctpop"
-                            | "cttz"
-                            | "cttz_nonzero"
-                            | "ctlz"
-                            | "ctlz_nonzero"
-                            | "overflowing_add"
-                            | "overflowing_sub"
-                            | "overflowing_mul"
-                            | "unchecked_shl"
-                            | "unchecked_shr"
-                            | "rotate_left"
-                            | "rotate_right"
-                            | "add_with_overflow"
-                            | "sub_with_overflow"
-                            | "mul_with_overflow"
-                            // no need to check feature gates, intrinsics are only callable from the
-                            // libstd or with forever unstable feature gates
-                            => is_const_fn = true,
-                            // special intrinsic that can be called diretly without an intrinsic
-                            // feature gate needs a language feature gate
-                            "transmute" => {
-                                // never promote transmute calls
-                                if self.mode != Mode::Fn {
-                                    is_const_fn = true;
-                                    // const eval transmute calls only with the feature gate
-                                    if !self.tcx.sess.features_untracked().const_transmute {
-                                        emit_feature_err(
-                                            &self.tcx.sess.parse_sess, "const_transmute",
-                                            self.span, GateIssue::Language,
-                                            &format!("The use of std::mem::transmute() \
-                                            is gated in {}s", self.mode));
+            match fn_ty.sty {
+                ty::FnDef(def_id, _) => {
+                    callee_def_id = Some(def_id);
+                    match self.tcx.fn_sig(def_id).abi() {
+                        Abi::RustIntrinsic |
+                        Abi::PlatformIntrinsic => {
+                            assert!(!self.tcx.is_const_fn(def_id));
+                            match &self.tcx.item_name(def_id).as_str()[..] {
+                                | "size_of"
+                                | "min_align_of"
+                                | "needs_drop"
+                                | "type_id"
+                                | "bswap"
+                                | "bitreverse"
+                                | "ctpop"
+                                | "cttz"
+                                | "cttz_nonzero"
+                                | "ctlz"
+                                | "ctlz_nonzero"
+                                | "overflowing_add"
+                                | "overflowing_sub"
+                                | "overflowing_mul"
+                                | "unchecked_shl"
+                                | "unchecked_shr"
+                                | "rotate_left"
+                                | "rotate_right"
+                                | "add_with_overflow"
+                                | "sub_with_overflow"
+                                | "mul_with_overflow"
+                                // no need to check feature gates, intrinsics are only callable
+                                // from the libstd or with forever unstable feature gates
+                                => is_const_fn = true,
+                                // special intrinsic that can be called diretly without an intrinsic
+                                // feature gate needs a language feature gate
+                                "transmute" => {
+                                    // never promote transmute calls
+                                    if self.mode != Mode::Fn {
+                                        is_const_fn = true;
+                                        // const eval transmute calls only with the feature gate
+                                        if !self.tcx.features().const_transmute {
+                                            emit_feature_err(
+                                                &self.tcx.sess.parse_sess, "const_transmute",
+                                                self.span, GateIssue::Language,
+                                                &format!("The use of std::mem::transmute() \
+                                                is gated in {}s", self.mode));
+                                        }
                                     }
                                 }
-                            }
 
-                            name if name.starts_with("simd_shuffle") => {
-                                is_shuffle = true;
-                            }
-
-                            _ => {}
-                        }
-                    }
-                    _ => {
-                        // in normal functions we only care about promotion
-                        if self.mode == Mode::Fn {
-                            // never promote const fn calls of
-                            // functions without #[rustc_promotable]
-                            if self.tcx.is_promotable_const_fn(def_id) {
-                                is_const_fn = true;
-                                is_promotable_const_fn = true;
-                            } else if self.tcx.is_const_fn(def_id) {
-                                is_const_fn = true;
-                            }
-                        } else {
-                            // stable const fn or unstable const fns with their feature gate
-                            // active
-                            if self.tcx.is_const_fn(def_id) {
-                                is_const_fn = true;
-                            } else if self.is_const_panic_fn(def_id) {
-                                // check the const_panic feature gate
-                                // FIXME: cannot allow this inside `allow_internal_unstable` because
-                                // that would make `panic!` insta stable in constants, since the
-                                // macro is marked with the attr
-                                if self.tcx.sess.features_untracked().const_panic {
-                                    is_const_fn = true;
-                                } else {
-                                    // don't allow panics in constants without the feature gate
-                                    emit_feature_err(
-                                        &self.tcx.sess.parse_sess,
-                                        "const_panic",
-                                        self.span,
-                                        GateIssue::Language,
-                                        &format!("panicking in {}s is unstable", self.mode),
-                                    );
+                                name if name.starts_with("simd_shuffle") => {
+                                    is_shuffle = true;
                                 }
-                            } else if let Some(feature) = self.tcx.is_unstable_const_fn(def_id) {
-                                // check `#[unstable]` const fns or `#[rustc_const_unstable]`
-                                // functions without the feature gate active in this crate to report
-                                // a better error message than the one below
-                                if self.span.allows_unstable() {
-                                    // `allow_internal_unstable` can make such calls stable
+
+                                _ => {}
+                            }
+                        }
+                        _ => {
+                            // in normal functions we only care about promotion
+                            if self.mode == Mode::Fn {
+                                // never promote const fn calls of
+                                // functions without #[rustc_promotable]
+                                if self.tcx.is_promotable_const_fn(def_id) {
                                     is_const_fn = true;
-                                } else {
-                                    let mut err = self.tcx.sess.struct_span_err(self.span,
-                                        &format!("`{}` is not yet stable as a const fn",
-                                                self.tcx.item_path_str(def_id)));
-                                    help!(&mut err,
-                                        "in Nightly builds, add `#![feature({})]` \
-                                        to the crate attributes to enable",
-                                        feature);
-                                    err.emit();
+                                    is_promotable_const_fn = true;
+                                } else if self.tcx.is_const_fn(def_id) {
+                                    is_const_fn = true;
                                 }
                             } else {
-                                // FIXME(#24111) Remove this check when const fn stabilizes
-                                let (msg, note) = if let UnstableFeatures::Disallow =
-                                        self.tcx.sess.opts.unstable_features {
-                                    (format!("calls in {}s are limited to \
-                                            tuple structs and tuple variants",
-                                            self.mode),
-                                    Some("a limited form of compile-time function \
-                                        evaluation is available on a nightly \
-                                        compiler via `const fn`"))
+                                // stable const fn or unstable const fns with their feature gate
+                                // active
+                                if self.tcx.is_const_fn(def_id) {
+                                    is_const_fn = true;
+                                } else if self.is_const_panic_fn(def_id) {
+                                    // check the const_panic feature gate
+                                    // FIXME: cannot allow this inside `allow_internal_unstable`
+                                    // because that would make `panic!` insta stable in constants,
+                                    // since the macro is marked with the attr
+                                    if self.tcx.features().const_panic {
+                                        is_const_fn = true;
+                                    } else {
+                                        // don't allow panics in constants without the feature gate
+                                        emit_feature_err(
+                                            &self.tcx.sess.parse_sess,
+                                            "const_panic",
+                                            self.span,
+                                            GateIssue::Language,
+                                            &format!("panicking in {}s is unstable", self.mode),
+                                        );
+                                    }
+                                } else if let Some(feat) = self.tcx.is_unstable_const_fn(def_id) {
+                                    // check `#[unstable]` const fns or `#[rustc_const_unstable]`
+                                    // functions without the feature gate active in this crate to
+                                    // report a better error message than the one below
+                                    if self.span.allows_unstable() {
+                                        // `allow_internal_unstable` can make such calls stable
+                                        is_const_fn = true;
+                                    } else {
+                                        let mut err = self.tcx.sess.struct_span_err(self.span,
+                                            &format!("`{}` is not yet stable as a const fn",
+                                                    self.tcx.item_path_str(def_id)));
+                                        help!(&mut err,
+                                            "in Nightly builds, add `#![feature({})]` \
+                                            to the crate attributes to enable",
+                                            feat);
+                                        err.emit();
+                                    }
                                 } else {
-                                    (format!("calls in {}s are limited \
-                                            to constant functions, \
-                                            tuple structs and tuple variants",
-                                            self.mode),
-                                    None)
-                                };
-                                let mut err = struct_span_err!(
-                                    self.tcx.sess,
-                                    self.span,
-                                    E0015,
-                                    "{}",
-                                    msg,
-                                );
-                                if let Some(note) = note {
-                                    err.span_note(self.span, note);
+                                    // FIXME(#24111) Remove this check when const fn stabilizes
+                                    let (msg, note) = if let UnstableFeatures::Disallow =
+                                            self.tcx.sess.opts.unstable_features {
+                                        (format!("calls in {}s are limited to \
+                                                tuple structs and tuple variants",
+                                                self.mode),
+                                        Some("a limited form of compile-time function \
+                                            evaluation is available on a nightly \
+                                            compiler via `const fn`"))
+                                    } else {
+                                        (format!("calls in {}s are limited \
+                                                to constant functions, \
+                                                tuple structs and tuple variants",
+                                                self.mode),
+                                        None)
+                                    };
+                                    let mut err = struct_span_err!(
+                                        self.tcx.sess,
+                                        self.span,
+                                        E0015,
+                                        "{}",
+                                        msg,
+                                    );
+                                    if let Some(note) = note {
+                                        err.span_note(self.span, note);
+                                    }
+                                    err.emit();
                                 }
-                                err.emit();
                             }
                         }
                     }
+                },
+                ty::FnPtr(_) => {
+                    if self.mode != Mode::Fn {
+                        let mut err = self.tcx.sess.struct_span_err(
+                            self.span,
+                            &format!("function pointers are not allowed in const fn"));
+                        err.emit();
+                    }
+                },
+                _ => {
+                    self.not_const();
+                    return
                 }
             }
 
+
             let constant_arguments = callee_def_id.and_then(|id| {
                 args_required_const(self.tcx, id)
             });
@@ -1158,7 +1173,7 @@
         if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) {
             if self.mir.local_kind(index) == LocalKind::Var &&
                self.const_fn_arg_vars.insert(index) &&
-               !self.tcx.sess.features_untracked().const_let {
+               !self.tcx.features().const_let {
 
                 // Direct use of an argument is permitted.
                 match *rvalue {
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index 13e134b..3c1b9db 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -2,6 +2,7 @@
 use rustc::hir;
 use rustc::mir::*;
 use rustc::ty::{self, Predicate, TyCtxt};
+use rustc_target::spec::abi;
 use std::borrow::Cow;
 use syntax_pos::Span;
 
@@ -338,19 +339,40 @@
         } => {
             let fn_ty = func.ty(mir, tcx);
             if let ty::FnDef(def_id, _) = fn_ty.sty {
-                if tcx.is_min_const_fn(def_id) {
-                    check_operand(tcx, mir, func, span)?;
 
-                    for arg in args {
-                        check_operand(tcx, mir, arg, span)?;
-                    }
-                    Ok(())
-                } else {
-                    Err((
+                // some intrinsics are waved through if called inside the
+                // standard library. Users never need to call them directly
+                match tcx.fn_sig(def_id).abi() {
+                    abi::Abi::RustIntrinsic => match &tcx.item_name(def_id).as_str()[..] {
+                        | "size_of"
+                        | "min_align_of"
+                        | "needs_drop"
+                        => {},
+                        _ => return Err((
+                            span,
+                            "can only call a curated list of intrinsics in `min_const_fn`".into(),
+                        )),
+                    },
+                    abi::Abi::Rust if tcx.is_min_const_fn(def_id) => {},
+                    abi::Abi::Rust => return Err((
                         span,
                         "can only call other `min_const_fn` within a `min_const_fn`".into(),
-                    ))
+                    )),
+                    abi => return Err((
+                        span,
+                        format!(
+                            "cannot call functions with `{}` abi in `min_const_fn`",
+                            abi,
+                        ).into(),
+                    )),
                 }
+
+                check_operand(tcx, mir, func, span)?;
+
+                for arg in args {
+                    check_operand(tcx, mir, arg, span)?;
+                }
+                Ok(())
             } else {
                 Err((span, "can only call other const fns within const fn".into()))
             }
diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs
index ae0483e..8566f84 100644
--- a/src/librustc_mir/util/borrowck_errors.rs
+++ b/src/librustc_mir/util/borrowck_errors.rs
@@ -261,6 +261,7 @@
         old_loan_span: Span,
         old_opt_via: &str,
         previous_end_span: Option<Span>,
+        second_borrow_desc: &str,
         o: Origin,
     ) -> DiagnosticBuilder<'cx> {
         let mut err = struct_span_err!(
@@ -274,7 +275,10 @@
             kind_new,
             OGN = o
         );
-        err.span_label(new_loan_span, format!("borrow occurs here{}", opt_via));
+        err.span_label(
+            new_loan_span,
+            format!("{}borrow occurs here{}", second_borrow_desc, opt_via),
+        );
         err.span_label(
             old_loan_span,
             format!("{} construction occurs here{}", container_name, old_opt_via),
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index c74492f..2d7e7d0 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -24,7 +24,7 @@
 use super::graphviz::write_mir_fn_graphviz;
 use transform::MirSource;
 
-const INDENT: &'static str = "    ";
+const INDENT: &str = "    ";
 /// Alignment for lining up comments following MIR statements
 pub(crate) const ALIGN: usize = 40;
 
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index fbd6f6e..6d9abbf 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -969,7 +969,7 @@
                             Some(poly_projection_predicate.skip_binder()
                                                           .projection_ty.trait_ref(self.tcx))
                         }
-                        ty::Predicate::TypeOutlives(..) => None,
+                        ty::Predicate::TypeOutlives(..) | ty::Predicate::RegionOutlives(..) => None,
                         _ => bug!("unexpected predicate: {:?}", predicate),
                     };
                     if let Some(trait_ref) = trait_ref {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 2966e9e..191e4e8 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -40,7 +40,7 @@
 use syntax::ext::base::Determinacy::Undetermined;
 use syntax::ext::hygiene::Mark;
 use syntax::ext::tt::macro_rules;
-use syntax::feature_gate::is_builtin_attr;
+use syntax::feature_gate::{is_builtin_attr, emit_feature_err, GateIssue};
 use syntax::parse::token::{self, Token};
 use syntax::std_inject::injected_crate_name;
 use syntax::symbol::keywords;
@@ -145,7 +145,7 @@
             }
             _ => None,
         }.map(|ctxt| Segment::from_ident(Ident::new(
-            keywords::CrateRoot.name(), use_tree.prefix.span.shrink_to_lo().with_ctxt(ctxt)
+            keywords::PathRoot.name(), use_tree.prefix.span.shrink_to_lo().with_ctxt(ctxt)
         )));
 
         let prefix = crate_root.into_iter().chain(prefix_iter).collect::<Vec<_>>();
@@ -153,18 +153,18 @@
 
         let empty_for_self = |prefix: &[Segment]| {
             prefix.is_empty() ||
-            prefix.len() == 1 && prefix[0].ident.name == keywords::CrateRoot.name()
+            prefix.len() == 1 && prefix[0].ident.name == keywords::PathRoot.name()
         };
         match use_tree.kind {
             ast::UseTreeKind::Simple(rename, ..) => {
-                let mut ident = use_tree.ident();
+                let mut ident = use_tree.ident().gensym_if_underscore();
                 let mut module_path = prefix;
                 let mut source = module_path.pop().unwrap();
                 let mut type_ns_only = false;
 
                 if nested {
                     // Correctly handle `self`
-                    if source.ident.name == keywords::SelfValue.name() {
+                    if source.ident.name == keywords::SelfLower.name() {
                         type_ns_only = true;
 
                         if empty_for_self(&module_path) {
@@ -185,7 +185,7 @@
                     }
                 } else {
                     // Disallow `self`
-                    if source.ident.name == keywords::SelfValue.name() {
+                    if source.ident.name == keywords::SelfLower.name() {
                         resolve_error(self,
                                       use_tree.span,
                                       ResolutionError::SelfImportsOnlyAllowedWithin);
@@ -205,7 +205,7 @@
                             // `crate_name` should not be interpreted as relative.
                             module_path.push(Segment {
                                 ident: Ident {
-                                    name: keywords::CrateRoot.name(),
+                                    name: keywords::PathRoot.name(),
                                     span: source.ident.span,
                                 },
                                 id: Some(self.session.next_node_id()),
@@ -230,13 +230,18 @@
                 }
 
                 let subclass = SingleImport {
-                    target: ident,
                     source: source.ident,
-                    result: PerNS {
+                    target: ident,
+                    source_bindings: PerNS {
                         type_ns: Cell::new(Err(Undetermined)),
                         value_ns: Cell::new(Err(Undetermined)),
                         macro_ns: Cell::new(Err(Undetermined)),
                     },
+                    target_bindings: PerNS {
+                        type_ns: Cell::new(None),
+                        value_ns: Cell::new(None),
+                        macro_ns: Cell::new(None),
+                    },
                     type_ns_only,
                 };
                 self.add_import_directive(
@@ -270,7 +275,7 @@
                 // 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(..) = use_tree.kind {
-                        if use_tree.ident().name == keywords::SelfValue.name() {
+                        if use_tree.ident().name == keywords::SelfLower.name() {
                             return Some(use_tree.span);
                         }
                     }
@@ -305,7 +310,7 @@
                     let new_span = prefix[prefix.len() - 1].ident.span;
                     let tree = ast::UseTree {
                         prefix: ast::Path::from_ident(
-                            Ident::new(keywords::SelfValue.name(), new_span)
+                            Ident::new(keywords::SelfLower.name(), new_span)
                         ),
                         kind: ast::UseTreeKind::Simple(
                             Some(Ident::new(keywords::Underscore.name().gensymed(), new_span)),
@@ -318,7 +323,7 @@
                         // This particular use tree
                         &tree, id, &prefix, true,
                         // The whole `use` item
-                        parent_scope.clone(), item, ty::Visibility::Invisible, root_span,
+                        parent_scope, item, ty::Visibility::Invisible, root_span,
                     );
                 }
             }
@@ -329,7 +334,7 @@
     fn build_reduced_graph_for_item(&mut self, item: &Item, parent_scope: ParentScope<'a>) {
         let parent = parent_scope.module;
         let expansion = parent_scope.expansion;
-        let ident = item.ident;
+        let ident = item.ident.gensym_if_underscore();
         let sp = item.span;
         let vis = self.resolve_visibility(&item.vis);
 
@@ -344,9 +349,23 @@
             }
 
             ItemKind::ExternCrate(orig_name) => {
-                let crate_id = self.crate_loader.process_extern_crate(item, &self.definitions);
-                let module =
-                    self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
+                let module = if orig_name.is_none() && ident.name == keywords::SelfLower.name() {
+                    self.session
+                        .struct_span_err(item.span, "`extern crate self;` requires renaming")
+                        .span_suggestion(item.span, "try", "extern crate self as name;".into())
+                        .emit();
+                    return;
+                } else if orig_name == Some(keywords::SelfLower.name()) {
+                    if !self.session.features_untracked().extern_crate_self {
+                        emit_feature_err(&self.session.parse_sess, "extern_crate_self", item.span,
+                                         GateIssue::Language, "`extern crate self` is unstable");
+                    }
+                    self.graph_root
+                } else {
+                    let crate_id = self.crate_loader.process_extern_crate(item, &self.definitions);
+                    self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
+                };
+
                 self.populate_module_if_necessary(module);
                 if injected_crate_name().map_or(false, |name| ident.name == name) {
                     self.injected_crate = Some(module);
@@ -609,7 +628,11 @@
 
     /// Builds the reduced graph for a single item in an external crate.
     fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, child: Export) {
-        let Export { ident, def, vis, span, .. } = child;
+        let Export { ident, def, vis, span } = child;
+        // FIXME: We shouldn't create the gensym here, it should come from metadata,
+        // but metadata cannot encode gensyms currently, so we create it here.
+        // This is only a guess, two equivalent idents may incorrectly get different gensyms here.
+        let ident = ident.gensym_if_underscore();
         let def_id = def.def_id();
         let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene
         match def {
@@ -768,6 +791,12 @@
                     span_err!(self.session, item.span, E0468,
                         "an `extern crate` loading macros must be at the crate root");
                 }
+                if let ItemKind::ExternCrate(Some(orig_name)) = item.node {
+                    if orig_name == keywords::SelfLower.name() {
+                        self.session.span_err(attr.span,
+                            "`macro_use` is not supported on `extern crate self`");
+                    }
+                }
                 let ill_formed = |span| span_err!(self.session, span, E0466, "bad macro import");
                 match attr.meta() {
                     Some(meta) => match meta.node {
diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs
index e2a6303..23edaf1 100644
--- a/src/librustc_resolve/error_reporting.rs
+++ b/src/librustc_resolve/error_reporting.rs
@@ -30,7 +30,7 @@
         match (path.get(0), path.get(1)) {
             // `{{root}}::ident::...` on both editions.
             // On 2015 `{{root}}` is usually added implicitly.
-            (Some(fst), Some(snd)) if fst.ident.name == keywords::CrateRoot.name() &&
+            (Some(fst), Some(snd)) if fst.ident.name == keywords::PathRoot.name() &&
                                       !snd.ident.is_path_segment_keyword() => {}
             // `ident::...` on 2018
             (Some(fst), _) if fst.ident.span.rust_2018() &&
@@ -61,7 +61,7 @@
         parent_scope: &ParentScope<'b>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `self` and check if that is valid.
-        path[0].ident.name = keywords::SelfValue.name();
+        path[0].ident.name = keywords::SelfLower.name();
         let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
         debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index cbf82a8..f314d57 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -769,7 +769,7 @@
                 self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
             }
             TyKind::ImplicitSelf => {
-                let self_ty = keywords::SelfType.ident();
+                let self_ty = keywords::SelfUpper.ident();
                 let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
                               .map_or(Def::Err, |d| d.def());
                 self.record_def(ty.id, PathResolution::new(def));
@@ -1519,8 +1519,12 @@
     /// The current self item if inside an ADT (used for better errors).
     current_self_item: Option<NodeId>,
 
-    /// FIXME: Refactor things so that this is passed through arguments and not resolver.
+    /// FIXME: Refactor things so that these fields are passed through arguments and not resolver.
+    /// We are resolving a last import segment during import validation.
     last_import_segment: bool,
+    /// This binding should be ignored during in-module resolution, so that we don't get
+    /// "self-confirming" import resolutions during import validation.
+    blacklisted_binding: Option<&'a NameBinding<'a>>,
 
     /// The idents for the primitive types.
     primitive_type_table: PrimitiveTypeTable,
@@ -1679,7 +1683,7 @@
         components: &[&str],
         is_value: bool
     ) -> hir::Path {
-        let segments = iter::once(keywords::CrateRoot.ident())
+        let segments = iter::once(keywords::PathRoot.ident())
             .chain(
                 crate_root.into_iter()
                     .chain(components.iter().cloned())
@@ -1721,7 +1725,7 @@
         let path = if path_str.starts_with("::") {
             ast::Path {
                 span,
-                segments: iter::once(keywords::CrateRoot.ident())
+                segments: iter::once(keywords::PathRoot.ident())
                     .chain({
                         path_str.split("::").skip(1).map(Ident::from_str)
                     })
@@ -1871,6 +1875,7 @@
             current_self_type: None,
             current_self_item: None,
             last_import_segment: false,
+            blacklisted_binding: None,
 
             primitive_type_table: PrimitiveTypeTable::new(),
 
@@ -2036,7 +2041,7 @@
         let record_used = record_used_id.is_some();
         assert!(ns == TypeNS  || ns == ValueNS);
         if ns == TypeNS {
-            ident.span = if ident.name == keywords::SelfType.name() {
+            ident.span = if ident.name == keywords::SelfUpper.name() {
                 // FIXME(jseyfried) improve `Self` hygiene
                 ident.span.with_ctxt(SyntaxContext::empty())
             } else {
@@ -2373,13 +2378,9 @@
         self.with_current_self_item(item, |this| {
             this.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
                 let item_def_id = this.definitions.local_def_id(item.id);
-                if this.session.features_untracked().self_in_typedefs {
-                    this.with_self_rib(Def::SelfTy(None, Some(item_def_id)), |this| {
-                        visit::walk_item(this, item);
-                    });
-                } else {
+                this.with_self_rib(Def::SelfTy(None, Some(item_def_id)), |this| {
                     visit::walk_item(this, item);
-                }
+                });
             });
         });
     }
@@ -2653,7 +2654,7 @@
         let mut self_type_rib = Rib::new(NormalRibKind);
 
         // plain insert (no renaming, types are not currently hygienic....)
-        self_type_rib.bindings.insert(keywords::SelfType.ident(), self_def);
+        self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_def);
         self.ribs[TypeNS].push(self_type_rib);
         f(self);
         self.ribs[TypeNS].pop();
@@ -2664,7 +2665,7 @@
     {
         let self_def = Def::SelfCtor(impl_id);
         let mut self_type_rib = Rib::new(NormalRibKind);
-        self_type_rib.bindings.insert(keywords::SelfType.ident(), self_def);
+        self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_def);
         self.ribs[ValueNS].push(self_type_rib);
         f(self);
         self.ribs[ValueNS].pop();
@@ -3150,7 +3151,7 @@
                 let item_span = path.last().unwrap().ident.span;
                 let (mod_prefix, mod_str) = if path.len() == 1 {
                     (String::new(), "this scope".to_string())
-                } else if path.len() == 2 && path[0].ident.name == keywords::CrateRoot.name() {
+                } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() {
                     (String::new(), "the crate root".to_string())
                 } else {
                     let mod_path = &path[..path.len() - 1];
@@ -3185,16 +3186,8 @@
             if is_self_type(path, ns) {
                 __diagnostic_used!(E0411);
                 err.code(DiagnosticId::Error("E0411".into()));
-                let available_in = if this.session.features_untracked().self_in_typedefs {
-                    "impls, traits, and type definitions"
-                } else {
-                    "traits and impls"
-                };
-                err.span_label(span, format!("`Self` is only available in {}", available_in));
-                if this.current_self_item.is_some() && nightly_options::is_nightly_build() {
-                    err.help("add #![feature(self_in_typedefs)] to the crate attributes \
-                              to enable");
-                }
+                err.span_label(span, format!("`Self` is only available in impls, traits, \
+                                              and type definitions"));
                 return (err, Vec::new());
             }
             if is_self_value(path, ns) {
@@ -3527,13 +3520,13 @@
     }
 
     fn self_type_is_available(&mut self, span: Span) -> bool {
-        let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(),
+        let binding = self.resolve_ident_in_lexical_scope(keywords::SelfUpper.ident(),
                                                           TypeNS, None, span);
         if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
     }
 
     fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool {
-        let ident = Ident::new(keywords::SelfValue.name(), self_span);
+        let ident = Ident::new(keywords::SelfLower.name(), self_span);
         let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, path_span);
         if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
     }
@@ -3685,7 +3678,7 @@
         };
 
         if path.len() > 1 && !global_by_default && result.base_def() != Def::Err &&
-           path[0].ident.name != keywords::CrateRoot.name() &&
+           path[0].ident.name != keywords::PathRoot.name() &&
            path[0].ident.name != keywords::DollarCrate.name() {
             let unqualified_result = {
                 match self.resolve_path_without_parent_scope(
@@ -3767,7 +3760,7 @@
             let name = ident.name;
 
             allow_super &= ns == TypeNS &&
-                (name == keywords::SelfValue.name() ||
+                (name == keywords::SelfLower.name() ||
                  name == keywords::Super.name());
 
             if ns == TypeNS {
@@ -3791,24 +3784,24 @@
                     return PathResult::Failed(ident.span, msg, false);
                 }
                 if i == 0 {
-                    if name == keywords::SelfValue.name() {
+                    if name == keywords::SelfLower.name() {
                         let mut ctxt = ident.span.ctxt().modern();
                         module = Some(ModuleOrUniformRoot::Module(
                             self.resolve_self(&mut ctxt, self.current_module)));
                         continue;
                     }
                     if name == keywords::Extern.name() ||
-                       name == keywords::CrateRoot.name() && ident.span.rust_2018() {
+                       name == keywords::PathRoot.name() && ident.span.rust_2018() {
                         module = Some(ModuleOrUniformRoot::ExternPrelude);
                         continue;
                     }
-                    if name == keywords::CrateRoot.name() &&
+                    if name == keywords::PathRoot.name() &&
                        ident.span.rust_2015() && self.session.rust_2018() {
                         // `::a::b` from 2015 macro on 2018 global edition
                         module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude);
                         continue;
                     }
-                    if name == keywords::CrateRoot.name() ||
+                    if name == keywords::PathRoot.name() ||
                        name == keywords::Crate.name() ||
                        name == keywords::DollarCrate.name() {
                         // `::a::b`, `crate::a::b` or `$crate::a::b`
@@ -3821,12 +3814,12 @@
 
             // Report special messages for path segment keywords in wrong positions.
             if ident.is_path_segment_keyword() && i != 0 {
-                let name_str = if name == keywords::CrateRoot.name() {
+                let name_str = if name == keywords::PathRoot.name() {
                     "crate root".to_string()
                 } else {
                     format!("`{}`", name)
                 };
-                let msg = if i == 1 && path[0].ident.name == keywords::CrateRoot.name() {
+                let msg = if i == 1 && path[0].ident.name == keywords::PathRoot.name() {
                     format!("global paths cannot start with {}", name_str)
                 } else {
                     format!("{} in paths can only be used in start position", name_str)
@@ -3950,13 +3943,13 @@
 
         let first_name = match path.get(0) {
             // In the 2018 edition this lint is a hard error, so nothing to do
-            Some(seg) if seg.ident.span.rust_2015() => seg.ident.name,
+            Some(seg) if seg.ident.span.rust_2015() && self.session.rust_2015() => seg.ident.name,
             _ => return,
         };
 
         // We're only interested in `use` paths which should start with
         // `{{root}}` or `extern` currently.
-        if first_name != keywords::Extern.name() && first_name != keywords::CrateRoot.name() {
+        if first_name != keywords::Extern.name() && first_name != keywords::PathRoot.name() {
             return
         }
 
@@ -3965,7 +3958,7 @@
             Some(Segment { ident, .. }) if ident.name == keywords::Crate.name() => return,
             // Otherwise go below to see if it's an extern crate
             Some(_) => {}
-            // If the path has length one (and it's `CrateRoot` most likely)
+            // If the path has length one (and it's `PathRoot` most likely)
             // then we don't know whether we're gonna be importing a crate or an
             // item in our crate. Defer this lint to elsewhere
             None => return,
@@ -4752,7 +4745,7 @@
                 } else {
                     let ctxt = ident.span.ctxt();
                     Some(Segment::from_ident(Ident::new(
-                        keywords::CrateRoot.name(), path.span.shrink_to_lo().with_ctxt(ctxt)
+                        keywords::PathRoot.name(), path.span.shrink_to_lo().with_ctxt(ctxt)
                     )))
                 };
 
@@ -5102,17 +5095,17 @@
 }
 
 fn is_self_type(path: &[Segment], namespace: Namespace) -> bool {
-    namespace == TypeNS && path.len() == 1 && path[0].ident.name == keywords::SelfType.name()
+    namespace == TypeNS && path.len() == 1 && path[0].ident.name == keywords::SelfUpper.name()
 }
 
 fn is_self_value(path: &[Segment], namespace: Namespace) -> bool {
-    namespace == ValueNS && path.len() == 1 && path[0].ident.name == keywords::SelfValue.name()
+    namespace == ValueNS && path.len() == 1 && path[0].ident.name == keywords::SelfLower.name()
 }
 
 fn names_to_string(idents: &[Ident]) -> String {
     let mut result = String::new();
     for (i, ident) in idents.iter()
-                            .filter(|ident| ident.name != keywords::CrateRoot.name())
+                            .filter(|ident| ident.name != keywords::PathRoot.name())
                             .enumerate() {
         if i > 0 {
             result.push_str("::");
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 5db3efe..7deefc7 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -167,7 +167,7 @@
 
                 if path.segments[0].ident.name == keywords::DollarCrate.name() {
                     let module = self.0.resolve_crate_root(path.segments[0].ident);
-                    path.segments[0].ident.name = keywords::CrateRoot.name();
+                    path.segments[0].ident.name = keywords::PathRoot.name();
                     if !module.is_local() {
                         let span = path.segments[0].ident.span;
                         path.segments.insert(1, match module.kind {
@@ -674,7 +674,7 @@
                     _ => Err(Determinacy::Determined),
                 }
                 WhereToResolve::CrateRoot => {
-                    let root_ident = Ident::new(keywords::CrateRoot.name(), orig_ident.span);
+                    let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span);
                     let root_module = self.resolve_crate_root(root_ident);
                     let binding = self.resolve_ident_in_module_ext(
                         ModuleOrUniformRoot::Module(root_module),
@@ -960,7 +960,7 @@
                     break 'ok;
                 }
                 if rust_2015 {
-                    let root_ident = Ident::new(keywords::CrateRoot.name(), orig_ident.span);
+                    let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span);
                     let root_module = self.resolve_crate_root(root_ident);
                     if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module),
                                                         orig_ident, ns, None, false, path_span)
@@ -977,12 +977,14 @@
                 let what = self.binding_description(binding, ident,
                                                     flags.contains(Flags::MISC_FROM_PRELUDE));
                 let note_msg = format!("this import refers to {what}", what = what);
-                if binding.span.is_dummy() {
+                let label_span = if binding.span.is_dummy() {
                     err.note(&note_msg);
+                    ident.span
                 } else {
                     err.span_note(binding.span, &note_msg);
-                    err.span_label(binding.span, "not an extern crate passed with `--extern`");
-                }
+                    binding.span
+                };
+                err.span_label(label_span, "not an extern crate passed with `--extern`");
                 err.emit();
             }
 
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index e7cd32f..36b6b52 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -42,9 +42,15 @@
 #[derive(Clone, Debug)]
 pub enum ImportDirectiveSubclass<'a> {
     SingleImport {
-        target: Ident,
+        /// `source` in `use prefix::source as target`.
         source: Ident,
-        result: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
+        /// `target` in `use prefix::source as target`.
+        target: Ident,
+        /// Bindings to which `source` refers to.
+        source_bindings: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
+        /// Bindings introduced by `target`.
+        target_bindings: PerNS<Cell<Option<&'a NameBinding<'a>>>>,
+        /// `true` for `...::{self [as target]}` imports, `false` otherwise.
         type_ns_only: bool,
     },
     GlobImport {
@@ -198,7 +204,7 @@
                                         .to_name_binding(self.arenas);
                         return Ok(binding);
                     } else if ident.name == keywords::Super.name() ||
-                                ident.name == keywords::SelfValue.name() {
+                                ident.name == keywords::SelfLower.name() {
                         // FIXME: Implement these with renaming requirements so that e.g.
                         // `use super;` doesn't work, but `use super as name;` does.
                         // Fall through here to get an error from `early_resolve_...`.
@@ -227,6 +233,11 @@
         }
 
         let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
+            if let Some(blacklisted_binding) = this.blacklisted_binding {
+                if ptr::eq(binding, blacklisted_binding) {
+                    return Err((Determined, Weak::No));
+                }
+            }
             // `extern crate` are always usable for backwards compatibility, see issue #37020,
             // remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
             let usable = this.is_accessible(binding.vis) || binding.is_extern_crate();
@@ -642,10 +653,10 @@
             if let Some((span, err, note)) = self.finalize_import(import) {
                 errors = true;
 
-                if let SingleImport { source, ref result, .. } = import.subclass {
+                if let SingleImport { source, ref source_bindings, .. } = import.subclass {
                     if source.name == "self" {
                         // Silence `unresolved import` error if E0429 is already emitted
-                        if let Err(Determined) = result.value_ns.get() {
+                        if let Err(Determined) = source_bindings.value_ns.get() {
                             continue;
                         }
                     }
@@ -765,9 +776,11 @@
         };
 
         directive.imported_module.set(Some(module));
-        let (source, target, result, type_ns_only) = match directive.subclass {
-            SingleImport { source, target, ref result, type_ns_only } =>
-                (source, target, result, type_ns_only),
+        let (source, target, source_bindings, target_bindings, type_ns_only) =
+                match directive.subclass {
+            SingleImport { source, target, ref source_bindings,
+                           ref target_bindings, type_ns_only } =>
+                (source, target, source_bindings, target_bindings, type_ns_only),
             GlobImport { .. } => {
                 self.resolve_glob_import(directive);
                 return true;
@@ -777,7 +790,7 @@
 
         let mut indeterminate = false;
         self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
-            if let Err(Undetermined) = result[ns].get() {
+            if let Err(Undetermined) = source_bindings[ns].get() {
                 // For better failure detection, pretend that the import will
                 // not define any names while resolving its module path.
                 let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
@@ -786,13 +799,13 @@
                 );
                 directive.vis.set(orig_vis);
 
-                result[ns].set(binding);
+                source_bindings[ns].set(binding);
             } else {
                 return
             };
 
             let parent = directive.parent_scope.module;
-            match result[ns].get() {
+            match source_bindings[ns].get() {
                 Err(Undetermined) => indeterminate = true,
                 Err(Determined) => {
                     this.update_resolution(parent, target, ns, |_, resolution| {
@@ -810,6 +823,7 @@
                 }
                 Ok(binding) => {
                     let imported_binding = this.import(binding, directive);
+                    target_bindings[ns].set(Some(imported_binding));
                     let conflict = this.try_define(parent, target, ns, imported_binding);
                     if let Err(old_binding) = conflict {
                         this.report_conflict(parent, target, ns, imported_binding, old_binding);
@@ -879,8 +893,11 @@
             PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(),
         };
 
-        let (ident, result, type_ns_only) = match directive.subclass {
-            SingleImport { source, ref result, type_ns_only, .. } => (source, result, type_ns_only),
+        let (ident, target, source_bindings, target_bindings, type_ns_only) =
+                match directive.subclass {
+            SingleImport { source, target, ref source_bindings,
+                           ref target_bindings, type_ns_only } =>
+                (source, target, source_bindings, target_bindings, type_ns_only),
             GlobImport { is_prelude, ref max_vis } => {
                 if directive.module_path.len() <= 1 {
                     // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
@@ -919,20 +936,28 @@
         let mut all_ns_err = true;
         self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
             let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
+            let orig_blacklisted_binding =
+                mem::replace(&mut this.blacklisted_binding, target_bindings[ns].get());
             let orig_last_import_segment = mem::replace(&mut this.last_import_segment, true);
             let binding = this.resolve_ident_in_module(
                 module, ident, ns, Some(&directive.parent_scope), true, directive.span
             );
             this.last_import_segment = orig_last_import_segment;
+            this.blacklisted_binding = orig_blacklisted_binding;
             directive.vis.set(orig_vis);
 
             match binding {
                 Ok(binding) => {
                     // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
-                    let initial_def = result[ns].get().map(|initial_binding| {
+                    let initial_def = source_bindings[ns].get().map(|initial_binding| {
                         all_ns_err = false;
-                        this.record_use(ident, ns, initial_binding,
-                                        directive.module_path.is_empty());
+                        if let Some(target_binding) = target_bindings[ns].get() {
+                            if target.name == "_" &&
+                               initial_binding.is_extern_crate() && !initial_binding.is_import() {
+                                this.record_use(ident, ns, target_binding,
+                                                directive.module_path.is_empty());
+                            }
+                        }
                         initial_binding.def_ignoring_ambiguity()
                     });
                     let def = binding.def_ignoring_ambiguity();
@@ -1034,7 +1059,7 @@
         let mut reexport_error = None;
         let mut any_successful_reexport = false;
         self.per_ns(|this, ns| {
-            if let Ok(binding) = result[ns].get() {
+            if let Ok(binding) = source_bindings[ns].get() {
                 let vis = directive.vis.get();
                 if !binding.pseudo_vis().is_at_least(vis, &*this) {
                     reexport_error = Some((ns, binding));
@@ -1078,7 +1103,7 @@
             let mut full_path = directive.module_path.clone();
             full_path.push(Segment::from_ident(ident));
             self.per_ns(|this, ns| {
-                if let Ok(binding) = result[ns].get() {
+                if let Ok(binding) = source_bindings[ns].get() {
                     this.lint_if_path_starts_with_module(
                         directive.crate_lint(),
                         &full_path,
@@ -1092,7 +1117,7 @@
         // Record what this import resolves to for later uses in documentation,
         // this may resolve to either a value or a type, but for documentation
         // purposes it's good enough to just favor one over the other.
-        self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() {
+        self.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
             let mut def = binding.def();
             if let Def::Macro(def_id, _) = def {
                 // `DefId`s from the "built-in macro crate" should not leak from resolve because
@@ -1263,8 +1288,8 @@
                          subclass: &ImportDirectiveSubclass,
                          span: Span) -> String {
     let pos = names.iter()
-        .position(|p| span == p.span && p.name != keywords::CrateRoot.name());
-    let global = !names.is_empty() && names[0].name == keywords::CrateRoot.name();
+        .position(|p| span == p.span && p.name != keywords::PathRoot.name());
+    let global = !names.is_empty() && names[0].name == keywords::PathRoot.name();
     if let Some(pos) = pos {
         let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] };
         names_to_string(names)
diff --git a/src/librustc_target/README.md b/src/librustc_target/README.md
index f5b1acb..a22000e 100644
--- a/src/librustc_target/README.md
+++ b/src/librustc_target/README.md
@@ -3,4 +3,4 @@
 
 For more information about how rustc works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
+[rustc guide]: https://rust-lang.github.io/rustc-guide/
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 3285ccf..5830fa0 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -234,7 +234,7 @@
         $(mod $module;)*
 
         /// List of supported targets
-        const TARGETS: &'static [&'static str] = &[$($triple),*];
+        const TARGETS: &[&str] = &[$($triple),*];
 
         fn load_specific(target: &str) -> TargetResult {
             match target {
@@ -399,6 +399,7 @@
     ("thumbv7m-none-eabi", thumbv7m_none_eabi),
     ("thumbv7em-none-eabi", thumbv7em_none_eabi),
     ("thumbv7em-none-eabihf", thumbv7em_none_eabihf),
+    ("thumbv8m.base-none-eabi", thumbv8m_base_none_eabi),
 
     ("msp430-none-elf", msp430_none_elf),
 
@@ -995,7 +996,7 @@
 
         key!(is_builtin, bool);
         key!(linker, optional);
-        try!(key!(lld_flavor, LldFlavor));
+        key!(lld_flavor, LldFlavor)?;
         key!(pre_link_args, link_args);
         key!(pre_link_args_crt, link_args);
         key!(pre_link_objects_exe, list);
@@ -1038,7 +1039,7 @@
         key!(no_default_libraries, bool);
         key!(position_independent_executables, bool);
         key!(needs_plt, bool);
-        try!(key!(relro_level, RelroLevel));
+        key!(relro_level, RelroLevel)?;
         key!(archive_format);
         key!(allow_asm, bool);
         key!(custom_unwind_resume, bool);
@@ -1048,7 +1049,7 @@
         key!(max_atomic_width, Option<u64>);
         key!(min_atomic_width, Option<u64>);
         key!(atomic_cas, bool);
-        try!(key!(panic_strategy, PanicStrategy));
+        key!(panic_strategy, PanicStrategy)?;
         key!(crt_static_allows_dylibs, bool);
         key!(crt_static_default, bool);
         key!(crt_static_respected, bool);
diff --git a/src/librustc_target/spec/thumb_base.rs b/src/librustc_target/spec/thumb_base.rs
index 4c9a476..22e5f49 100644
--- a/src/librustc_target/spec/thumb_base.rs
+++ b/src/librustc_target/spec/thumb_base.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// These 4 `thumbv*` targets cover the ARM Cortex-M family of processors which are widely used in
+// These `thumbv*` targets cover the ARM Cortex-M family of processors which are widely used in
 // microcontrollers. Namely, all these processors:
 //
 // - Cortex-M0
@@ -17,8 +17,9 @@
 // - Cortex-M3
 // - Cortex-M4(F)
 // - Cortex-M7(F)
+// - Cortex-M23
 //
-// We have opted for 4 targets instead of one target per processor (e.g. `cortex-m0`, `cortex-m3`,
+// We have opted for these instead of one target per processor (e.g. `cortex-m0`, `cortex-m3`,
 // etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost
 // non-existent from the POV of codegen so it doesn't make sense to have separate targets for them.
 // And if differences exist between two processors under the same target, rustc flags can be used to
diff --git a/src/librustc_target/spec/thumbv8m_base_none_eabi.rs b/src/librustc_target/spec/thumbv8m_base_none_eabi.rs
new file mode 100644
index 0000000..b614371
--- /dev/null
+++ b/src/librustc_target/spec/thumbv8m_base_none_eabi.rs
@@ -0,0 +1,36 @@
+// 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.
+
+// Targets the Cortex-M23 processor (Baseline ARMv8-M)
+
+use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "thumbv8m.base-none-eabi".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "none".to_string(),
+        target_env: String::new(),
+        target_vendor: String::new(),
+        linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
+
+        options: TargetOptions {
+            // ARMv8-M baseline doesn't support unaligned loads/stores so we disable them
+            // with +strict-align.
+            features: "+strict-align".to_string(),
+            max_atomic_width: Some(32),
+            .. super::thumb_base::opts()
+        },
+    })
+}
diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs
index 25a6af2..58a8d2a 100644
--- a/src/librustc_traits/chalk_context/mod.rs
+++ b/src/librustc_traits/chalk_context/mod.rs
@@ -9,13 +9,25 @@
 // except according to those terms.
 
 mod program_clauses;
+mod resolvent_ops;
+mod unify;
 
-use chalk_engine::fallible::Fallible as ChalkEngineFallible;
-use chalk_engine::{context, hh::HhGoal, DelayedLiteral, Literal, ExClause};
-use rustc::infer::canonical::{
-    Canonical, CanonicalVarValues, OriginalQueryValues, QueryRegionConstraint, QueryResponse,
+use chalk_engine::fallible::{Fallible, NoSolution};
+use chalk_engine::{
+    context,
+    hh::HhGoal,
+    DelayedLiteral,
+    Literal,
+    ExClause
 };
-use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
+use rustc::infer::{InferCtxt, LateBoundRegionConversionTime};
+use rustc::infer::canonical::{
+    Canonical,
+    CanonicalVarValues,
+    OriginalQueryValues,
+    QueryResponse,
+    Certainty,
+};
 use rustc::traits::{
     DomainGoal,
     ExClauseFold,
@@ -27,14 +39,15 @@
     Environment,
     InEnvironment,
 };
+use rustc::ty::{self, TyCtxt};
 use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use rustc::ty::subst::{Kind, UnpackedKind};
-use rustc::ty::{self, TyCtxt};
+use syntax_pos::DUMMY_SP;
 
 use std::fmt::{self, Debug};
 use std::marker::PhantomData;
 
-use syntax_pos::DUMMY_SP;
+use self::unify::*;
 
 #[derive(Copy, Clone, Debug)]
 crate struct ChalkArenas<'gcx> {
@@ -55,10 +68,12 @@
 #[derive(Copy, Clone, Debug)]
 crate struct UniverseMap;
 
+crate type RegionConstraint<'tcx> = ty::OutlivesPredicate<Kind<'tcx>, ty::Region<'tcx>>;
+
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
 crate struct ConstrainedSubst<'tcx> {
     subst: CanonicalVarValues<'tcx>,
-    constraints: Vec<QueryRegionConstraint<'tcx>>,
+    constraints: Vec<RegionConstraint<'tcx>>,
 }
 
 BraceStructTypeFoldableImpl! {
@@ -86,7 +101,7 @@
 
     type GoalInEnvironment = InEnvironment<'tcx, Goal<'tcx>>;
 
-    type RegionConstraint = QueryRegionConstraint<'tcx>;
+    type RegionConstraint = RegionConstraint<'tcx>;
 
     type Substitution = CanonicalVarValues<'tcx>;
 
@@ -104,7 +119,7 @@
 
     type ProgramClauses = Vec<Clause<'tcx>>;
 
-    type UnificationResult = InferOk<'tcx, ()>;
+    type UnificationResult = UnificationResult<'tcx>;
 
     fn goal_in_environment(
         env: &Environment<'tcx>,
@@ -118,9 +133,34 @@
     fn make_solution(
         &self,
         _root_goal: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>,
-        _simplified_answers: impl context::AnswerStream<ChalkArenas<'gcx>>,
+        mut simplified_answers: impl context::AnswerStream<ChalkArenas<'gcx>>,
     ) -> Option<Canonical<'gcx, QueryResponse<'gcx, ()>>> {
-        unimplemented!()
+        use chalk_engine::SimplifiedAnswer;
+
+        if simplified_answers.peek_answer().is_none() {
+            return None;
+        }
+
+        let SimplifiedAnswer { subst, ambiguous } = simplified_answers
+            .next_answer()
+            .unwrap();
+
+        let ambiguous = simplified_answers.peek_answer().is_some() || ambiguous;
+
+        Some(subst.unchecked_map(|subst| {
+            QueryResponse {
+                var_values: subst.subst,
+                region_constraints: subst.constraints
+                    .into_iter()
+                    .map(|c| ty::Binder::bind(c))
+                    .collect(),
+                certainty: match ambiguous {
+                    true => Certainty::Ambiguous,
+                    false => Certainty::Proven,
+                },
+                value: (),
+            }
+        }))
     }
 }
 
@@ -197,7 +237,7 @@
 
     fn is_trivial_substitution(
         u_canon: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>,
-        canonical_subst: &Canonical<'tcx, ConstrainedSubst<'tcx>>,
+        canonical_subst: &Canonical<'gcx, ConstrainedSubst<'gcx>>,
     ) -> bool {
         let subst = &canonical_subst.value.subst;
         assert_eq!(u_canon.variables.len(), subst.var_values.len());
@@ -282,30 +322,6 @@
     }
 }
 
-impl context::ResolventOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
-    for ChalkInferenceContext<'cx, 'gcx, 'tcx>
-{
-    fn resolvent_clause(
-        &mut self,
-        _environment: &Environment<'tcx>,
-        _goal: &DomainGoal<'tcx>,
-        _subst: &CanonicalVarValues<'tcx>,
-        _clause: &Clause<'tcx>,
-    ) -> chalk_engine::fallible::Fallible<Canonical<'gcx, ChalkExClause<'gcx>>> {
-        panic!()
-    }
-
-    fn apply_answer_subst(
-        &mut self,
-        _ex_clause: ChalkExClause<'tcx>,
-        _selected_goal: &InEnvironment<'tcx, Goal<'tcx>>,
-        _answer_table_goal: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>,
-        _canonical_answer_subst: &Canonical<'gcx, ConstrainedSubst<'gcx>>,
-    ) -> chalk_engine::fallible::Fallible<ChalkExClause<'tcx>> {
-        panic!()
-    }
-}
-
 impl context::TruncateOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
     for ChalkInferenceContext<'cx, 'gcx, 'tcx>
 {
@@ -376,7 +392,7 @@
     fn canonicalize_constrained_subst(
         &mut self,
         subst: CanonicalVarValues<'tcx>,
-        constraints: Vec<QueryRegionConstraint<'tcx>>,
+        constraints: Vec<RegionConstraint<'tcx>>,
     ) -> Canonical<'gcx, ConstrainedSubst<'gcx>> {
         self.infcx.canonicalize_response(&ConstrainedSubst { subst, constraints })
     }
@@ -400,11 +416,13 @@
 
     fn unify_parameters(
         &mut self,
-        _environment: &Environment<'tcx>,
-        _a: &Kind<'tcx>,
-        _b: &Kind<'tcx>,
-    ) -> ChalkEngineFallible<InferOk<'tcx, ()>> {
-        panic!()
+        environment: &Environment<'tcx>,
+        a: &Kind<'tcx>,
+        b: &Kind<'tcx>,
+    ) -> Fallible<UnificationResult<'tcx>> {
+        self.infcx.commit_if_ok(|_| {
+            unify(self.infcx, *environment, a, b).map_err(|_| NoSolution)
+        })
     }
 
     fn sink_answer_subset(
@@ -421,11 +439,22 @@
         panic!("lift")
     }
 
-    fn into_ex_clause(&mut self, _result: InferOk<'tcx, ()>, _ex_clause: &mut ChalkExClause<'tcx>) {
-        panic!("TBD")
+    fn into_ex_clause(
+        &mut self,
+        result: UnificationResult<'tcx>,
+        ex_clause: &mut ChalkExClause<'tcx>
+    ) {
+        into_ex_clause(result, ex_clause);
     }
 }
 
+crate fn into_ex_clause(result: UnificationResult<'tcx>, ex_clause: &mut ChalkExClause<'tcx>) {
+    ex_clause.subgoals.extend(
+        result.goals.into_iter().map(Literal::Positive)
+    );
+    ex_clause.constraints.extend(result.constraints);
+}
+
 type ChalkHhGoal<'tcx> = HhGoal<ChalkArenas<'tcx>>;
 
 type ChalkExClause<'tcx> = ExClause<ChalkArenas<'tcx>>;
diff --git a/src/librustc_traits/chalk_context/resolvent_ops.rs b/src/librustc_traits/chalk_context/resolvent_ops.rs
new file mode 100644
index 0000000..df6458a
--- /dev/null
+++ b/src/librustc_traits/chalk_context/resolvent_ops.rs
@@ -0,0 +1,241 @@
+use chalk_engine::fallible::{Fallible, NoSolution};
+use chalk_engine::{
+    context,
+    Literal,
+    ExClause
+};
+use rustc::infer::{InferCtxt, LateBoundRegionConversionTime};
+use rustc::infer::canonical::{Canonical, CanonicalVarValues};
+use rustc::traits::{
+    DomainGoal,
+    Goal,
+    GoalKind,
+    Clause,
+    ProgramClause,
+    Environment,
+    InEnvironment,
+};
+use rustc::ty::{self, Ty};
+use rustc::ty::subst::Kind;
+use rustc::ty::relate::{Relate, RelateResult, TypeRelation};
+use syntax_pos::DUMMY_SP;
+
+use super::{ChalkInferenceContext, ChalkArenas, ChalkExClause, ConstrainedSubst};
+use super::unify::*;
+
+impl context::ResolventOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
+    for ChalkInferenceContext<'cx, 'gcx, 'tcx>
+{
+    fn resolvent_clause(
+        &mut self,
+        environment: &Environment<'tcx>,
+        goal: &DomainGoal<'tcx>,
+        subst: &CanonicalVarValues<'tcx>,
+        clause: &Clause<'tcx>,
+    ) -> Fallible<Canonical<'gcx, ChalkExClause<'gcx>>> {
+        use chalk_engine::context::UnificationOps;
+
+        self.infcx.probe(|_| {
+            let ProgramClause {
+                goal: consequence,
+                hypotheses,
+                ..
+            } = match clause {
+                Clause::Implies(program_clause) => *program_clause,
+                Clause::ForAll(program_clause) => self.infcx.replace_bound_vars_with_fresh_vars(
+                    DUMMY_SP,
+                    LateBoundRegionConversionTime::HigherRankedType,
+                    program_clause
+                ).0,
+            };
+
+            let result = unify(self.infcx, *environment, goal, &consequence)
+                .map_err(|_| NoSolution)?;
+
+            let mut ex_clause = ExClause {
+                subst: subst.clone(),
+                delayed_literals: vec![],
+                constraints: vec![],
+                subgoals: vec![],
+            };
+
+            self.into_ex_clause(result, &mut ex_clause);
+
+            ex_clause.subgoals.extend(
+                hypotheses.iter().map(|g| match g {
+                    GoalKind::Not(g) => Literal::Negative(environment.with(*g)),
+                    g => Literal::Positive(environment.with(*g)),
+                })
+            );
+
+            let canonical_ex_clause = self.canonicalize_ex_clause(&ex_clause);
+            Ok(canonical_ex_clause)
+        })
+    }
+
+    fn apply_answer_subst(
+        &mut self,
+        ex_clause: ChalkExClause<'tcx>,
+        selected_goal: &InEnvironment<'tcx, Goal<'tcx>>,
+        answer_table_goal: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>,
+        canonical_answer_subst: &Canonical<'gcx, ConstrainedSubst<'gcx>>,
+    ) -> Fallible<ChalkExClause<'tcx>> {
+        let (answer_subst, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(
+            DUMMY_SP,
+            canonical_answer_subst
+        );
+
+        let mut substitutor = AnswerSubstitutor {
+            infcx: self.infcx,
+            environment: selected_goal.environment,
+            answer_subst: answer_subst.subst,
+            binder_index: ty::INNERMOST,
+            ex_clause,
+        };
+
+        substitutor.relate(&answer_table_goal.value, &selected_goal)
+            .map_err(|_| NoSolution)?;
+
+        let mut ex_clause = substitutor.ex_clause;
+        ex_clause.constraints.extend(answer_subst.constraints);
+        Ok(ex_clause)
+    }
+}
+
+struct AnswerSubstitutor<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
+    infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
+    environment: Environment<'tcx>,
+    answer_subst: CanonicalVarValues<'tcx>,
+    binder_index: ty::DebruijnIndex,
+    ex_clause: ChalkExClause<'tcx>,
+}
+
+impl AnswerSubstitutor<'cx, 'gcx, 'tcx> {
+    fn unify_free_answer_var(
+        &mut self,
+        answer_var: ty::BoundVar,
+        pending: Kind<'tcx>
+    ) -> RelateResult<'tcx, ()> {
+        let answer_param = &self.answer_subst.var_values[answer_var];
+        let pending = &ty::fold::shift_out_vars(
+            self.infcx.tcx,
+            &pending,
+            self.binder_index.as_u32()
+        );
+
+        super::into_ex_clause(
+            unify(self.infcx, self.environment, answer_param, pending)?,
+            &mut self.ex_clause
+        );
+
+        Ok(())
+    }
+}
+
+impl TypeRelation<'cx, 'gcx, 'tcx> for AnswerSubstitutor<'cx, 'gcx, 'tcx> {
+    fn tcx(&self) -> ty::TyCtxt<'cx, 'gcx, 'tcx> {
+        self.infcx.tcx
+    }
+
+    fn tag(&self) -> &'static str {
+        "chalk_context::answer_substitutor"
+    }
+
+    fn a_is_expected(&self) -> bool {
+        true
+    }
+
+    fn relate_with_variance<T: Relate<'tcx>>(
+        &mut self,
+        _variance: ty::Variance,
+        a: &T,
+        b: &T,
+    ) -> RelateResult<'tcx, T> {
+        // We don't care about variance.
+        self.relate(a, b)
+    }
+
+    fn binders<T: Relate<'tcx>>(
+        &mut self,
+        a: &ty::Binder<T>,
+        b: &ty::Binder<T>,
+    ) -> RelateResult<'tcx, ty::Binder<T>> {
+        self.binder_index.shift_in(1);
+        let result = self.relate(a.skip_binder(), b.skip_binder())?;
+        self.binder_index.shift_out(1);
+        Ok(ty::Binder::bind(result))
+    }
+
+    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+        let b = self.infcx.shallow_resolve(b);
+
+        if let &ty::Bound(debruijn, bound_ty) = &a.sty {
+            // Free bound var
+            if debruijn == self.binder_index {
+                self.unify_free_answer_var(bound_ty.var, b.into())?;
+                return Ok(b);
+            }
+        }
+
+        match (&a.sty, &b.sty) {
+            (&ty::Bound(a_debruijn, a_bound), &ty::Bound(b_debruijn, b_bound)) => {
+                assert_eq!(a_debruijn, b_debruijn);
+                assert_eq!(a_bound.var, b_bound.var);
+                Ok(a)
+            }
+
+            // Those should have been canonicalized away.
+            (ty::Placeholder(..), _) => {
+                bug!("unexpected placeholder ty in `AnswerSubstitutor`: {:?} ", a);
+            }
+
+            // Everything else should just be a perfect match as well,
+            // and we forbid inference variables.
+            _ => match ty::relate::super_relate_tys(self, a, b) {
+                Ok(ty) => Ok(ty),
+                Err(err) => bug!("type mismatch in `AnswerSubstitutor`: {}", err),
+            }
+        }
+    }
+
+    fn regions(
+        &mut self,
+        a: ty::Region<'tcx>,
+        b: ty::Region<'tcx>,
+    ) -> RelateResult<'tcx, ty::Region<'tcx>> {
+        let b = match b {
+            &ty::ReVar(vid) => self.infcx
+                .borrow_region_constraints()
+                .opportunistic_resolve_var(self.infcx.tcx, vid),
+
+            other => other,
+        };
+
+        if let &ty::ReLateBound(debruijn, bound) = a {
+            // Free bound region
+            if debruijn == self.binder_index {
+                self.unify_free_answer_var(bound.assert_bound_var(), b.into())?;
+                return Ok(b);
+            }
+        }
+
+        match (a, b) {
+            (&ty::ReLateBound(a_debruijn, a_bound), &ty::ReLateBound(b_debruijn, b_bound)) => {
+                assert_eq!(a_debruijn, b_debruijn);
+                assert_eq!(a_bound.assert_bound_var(), b_bound.assert_bound_var());
+            }
+
+            (ty::ReStatic, ty::ReStatic) |
+            (ty::ReErased, ty::ReErased) |
+            (ty::ReEmpty, ty::ReEmpty) => (),
+
+            (&ty::ReFree(a_free), &ty::ReFree(b_free)) => {
+                assert_eq!(a_free, b_free);
+            }
+
+            _ => bug!("unexpected regions in `AnswerSubstitutor`: {:?}, {:?}", a, b),
+        }
+
+        Ok(a)
+    }
+}
diff --git a/src/librustc_traits/chalk_context/unify.rs b/src/librustc_traits/chalk_context/unify.rs
new file mode 100644
index 0000000..3a9c391
--- /dev/null
+++ b/src/librustc_traits/chalk_context/unify.rs
@@ -0,0 +1,98 @@
+use rustc::infer::nll_relate::{TypeRelating, TypeRelatingDelegate, NormalizationStrategy};
+use rustc::infer::{InferCtxt, RegionVariableOrigin};
+use rustc::traits::{DomainGoal, Goal, Environment, InEnvironment};
+use rustc::ty::relate::{Relate, TypeRelation, RelateResult};
+use rustc::ty;
+use syntax_pos::DUMMY_SP;
+
+crate struct UnificationResult<'tcx> {
+    crate goals: Vec<InEnvironment<'tcx, Goal<'tcx>>>,
+    crate constraints: Vec<super::RegionConstraint<'tcx>>,
+}
+
+crate fn unify<'me, 'gcx, 'tcx, T: Relate<'tcx>>(
+    infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
+    environment: Environment<'tcx>,
+    a: &T,
+    b: &T
+) -> RelateResult<'tcx, UnificationResult<'tcx>> {
+    let mut delegate = ChalkTypeRelatingDelegate::new(
+        infcx,
+        environment
+    );
+
+    TypeRelating::new(
+        infcx,
+        &mut delegate,
+        ty::Variance::Invariant
+    ).relate(a, b)?;
+
+    Ok(UnificationResult {
+        goals: delegate.goals,
+        constraints: delegate.constraints,
+    })
+}
+
+struct ChalkTypeRelatingDelegate<'me, 'gcx: 'tcx, 'tcx: 'me> {
+    infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
+    environment: Environment<'tcx>,
+    goals: Vec<InEnvironment<'tcx, Goal<'tcx>>>,
+    constraints: Vec<super::RegionConstraint<'tcx>>,
+}
+
+impl ChalkTypeRelatingDelegate<'me, 'gcx, 'tcx> {
+    fn new(
+        infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
+        environment: Environment<'tcx>,
+    ) -> Self {
+        Self {
+            infcx,
+            environment,
+            goals: Vec::new(),
+            constraints: Vec::new(),
+        }
+    }
+}
+
+impl TypeRelatingDelegate<'tcx> for &mut ChalkTypeRelatingDelegate<'_, '_, 'tcx> {
+    fn create_next_universe(&mut self) -> ty::UniverseIndex {
+        self.infcx.create_next_universe()
+    }
+
+    fn next_existential_region_var(&mut self) -> ty::Region<'tcx> {
+        self.infcx.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP))
+    }
+
+    fn next_placeholder_region(
+        &mut self,
+        placeholder: ty::PlaceholderRegion
+    ) -> ty::Region<'tcx> {
+        self.infcx.tcx.mk_region(ty::RePlaceholder(placeholder))
+    }
+
+    fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
+        self.infcx.next_region_var_in_universe(
+            RegionVariableOrigin::MiscVariable(DUMMY_SP),
+            universe
+        )
+    }
+
+    fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
+        self.constraints.push(ty::OutlivesPredicate(sup.into(), sub));
+    }
+
+    fn push_domain_goal(&mut self, domain_goal: DomainGoal<'tcx>) {
+        let goal = self.environment.with(
+            self.infcx.tcx.mk_goal(domain_goal.into_goal())
+        );
+        self.goals.push(goal);
+    }
+
+    fn normalization() -> NormalizationStrategy {
+        NormalizationStrategy::Lazy
+    }
+
+    fn forbid_inference_vars() -> bool {
+        false
+    }
+}
diff --git a/src/librustc_typeck/README.md b/src/librustc_typeck/README.md
index f00597c..fdcbd93 100644
--- a/src/librustc_typeck/README.md
+++ b/src/librustc_typeck/README.md
@@ -1,5 +1,5 @@
 For high-level intro to how type checking works in rustc, see the
 [type checking] chapter of the [rustc guide].
 
-[type checking]: https://rust-lang-nursery.github.io/rustc-guide/type-checking.html
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
+[type checking]: https://rust-lang.github.io/rustc-guide/type-checking.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index 7348930..2cd2bb5 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -59,7 +59,7 @@
         if self.steps.len() >= *tcx.sess.recursion_limit.get() {
             // We've reached the recursion limit, error gracefully.
             let suggested_limit = *tcx.sess.recursion_limit.get() * 2;
-            let msg = format!("reached the recursion limit while auto-dereferencing {:?}",
+            let msg = format!("reached the recursion limit while auto-dereferencing `{:?}`",
                               self.cur_ty);
             let error_id = (DiagnosticMessageId::ErrorId(55), Some(self.span), msg);
             let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
@@ -67,7 +67,7 @@
                 struct_span_err!(tcx.sess,
                                  self.span,
                                  E0055,
-                                 "reached the recursion limit while auto-dereferencing {:?}",
+                                 "reached the recursion limit while auto-dereferencing `{:?}`",
                                  self.cur_ty)
                     .span_label(self.span, "deref recursion limit reached")
                     .help(&format!(
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 9aad176..2af21f5 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -14,6 +14,7 @@
 use intrinsics;
 use rustc::traits::{ObligationCause, ObligationCauseCode};
 use rustc::ty::{self, TyCtxt, Ty};
+use rustc::ty::subst::Subst;
 use rustc::util::nodemap::FxHashMap;
 use require_same_types;
 
@@ -81,6 +82,16 @@
                                       it: &hir::ForeignItem) {
     let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)).as_interned_str());
     let name = it.name.as_str();
+
+    let mk_va_list_ty = || {
+        tcx.lang_items().va_list().map(|did| {
+            let region = tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(0)));
+            let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
+            let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]);
+            tcx.mk_mut_ref(tcx.mk_region(env_region), va_list_ty)
+        })
+    };
+
     let (n_tps, inputs, output, unsafety) = if name.starts_with("atomic_") {
         let split : Vec<&str> = name.split('_').collect();
         assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format");
@@ -323,6 +334,47 @@
                 (0, vec![tcx.mk_fn_ptr(fn_ty), mut_u8, mut_u8], tcx.types.i32)
             }
 
+            "va_start" | "va_end" => {
+                match mk_va_list_ty() {
+                    Some(va_list_ty) => (0, vec![va_list_ty], tcx.mk_unit()),
+                    None => bug!("va_list lang_item must be defined to use va_list intrinsics")
+                }
+            }
+
+            "va_copy" => {
+                match tcx.lang_items().va_list() {
+                    Some(did) => {
+                        let region = tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(0)));
+                        let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
+                        let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]);
+                        let ret_ty = match va_list_ty.sty {
+                            ty::Adt(def, _) if def.is_struct() => {
+                                let fields = &def.non_enum_variant().fields;
+                                match tcx.type_of(fields[0].did).subst(tcx, &[region.into()]).sty {
+                                    ty::Ref(_, element_ty, _) => match element_ty.sty {
+                                        ty::Adt(..) => element_ty,
+                                        _ => va_list_ty
+                                    }
+                                    _ => bug!("va_list structure is invalid")
+                                }
+                            }
+                            _ => {
+                                bug!("va_list structure is invalid")
+                            }
+                        };
+                        (0, vec![tcx.mk_imm_ref(tcx.mk_region(env_region), va_list_ty)], ret_ty)
+                    }
+                    None => bug!("va_list lang_item must be defined to use va_list intrinsics")
+                }
+            }
+
+            "va_arg" => {
+                match mk_va_list_ty() {
+                    Some(va_list_ty) => (1, vec![va_list_ty], param(0)),
+                    None => bug!("va_list lang_item must be defined to use va_list intrinsics")
+                }
+            }
+
             "nontemporal_store" => {
                 (1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_unit())
             }
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index ac338ba..37f4ae5 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -10,7 +10,7 @@
 
 //! Method lookup: the secret sauce of Rust. See the [rustc guide] chapter.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/method-lookup.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/method-lookup.html
 
 use check::FnCtxt;
 use hir::def::Def;
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index e30a79b..a107cec 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -914,6 +914,7 @@
         fcx.resolve_generator_interiors(def_id);
 
         for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
+            let ty = fcx.normalize_ty(span, ty);
             fcx.require_type_is_sized(ty, span, code);
         }
         fcx.select_all_obligations_or_error();
@@ -3969,7 +3970,13 @@
                         //
                         // to work in stable even if the Sized bound on `drop` is relaxed.
                         for i in 0..fn_sig.inputs().skip_binder().len() {
-                            let input = tcx.erase_late_bound_regions(&fn_sig.input(i));
+                            // We just want to check sizedness, so instead of introducing
+                            // placeholder lifetimes with probing, we just replace higher lifetimes
+                            // with fresh vars.
+                            let input = self.replace_bound_vars_with_fresh_vars(
+                                expr.span,
+                                infer::LateBoundRegionConversionTime::FnCall,
+                                &fn_sig.input(i)).0;
                             self.require_type_is_sized_deferred(input, expr.span,
                                                                 traits::SizedArgumentType);
                         }
@@ -3977,7 +3984,13 @@
                     // Here we want to prevent struct constructors from returning unsized types.
                     // There were two cases this happened: fn pointer coercion in stable
                     // and usual function call in presense of unsized_locals.
-                    let output = tcx.erase_late_bound_regions(&fn_sig.output());
+                    // Also, as we just want to check sizedness, instead of introducing
+                    // placeholder lifetimes with probing, we just replace higher lifetimes
+                    // with fresh vars.
+                    let output = self.replace_bound_vars_with_fresh_vars(
+                        expr.span,
+                        infer::LateBoundRegionConversionTime::FnCall,
+                        &fn_sig.output()).0;
                     self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
                 }
 
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index b5addbd..e5fe74f 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -355,13 +355,13 @@
 ) {
     debug!("check_item_type: {:?}", item_id);
 
-    for_id(tcx, item_id, ty_span).with_fcx(|fcx, _this| {
-        let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item_id));
+    for_id(tcx, item_id, ty_span).with_fcx(|fcx, gcx| {
+        let ty = gcx.type_of(gcx.hir.local_def_id(item_id));
         let item_ty = fcx.normalize_associated_types_in(ty_span, &ty);
 
         let mut forbid_unsized = true;
         if allow_foreign_ty {
-            if let TyKind::Foreign(_) = tcx.struct_tail(item_ty).sty {
+            if let TyKind::Foreign(_) = fcx.tcx.struct_tail(item_ty).sty {
                 forbid_unsized = false;
             }
         }
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index 22a96d4..9c1860f 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -113,11 +113,12 @@
             true
         })
         .filter(|&&(def_id, _)| {
-            let cnum = tcx.extern_mod_stmt_cnum(def_id).unwrap();
-            !tcx.is_compiler_builtins(cnum)
-                && !tcx.is_panic_runtime(cnum)
-                && !tcx.has_global_allocator(cnum)
-                && !tcx.has_panic_handler(cnum)
+            tcx.extern_mod_stmt_cnum(def_id).map_or(true, |cnum| {
+                !tcx.is_compiler_builtins(cnum) &&
+                !tcx.is_panic_runtime(cnum) &&
+                !tcx.has_global_allocator(cnum) &&
+                !tcx.has_panic_handler(cnum)
+            })
         })
         .cloned()
         .collect();
@@ -185,7 +186,7 @@
             Some(orig_name) => format!("use {} as {};", orig_name, item.name),
             None => format!("use {};", item.name),
         };
-        let replacement = visibility_qualified(&item.vis, &base_replacement);
+        let replacement = visibility_qualified(&item.vis, base_replacement);
         tcx.struct_span_lint_node(lint, id, extern_crate.span, msg)
             .span_suggestion_short_with_applicability(
                 extern_crate.span,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index a1bb0b5..5682a73 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -938,7 +938,7 @@
 
                     opt_self = Some(ty::GenericParamDef {
                         index: 0,
-                        name: keywords::SelfType.name().as_interned_str(),
+                        name: keywords::SelfUpper.name().as_interned_str(),
                         def_id: tcx.hir.local_def_id(param_id),
                         pure_wrt_drop: false,
                         kind: ty::GenericParamDefKind::Type {
@@ -1007,7 +1007,7 @@
                     synthetic,
                     ..
                 } => {
-                    if param.name.ident().name == keywords::SelfType.name() {
+                    if param.name.ident().name == keywords::SelfUpper.name() {
                         span_bug!(
                             param.span,
                             "`Self` should not be the name of a regular parameter"
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index a985c3e..084951f 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -538,7 +538,7 @@
     let foo = Foo;
     let ref_foo = &&Foo;
 
-    // error, reached the recursion limit while auto-dereferencing &&Foo
+    // error, reached the recursion limit while auto-dereferencing `&&Foo`
     ref_foo.foo();
 }
 ```
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index 7cc56bc..e3c82d5 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -11,7 +11,7 @@
 //! Module for inferring the variance of type and lifetime parameters. See the [rustc guide]
 //! chapter for more info.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/variance.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/variance.html
 
 use arena;
 use rustc::hir;
diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs
index 087d53b..3692221 100644
--- a/src/librustc_typeck/variance/terms.rs
+++ b/src/librustc_typeck/variance/terms.rs
@@ -89,8 +89,8 @@
 
     // See the following for a discussion on dep-graph management.
     //
-    // - https://rust-lang-nursery.github.io/rustc-guide/query.html
-    // - https://rust-lang-nursery.github.io/rustc-guide/variance.html
+    // - https://rust-lang.github.io/rustc-guide/query.html
+    // - https://rust-lang.github.io/rustc-guide/variance.html
     tcx.hir.krate().visit_all_item_likes(&mut terms_cx);
 
     terms_cx
diff --git a/src/librustdoc/README.md b/src/librustdoc/README.md
index 2cfe43a..e4f7bc3 100644
--- a/src/librustdoc/README.md
+++ b/src/librustdoc/README.md
@@ -1,3 +1,3 @@
 For more information about how `librustdoc` works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/rustdoc.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/rustdoc.html
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index fd8f70b..310c369a 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1575,7 +1575,7 @@
         let stripped_typarams = gens.params.iter().filter_map(|param| match param.kind {
             ty::GenericParamDefKind::Lifetime => None,
             ty::GenericParamDefKind::Type { .. } => {
-                if param.name == keywords::SelfType.name().as_str() {
+                if param.name == keywords::SelfUpper.name().as_str() {
                     assert_eq!(param.index, 0);
                     return None;
                 }
@@ -3008,7 +3008,7 @@
 impl Span {
     pub fn empty() -> Span {
         Span {
-            filename: FileName::Anon,
+            filename: FileName::Anon(0),
             loline: 0, locol: 0,
             hiline: 0, hicol: 0,
         }
@@ -3174,7 +3174,7 @@
         if i > 0 {
             s.push_str("::");
         }
-        if seg.ident.name != keywords::CrateRoot.name() {
+        if seg.ident.name != keywords::PathRoot.name() {
             s.push_str(&*seg.ident.as_str());
         }
     }
@@ -3726,7 +3726,7 @@
             hir::Float(float_ty) => return Primitive(float_ty.into()),
         },
         Def::SelfTy(..) if path.segments.len() == 1 => {
-            return Generic(keywords::SelfType.name().to_string());
+            return Generic(keywords::SelfUpper.name().to_string());
         }
         Def::TyParam(..) if path.segments.len() == 1 => {
             return Generic(format!("{:#}", path));
@@ -3948,10 +3948,7 @@
     let mut path_it = path.iter().peekable();
 
     loop {
-        let segment = match path_it.next() {
-            Some(segment) => segment,
-            None => return None,
-        };
+        let segment = path_it.next()?;
 
         for item_id in mem::replace(&mut items, HirVec::new()).iter() {
             let item = tcx.hir.expect_item(item_id.id);
@@ -3986,10 +3983,7 @@
         let mut path_it = path.iter().skip(1).peekable();
 
         loop {
-            let segment = match path_it.next() {
-                Some(segment) => segment,
-                None => return None,
-            };
+            let segment = path_it.next()?;
 
             for item in mem::replace(&mut items, Lrc::new(vec![])).iter() {
                 if item.ident.name == *segment {
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 6522261..8fb91cc 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -346,7 +346,7 @@
             token::Lifetime(..) => Class::Lifetime,
 
             token::Eof | token::Interpolated(..) |
-            token::Tilde | token::At | token::DotEq | token::SingleQuote => Class::None,
+            token::Tilde | token::At| token::SingleQuote => Class::None,
         };
 
         // Anything that didn't return above is the simple case where we the
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 6868c77..fa5d015 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -33,7 +33,7 @@
 
 pub fn render<T: fmt::Display, S: fmt::Display>(
     dst: &mut dyn io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
-    css_file_extension: bool, themes: &[PathBuf])
+    css_file_extension: bool, themes: &[PathBuf], extra_scripts: &[&str])
     -> io::Result<()>
 {
     write!(dst,
@@ -57,6 +57,9 @@
     {css_extension}\
     {favicon}\
     {in_header}\
+    <style type=\"text/css\">\
+    #crate-search{{background-image:url(\"{root_path}down-arrow{suffix}.svg\");}}\
+    </style>\
 </head>\
 <body class=\"rustdoc {css_class}\">\
     <!--[if lte IE 8]>\
@@ -81,11 +84,16 @@
     <nav class=\"sub\">\
         <form class=\"search-form js-only\">\
             <div class=\"search-container\">\
-                <input class=\"search-input\" name=\"search\" \
-                       autocomplete=\"off\" \
-                       spellcheck=\"false\" \
-                       placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
-                       type=\"search\">\
+                <div>\
+                    <select id=\"crate-search\">\
+                        <option value=\"All crates\">All crates</option>\
+                    </select>\
+                    <input class=\"search-input\" name=\"search\" \
+                           autocomplete=\"off\" \
+                           spellcheck=\"false\" \
+                           placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
+                           type=\"search\">\
+                </div>\
                 <a id=\"settings-menu\" href=\"{root_path}settings.html\">\
                     <img src=\"{root_path}wheel{suffix}.svg\" width=\"18\" alt=\"Change settings\">\
                 </a>\
@@ -149,6 +157,7 @@
     </script>\
     <script src=\"{root_path}aliases.js\"></script>\
     <script src=\"{root_path}main{suffix}.js\"></script>\
+    {extra_scripts}\
     <script defer src=\"{root_path}search-index.js\"></script>\
 </body>\
 </html>",
@@ -192,6 +201,11 @@
                                     page.resource_suffix))
                    .collect::<String>(),
     suffix=page.resource_suffix,
+    extra_scripts=extra_scripts.iter().map(|e| {
+        format!("<script src=\"{root_path}{extra_script}.js\"></script>",
+                root_path=page.root_path,
+                extra_script=e)
+    }).collect::<String>(),
     )
 }
 
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index b46efb2..6158815 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -202,8 +202,8 @@
 
 #[derive(Debug)]
 pub struct Error {
-    file: PathBuf,
-    error: io::Error,
+    pub file: PathBuf,
+    pub error: io::Error,
 }
 
 impl error::Error for Error {
@@ -793,6 +793,8 @@
           static_files::BRUSH_SVG)?;
     write(cx.dst.join(&format!("wheel{}.svg", cx.shared.resource_suffix)),
           static_files::WHEEL_SVG)?;
+    write(cx.dst.join(&format!("down-arrow{}.svg", cx.shared.resource_suffix)),
+          static_files::DOWN_ARROW_SVG)?;
     write_minify(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
                  static_files::themes::LIGHT,
                  options.enable_minification)?;
@@ -859,6 +861,11 @@
     write_minify(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
                  static_files::SETTINGS_JS,
                  options.enable_minification)?;
+    if cx.shared.include_sources {
+        write_minify(cx.dst.join(&format!("source-script{}.js", cx.shared.resource_suffix)),
+                     static_files::sidebar::SOURCE_SCRIPT,
+                     options.enable_minification)?;
+    }
 
     {
         let mut data = format!("var resourcesSuffix = \"{}\";\n",
@@ -969,10 +976,88 @@
         }
     }
 
+    use std::ffi::OsString;
+
+    #[derive(Debug)]
+    struct Hierarchy {
+        elem: OsString,
+        children: FxHashMap<OsString, Hierarchy>,
+        elems: FxHashSet<OsString>,
+    }
+
+    impl Hierarchy {
+        fn new(elem: OsString) -> Hierarchy {
+            Hierarchy {
+                elem,
+                children: FxHashMap::default(),
+                elems: FxHashSet::default(),
+            }
+        }
+
+        fn to_json_string(&self) -> String {
+            let mut subs: Vec<&Hierarchy> = self.children.values().collect();
+            subs.sort_unstable_by(|a, b| a.elem.cmp(&b.elem));
+            let mut files = self.elems.iter()
+                                      .map(|s| format!("\"{}\"",
+                                                       s.to_str()
+                                                        .expect("invalid osstring conversion")))
+                                      .collect::<Vec<_>>();
+            files.sort_unstable_by(|a, b| a.cmp(b));
+            // FIXME(imperio): we could avoid to generate "dirs" and "files" if they're empty.
+            format!("{{\"name\":\"{name}\",\"dirs\":[{subs}],\"files\":[{files}]}}",
+                    name=self.elem.to_str().expect("invalid osstring conversion"),
+                    subs=subs.iter().map(|s| s.to_json_string()).collect::<Vec<_>>().join(","),
+                    files=files.join(","))
+        }
+    }
+
+    if cx.shared.include_sources {
+        use std::path::Component;
+
+        let mut hierarchy = Hierarchy::new(OsString::new());
+        for source in cx.shared.local_sources.iter()
+                                             .filter_map(|p| p.0.strip_prefix(&cx.shared.src_root)
+                                                                .ok()) {
+            let mut h = &mut hierarchy;
+            let mut elems = source.components()
+                                  .filter_map(|s| {
+                                      match s {
+                                          Component::Normal(s) => Some(s.to_owned()),
+                                          _ => None,
+                                      }
+                                  })
+                                  .peekable();
+            loop {
+                let cur_elem = elems.next().expect("empty file path");
+                if elems.peek().is_none() {
+                    h.elems.insert(cur_elem);
+                    break;
+                } else {
+                    let e = cur_elem.clone();
+                    h.children.entry(cur_elem.clone()).or_insert_with(|| Hierarchy::new(e));
+                    h = h.children.get_mut(&cur_elem).expect("not found child");
+                }
+            }
+        }
+
+        let dst = cx.dst.join("source-files.js");
+        let (mut all_sources, _krates) = try_err!(collect(&dst, &krate.name, "sourcesIndex"), &dst);
+        all_sources.push(format!("sourcesIndex['{}'] = {};",
+                                 &krate.name,
+                                 hierarchy.to_json_string()));
+        all_sources.sort();
+        let mut w = try_err!(File::create(&dst), &dst);
+        try_err!(writeln!(&mut w,
+                          "var N = null;var sourcesIndex = {{}};\n{}",
+                          all_sources.join("\n")),
+                 &dst);
+    }
+
     // Update the search index
     let dst = cx.dst.join("search-index.js");
     let (mut all_indexes, mut krates) = try_err!(collect(&dst, &krate.name, "searchIndex"), &dst);
     all_indexes.push(search_index);
+
     // Sort the indexes by crate so the file will be generated identically even
     // with rustdoc running in parallel.
     all_indexes.sort();
@@ -983,7 +1068,7 @@
                                        &[(minifier::js::Keyword::Null, "N")]),
                  &dst);
     }
-    try_err!(writeln!(&mut w, "initSearch(searchIndex);"), &dst);
+    try_err!(writeln!(&mut w, "initSearch(searchIndex);addSearchOptions(searchIndex);"), &dst);
 
     if options.enable_index_page {
         if let Some(index_page) = options.index_page.clone() {
@@ -1020,7 +1105,7 @@
             try_err!(layout::render(&mut w, &cx.shared.layout,
                                     &page, &(""), &content,
                                     cx.shared.css_file_extension.is_some(),
-                                    &cx.shared.themes), &dst);
+                                    &cx.shared.themes, &[]), &dst);
             try_err!(w.flush(), &dst);
         }
     }
@@ -1292,7 +1377,8 @@
         layout::render(&mut w, &self.scx.layout,
                        &page, &(""), &Source(contents),
                        self.scx.css_file_extension.is_some(),
-                       &self.scx.themes)?;
+                       &self.scx.themes, &["source-files",
+                                           &format!("source-script{}", page.resource_suffix)])?;
         w.flush()?;
         self.scx.local_sources.insert(p.clone(), href);
         Ok(())
@@ -1890,7 +1976,7 @@
         try_err!(layout::render(&mut w, &self.shared.layout,
                                 &page, &sidebar, &all,
                                 self.shared.css_file_extension.is_some(),
-                                &self.shared.themes),
+                                &self.shared.themes, &[]),
                  &final_file);
 
         // Generating settings page.
@@ -1910,7 +1996,7 @@
         try_err!(layout::render(&mut w, &layout,
                                 &page, &sidebar, &settings,
                                 self.shared.css_file_extension.is_some(),
-                                &themes),
+                                &themes, &[]),
                  &settings_file);
 
         Ok(())
@@ -1968,7 +2054,7 @@
                            &Sidebar{ cx: self, item: it },
                            &Item{ cx: self, item: it },
                            self.shared.css_file_extension.is_some(),
-                           &self.shared.themes)?;
+                           &self.shared.themes, &[])?;
         } else {
             let mut url = self.root_path();
             if let Some(&(ref names, ty)) = cache().paths.get(&it.def_id) {
@@ -2136,13 +2222,13 @@
                 return None;
             }
         } else {
-            let (krate, src_root) = match cache.extern_locations.get(&self.item.def_id.krate) {
-                Some(&(ref name, ref src, Local)) => (name, src),
-                Some(&(ref name, ref src, Remote(ref s))) => {
+            let (krate, src_root) = match *cache.extern_locations.get(&self.item.def_id.krate)? {
+                (ref name, ref src, Local) => (name, src),
+                (ref name, ref src, Remote(ref s)) => {
                     root = s.to_string();
                     (name, src)
                 }
-                Some(&(_, _, Unknown)) | None => return None,
+                (_, _, Unknown) => return None,
             };
 
             clean_srcpath(&src_root, file, false, |component| {
@@ -4249,13 +4335,30 @@
     }
 }
 
-fn get_methods(i: &clean::Impl, for_deref: bool) -> Vec<String> {
+fn get_next_url(used_links: &mut FxHashSet<String>, url: String) -> String {
+    if used_links.insert(url.clone()) {
+        return url;
+    }
+    let mut add = 1;
+    while used_links.insert(format!("{}-{}", url, add)) == false {
+        add += 1;
+    }
+    format!("{}-{}", url, add)
+}
+
+fn get_methods(
+    i: &clean::Impl,
+    for_deref: bool,
+    used_links: &mut FxHashSet<String>,
+) -> Vec<String> {
     i.items.iter().filter_map(|item| {
         match item.name {
             // Maybe check with clean::Visibility::Public as well?
             Some(ref name) if !name.is_empty() && item.visibility.is_some() && item.is_method() => {
                 if !for_deref || should_render_item(item, false) {
-                    Some(format!("<a href=\"#method.{name}\">{name}</a>", name = name))
+                    Some(format!("<a href=\"#{}\">{}</a>",
+                                 get_next_url(used_links, format!("method.{}", name)),
+                                 name))
                 } else {
                     None
                 }
@@ -4285,13 +4388,20 @@
     let mut out = String::new();
     let c = cache();
     if let Some(v) = c.impls.get(&it.def_id) {
-        let ret = v.iter()
-                   .filter(|i| i.inner_impl().trait_.is_none())
-                   .flat_map(|i| get_methods(i.inner_impl(), false))
-                   .collect::<String>();
-        if !ret.is_empty() {
-            out.push_str(&format!("<a class=\"sidebar-title\" href=\"#methods\">Methods\
-                                   </a><div class=\"sidebar-links\">{}</div>", ret));
+        let mut used_links = FxHashSet::default();
+
+        {
+            let used_links_bor = Rc::new(RefCell::new(&mut used_links));
+            let ret = v.iter()
+                       .filter(|i| i.inner_impl().trait_.is_none())
+                       .flat_map(move |i| get_methods(i.inner_impl(),
+                                                      false,
+                                                      &mut used_links_bor.borrow_mut()))
+                       .collect::<String>();
+            if !ret.is_empty() {
+                out.push_str(&format!("<a class=\"sidebar-title\" href=\"#methods\">Methods\
+                                       </a><div class=\"sidebar-links\">{}</div>", ret));
+            }
         }
 
         if v.iter().any(|i| i.inner_impl().trait_.is_some()) {
@@ -4316,7 +4426,9 @@
                         out.push_str("</a>");
                         let ret = impls.iter()
                                        .filter(|i| i.inner_impl().trait_.is_none())
-                                       .flat_map(|i| get_methods(i.inner_impl(), true))
+                                       .flat_map(|i| get_methods(i.inner_impl(),
+                                                                 true,
+                                                                 &mut used_links))
                                        .collect::<String>();
                         out.push_str(&format!("<div class=\"sidebar-links\">{}</div>", ret));
                     }
@@ -4324,27 +4436,28 @@
             }
             let format_impls = |impls: Vec<&Impl>| {
                 let mut links = FxHashSet::default();
+
                 impls.iter()
-                           .filter_map(|i| {
-                               let is_negative_impl = is_negative_impl(i.inner_impl());
-                               if let Some(ref i) = i.inner_impl().trait_ {
-                                   let i_display = format!("{:#}", i);
-                                   let out = Escape(&i_display);
-                                   let encoded = small_url_encode(&format!("{:#}", i));
-                                   let generated = format!("<a href=\"#impl-{}\">{}{}</a>",
-                                                           encoded,
-                                                           if is_negative_impl { "!" } else { "" },
-                                                           out);
-                                   if links.insert(generated.clone()) {
-                                       Some(generated)
-                                   } else {
-                                       None
-                                   }
-                               } else {
-                                   None
-                               }
-                           })
-                           .collect::<String>()
+                     .filter_map(|i| {
+                         let is_negative_impl = is_negative_impl(i.inner_impl());
+                         if let Some(ref i) = i.inner_impl().trait_ {
+                             let i_display = format!("{:#}", i);
+                             let out = Escape(&i_display);
+                             let encoded = small_url_encode(&format!("{:#}", i));
+                             let generated = format!("<a href=\"#impl-{}\">{}{}</a>",
+                                                     encoded,
+                                                     if is_negative_impl { "!" } else { "" },
+                                                     out);
+                             if links.insert(generated.clone()) {
+                                 Some(generated)
+                             } else {
+                                 None
+                             }
+                         } else {
+                             None
+                         }
+                     })
+                     .collect::<String>()
             };
 
             let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = v
diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js
new file mode 100644
index 0000000..c7af41ac
--- /dev/null
+++ b/src/librustdoc/html/static/.eslintrc.js
@@ -0,0 +1,21 @@
+module.exports = {
+    "env": {
+        "browser": true,
+        "es6": true
+    },
+    "extends": "eslint:recommended",
+    "parserOptions": {
+        "ecmaVersion": 2015,
+        "sourceType": "module"
+    },
+    "rules": {
+        "linebreak-style": [
+            "error",
+            "unix"
+        ],
+        "semi": [
+            "error",
+            "always"
+        ]
+    }
+};
diff --git a/src/librustdoc/html/static/down-arrow.svg b/src/librustdoc/html/static/down-arrow.svg
new file mode 100644
index 0000000..a2d9a37
--- /dev/null
+++ b/src/librustdoc/html/static/down-arrow.svg
@@ -0,0 +1 @@
+<?xml version="1.0" ?><!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg height="128px" id="Layer_1" style="enable-background:new 0 0 128 128;" version="1.1" viewBox="0 0 128 128" width="128px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><line style="fill:none;stroke:#2F3435;stroke-width:12;stroke-linecap:square;stroke-miterlimit:10;" x1="111" x2="64" y1="40.5" y2="87.499"/><line style="fill:none;stroke:#2F3435;stroke-width:12;stroke-linecap:square;stroke-miterlimit:10;" x1="64" x2="17" y1="87.499" y2="40.5"/></g></svg>
\ No newline at end of file
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 55415e9..1869969 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -10,8 +10,25 @@
  * except according to those terms.
  */
 
-/*jslint browser: true, es5: true */
-/*globals $: true, rootPath: true */
+// From rust:
+/* global ALIASES, currentCrate, rootPath */
+
+// Local js definitions:
+/* global addClass, getCurrentValue, hasClass */
+/* global isHidden onEach, removeClass, updateLocalStorage */
+
+if (!String.prototype.startsWith) {
+    String.prototype.startsWith = function(searchString, position) {
+        position = position || 0;
+        return this.indexOf(searchString, position) === position;
+    };
+}
+if (!String.prototype.endsWith) {
+    String.prototype.endsWith = function(suffix, length) {
+        var l = length || this.length;
+        return this.indexOf(suffix, l - suffix.length) !== -1;
+    };
+}
 
 (function() {
     "use strict";
@@ -57,19 +74,6 @@
 
     var titleBeforeSearch = document.title;
 
-    if (!String.prototype.startsWith) {
-        String.prototype.startsWith = function(searchString, position) {
-            position = position || 0;
-            return this.indexOf(searchString, position) === position;
-        };
-    }
-    if (!String.prototype.endsWith) {
-        String.prototype.endsWith = function(suffix, length) {
-            var l = length || this.length;
-            return this.indexOf(suffix, l - suffix.length) !== -1;
-        };
-    }
-
     function getPageId() {
         var id = document.location.href.split('#')[1];
         if (id) {
@@ -78,46 +82,6 @@
         return null;
     }
 
-    function hasClass(elem, className) {
-        if (elem && className && elem.className) {
-            var elemClass = elem.className;
-            var start = elemClass.indexOf(className);
-            if (start === -1) {
-                return false;
-            } else if (elemClass.length === className.length) {
-                return true;
-            } else {
-                if (start > 0 && elemClass[start - 1] !== ' ') {
-                    return false;
-                }
-                var end = start + className.length;
-                return !(end < elemClass.length && elemClass[end] !== ' ');
-            }
-        }
-        return false;
-    }
-
-    function addClass(elem, className) {
-        if (elem && className && !hasClass(elem, className)) {
-            if (elem.className && elem.className.length > 0) {
-                elem.className += ' ' + className;
-            } else {
-                elem.className = className;
-            }
-        }
-    }
-
-    function removeClass(elem, className) {
-        if (elem && className && elem.className) {
-            elem.className = (" " + elem.className + " ").replace(" " + className + " ", " ")
-                                                         .trim();
-        }
-    }
-
-    function isHidden(elem) {
-        return (elem.offsetParent === null)
-    }
-
     function showSidebar() {
         var elems = document.getElementsByClassName("sidebar-elems")[0];
         if (elems) {
@@ -254,12 +218,14 @@
     //
     // So I guess you could say things are getting pretty interoperable.
     function getVirtualKey(ev) {
-        if ("key" in ev && typeof ev.key != "undefined")
+        if ("key" in ev && typeof ev.key != "undefined") {
             return ev.key;
+        }
 
         var c = ev.charCode || ev.keyCode;
-        if (c == 27)
+        if (c == 27) {
             return "Escape";
+        }
         return String.fromCharCode(c);
     }
 
@@ -467,12 +433,13 @@
 
         /**
          * Executes the query and builds an index of results
-         * @param  {[Object]} query     [The user query]
-         * @param  {[type]} searchWords [The list of search words to query
-         *                               against]
-         * @return {[type]}             [A search index of results]
+         * @param  {[Object]} query      [The user query]
+         * @param  {[type]} searchWords  [The list of search words to query
+         *                                against]
+         * @param  {[type]} filterCrates [Crate to search in if defined]
+         * @return {[type]}              [A search index of results]
          */
-        function execQuery(query, searchWords) {
+        function execQuery(query, searchWords, filterCrates) {
             function itemTypeFromName(typename) {
                 for (var i = 0; i < itemTypes.length; ++i) {
                     if (itemTypes[i] === typename) {
@@ -848,6 +815,9 @@
             {
                 val = extractGenerics(val.substr(1, val.length - 2));
                 for (var i = 0; i < nSearchWords; ++i) {
+                    if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) {
+                        continue;
+                    }
                     var in_args = findArg(searchIndex[i], val, true);
                     var returned = checkReturned(searchIndex[i], val, true);
                     var ty = searchIndex[i];
@@ -902,6 +872,9 @@
                 var output = extractGenerics(parts[1]);
 
                 for (var i = 0; i < nSearchWords; ++i) {
+                    if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) {
+                        continue;
+                    }
                     var type = searchIndex[i].type;
                     var ty = searchIndex[i];
                     if (!type) {
@@ -973,11 +946,11 @@
                 var contains = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1);
 
                 for (j = 0; j < nSearchWords; ++j) {
-                    var lev_distance;
                     var ty = searchIndex[j];
-                    if (!ty) {
+                    if (!ty || (filterCrates !== undefined && ty.crate !== filterCrates)) {
                         continue;
                     }
+                    var lev_distance;
                     var lev_add = 0;
                     if (paths.length > 1) {
                         var lev = checkPath(contains, paths[paths.length - 1], ty);
@@ -1340,7 +1313,16 @@
                 output = '<div class="search-failed"' + extraStyle + '>No results :(<br/>' +
                     'Try on <a href="https://duckduckgo.com/?q=' +
                     encodeURIComponent('rust ' + query.query) +
-                    '">DuckDuckGo</a>?</div>';
+                    '">DuckDuckGo</a>?<br/><br/>' +
+                    'Or try looking in one of these:<ul><li>The <a ' +
+                    'href="https://doc.rust-lang.org/reference/index.html">Rust Reference</a> for' +
+                    ' technical details about the language.</li><li><a ' +
+                    'href="https://doc.rust-lang.org/rust-by-example/index.html">Rust By Example' +
+                    '</a> for expository code examples.</a></li><li>The <a ' +
+                    'href="https://doc.rust-lang.org/book/index.html">Rust Book</a> for ' +
+                    'introductions to language features and the language itself.</li><li><a ' +
+                    'href="https://docs.rs">Docs.rs</a> for documentation of crates released on ' +
+                    '<a href="https://crates.io/">crates.io</a>.</li></ul></div>';
             }
             return [output, length];
         }
@@ -1353,7 +1335,7 @@
             return '<div>' + text + ' <div class="count">(' + nbElems + ')</div></div>';
         }
 
-        function showResults(results) {
+        function showResults(results, filterCrates) {
             if (results['others'].length === 1 &&
                 getCurrentValue('rustdoc-go-to-only-result') === "true") {
                 var elem = document.createElement('a');
@@ -1371,8 +1353,13 @@
             var ret_in_args = addTab(results['in_args'], query, false);
             var ret_returned = addTab(results['returned'], query, false);
 
+            var filter = "";
+            if (filterCrates !== undefined) {
+                filter = " (in <b>" + filterCrates + "</b> crate)";
+            }
+
             var output = '<h1>Results for ' + escape(query.query) +
-                (query.type ? ' (type: ' + escape(query.type) + ')' : '') + '</h1>' +
+                (query.type ? ' (type: ' + escape(query.type) + ')' : '') + filter + '</h1>' +
                 '<div id="titles">' +
                 makeTabHeader(0, "In Names", ret_others[1]) +
                 makeTabHeader(1, "In Parameters", ret_in_args[1]) +
@@ -1401,7 +1388,7 @@
             printTab(currentTab);
         }
 
-        function execSearch(query, searchWords) {
+        function execSearch(query, searchWords, filterCrates) {
             var queries = query.raw.split(",");
             var results = {
                 'in_args': [],
@@ -1412,7 +1399,7 @@
             for (var i = 0; i < queries.length; ++i) {
                 var query = queries[i].trim();
                 if (query.length !== 0) {
-                    var tmp = execQuery(getQuery(query), searchWords);
+                    var tmp = execQuery(getQuery(query), searchWords, filterCrates);
 
                     results['in_args'].push(tmp['in_args']);
                     results['returned'].push(tmp['returned']);
@@ -1474,7 +1461,16 @@
             }
         }
 
-        function search(e) {
+        function getFilterCrates() {
+            var elem = document.getElementById("crate-search");
+
+            if (elem && elem.value !== "All crates" && rawSearchIndex.hasOwnProperty(elem.value)) {
+                return elem.value;
+            }
+            return undefined;
+        }
+
+        function search(e, forced) {
             var params = getQueryStringParams();
             var query = getQuery(search_input.value.trim());
 
@@ -1482,7 +1478,10 @@
                 e.preventDefault();
             }
 
-            if (query.query.length === 0 || query.id === currentResults) {
+            if (query.query.length === 0) {
+                return;
+            }
+            if (forced !== true && query.id === currentResults) {
                 if (query.query.length > 0) {
                     putBackSearch(search_input);
                 }
@@ -1502,7 +1501,8 @@
                 }
             }
 
-            showResults(execSearch(query, index));
+            var filterCrates = getFilterCrates();
+            showResults(execSearch(query, index, filterCrates), filterCrates);
         }
 
         function buildIndex(rawSearchIndex) {
@@ -1602,6 +1602,13 @@
             };
             search_input.onpaste = search_input.onchange;
 
+            var selectCrate = document.getElementById('crate-search');
+            if (selectCrate) {
+                selectCrate.onchange = function() {
+                    search(undefined, true);
+                };
+            }
+
             // Push and pop states are used to add search results to the browser
             // history.
             if (browserSupportsHistoryApi()) {
@@ -2350,6 +2357,39 @@
     if (window.location.hash && window.location.hash.length > 0) {
         expandSection(window.location.hash.replace(/^#/, ''));
     }
+
+    function addSearchOptions(crates) {
+        var elem = document.getElementById('crate-search');
+
+        if (!elem) {
+            return;
+        }
+        var crates_text = [];
+        for (var crate in crates) {
+            if (crates.hasOwnProperty(crate)) {
+                crates_text.push(crate);
+            }
+        }
+        crates_text.sort(function(a, b) {
+            var lower_a = a.toLowerCase();
+            var lower_b = b.toLowerCase();
+
+            if (lower_a < lower_b) {
+                return -1;
+            } else if (lower_a > lower_b) {
+                return 1;
+            }
+            return 0;
+        });
+        for (var i = 0; i < crates_text.length; ++i) {
+            var option = document.createElement("option");
+            option.value = crates_text[i];
+            option.innerText = crates_text[i];
+            elem.appendChild(option);
+        }
+    }
+
+    window.addSearchOptions = addSearchOptions;
 }());
 
 // Sets the focus on the search bar at the top of the page
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index b2473dd..37d26a4 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -113,7 +113,8 @@
 
 h1, h2, h3, h4,
 .sidebar, a.source, .search-input, .content table :not(code)>a,
-.collapse-toggle, div.item-list .out-of-band {
+.collapse-toggle, div.item-list .out-of-band,
+#source-sidebar, #sidebar-toggle {
 	font-family: "Fira Sans", sans-serif;
 }
 
@@ -121,7 +122,7 @@
 	padding-left: 25px;
 }
 ul ul, ol ul, ul ol, ol ol {
-	margin-bottom: 0;
+	margin-bottom: .6em;
 }
 
 p {
@@ -134,7 +135,6 @@
 
 code, pre {
 	font-family: "Source Code Pro", monospace;
-	white-space: pre-wrap;
 }
 .docblock code, .docblock-short code {
 	border-radius: 3px;
@@ -282,7 +282,7 @@
 	padding-left: 0;
 }
 
-body:not(.source) .example-wrap {
+.rustdoc:not(.source) .example-wrap {
 	display: inline-flex;
 	margin-bottom: 10px;
 }
@@ -300,8 +300,9 @@
 	text-align: right;
 }
 
-body:not(.source) .example-wrap > pre.rust {
+.rustdoc:not(.source) .example-wrap > pre.rust {
 	width: 100%;
+	overflow-x: auto;
 }
 
 body:not(.source) .example-wrap > pre {
@@ -619,13 +620,36 @@
 .search-container {
 	position: relative;
 }
+.search-container > div {
+	display: inline-flex;
+	width: calc(100% - 34px);
+}
+#crate-search {
+	margin-top: 5px;
+	padding: 6px;
+	padding-right: 19px;
+	border: 0;
+	border-right: 0;
+	border-radius: 4px 0 0 4px;
+	outline: none;
+	cursor: pointer;
+	border-right: 1px solid;
+	-moz-appearance: none;
+	-webkit-appearance: none;
+	/* Removes default arrow from firefox */
+	text-indent: 0.01px;
+	text-overflow: "";
+	background-repeat: no-repeat;
+	background-color: transparent;
+	background-size: 16%;
+	background-position: calc(100% - 1px) 56%;
+}
 .search-container > .top-button {
 	position: absolute;
 	right: 0;
 	top: 10px;
 }
 .search-input {
-	width: calc(100% - 34px);
 	/* Override Normalize.css: we have margins and do
 	 not want to overflow - the `moz` attribute is necessary
 	 until Firefox 29, too early to drop at this point */
@@ -633,13 +657,14 @@
 	box-sizing: border-box !important;
 	outline: none;
 	border: none;
-	border-radius: 1px;
+	border-radius: 0 1px 1px 0;
 	margin-top: 5px;
 	padding: 10px 16px;
 	font-size: 17px;
 	transition: border-color 300ms ease;
 	transition: border-radius 300ms ease-in-out;
 	transition: box-shadow 300ms ease-in-out;
+	width: 100%;
 }
 
 .search-input:focus {
@@ -668,9 +693,9 @@
 	padding-right: 10px;
 }
 .content .search-results td:first-child a:after {
-    clear: both;
-    content: "";
-    display: block;
+	clear: both;
+	content: "";
+	display: block;
 }
 .content .search-results td:first-child a span {
 	float: left;
@@ -1131,6 +1156,13 @@
 	margin-top: 20px;
 }
 
+.search-failed > ul {
+	text-align: left;
+	max-width: 570px;
+	margin-left: auto;
+	margin-right: auto;
+}
+
 #titles {
 	height: 35px;
 }
@@ -1459,3 +1491,68 @@
 .non-exhaustive {
 	margin-bottom: 1em;
 }
+
+#sidebar-toggle {
+	position: fixed;
+	top: 30px;
+	left: 300px;
+	z-index: 10;
+	padding: 3px;
+	border-top-right-radius: 3px;
+	border-bottom-right-radius: 3px;
+	cursor: pointer;
+	font-weight: bold;
+	transition: left .5s;
+	font-size: 1.2em;
+	border: 1px solid;
+	border-left: 0;
+}
+#source-sidebar {
+	position: fixed;
+	top: 0;
+	bottom: 0;
+	left: 0;
+	width: 300px;
+	z-index: 1;
+	overflow: auto;
+	transition: left .5s;
+	border-right: 1px solid;
+}
+#source-sidebar > .title {
+	font-size: 1.5em;
+	text-align: center;
+	border-bottom: 1px solid;
+	margin-bottom: 6px;
+}
+
+div.children {
+	padding-left: 27px;
+	display: none;
+}
+div.name {
+	cursor: pointer;
+	position: relative;
+	margin-left: 16px;
+}
+div.files > a {
+	display: block;
+	padding: 0 3px;
+}
+div.files > a:hover, div.name:hover {
+	background-color: #a14b4b;
+}
+div.name.expand + .children {
+	display: block;
+}
+div.name::before {
+	content: "\25B6";
+	padding-left: 4px;
+	font-size: 0.7em;
+	position: absolute;
+	left: -16px;
+	top: 4px;
+}
+div.name.expand::before {
+	transform: rotate(90deg);
+	left: -14px;
+}
diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js
new file mode 100644
index 0000000..03b0955
--- /dev/null
+++ b/src/librustdoc/html/static/source-script.js
@@ -0,0 +1,153 @@
+/*!
+ * 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.
+ */
+
+// From rust:
+/* global sourcesIndex */
+
+// Local js definitions:
+/* global addClass, getCurrentValue, hasClass, removeClass, updateLocalStorage */
+
+function getCurrentFilePath() {
+    var parts = window.location.pathname.split("/");
+    var rootPathParts = window.rootPath.split("/");
+
+    for (var i = 0; i < rootPathParts.length; ++i) {
+        if (rootPathParts[i] === "..") {
+            parts.pop();
+        }
+    }
+    var file = window.location.pathname.substring(parts.join("/").length);
+    if (file.startsWith("/")) {
+        file = file.substring(1);
+    }
+    return file.substring(0, file.length - 5);
+}
+
+function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) {
+    var name = document.createElement("div");
+    name.className = "name";
+
+    fullPath += elem["name"] + "/";
+
+    name.onclick = function() {
+        if (hasClass(this, "expand")) {
+            removeClass(this, "expand");
+        } else {
+            addClass(this, "expand");
+        }
+    };
+    name.innerText = elem["name"];
+
+    var children = document.createElement("div");
+    children.className = "children";
+    var folders = document.createElement("div");
+    folders.className = "folders";
+    for (var i = 0; i < elem.dirs.length; ++i) {
+        if (createDirEntry(elem.dirs[i], folders, fullPath, currentFile,
+                           hasFoundFile) === true) {
+            addClass(name, "expand");
+            hasFoundFile = true;
+        }
+    }
+    children.appendChild(folders);
+
+    var files = document.createElement("div");
+    files.className = "files";
+    for (i = 0; i < elem.files.length; ++i) {
+        var file = document.createElement("a");
+        file.innerText = elem.files[i];
+        file.href = window.rootPath + "src/" + fullPath + elem.files[i] + ".html";
+        if (hasFoundFile === false &&
+                currentFile === fullPath + elem.files[i]) {
+            file.className = "selected";
+            addClass(name, "expand");
+            hasFoundFile = true;
+        }
+        files.appendChild(file);
+    }
+    search.fullPath = fullPath;
+    children.appendChild(files);
+    parent.appendChild(name);
+    parent.appendChild(children);
+    return hasFoundFile === true && currentFile.startsWith(fullPath);
+}
+
+function toggleSidebar() {
+    var sidebar = document.getElementById("source-sidebar");
+    var child = this.children[0].children[0];
+    if (child.innerText === ">") {
+        sidebar.style.left = "";
+        this.style.left = "";
+        child.innerText = "<";
+        updateLocalStorage("rustdoc-source-sidebar-show", "true");
+    } else {
+        sidebar.style.left = "-300px";
+        this.style.left = "0";
+        child.innerText = ">";
+        updateLocalStorage("rustdoc-source-sidebar-show", "false");
+    }
+}
+
+function createSidebarToggle() {
+    var sidebarToggle = document.createElement("div");
+    sidebarToggle.id = "sidebar-toggle";
+    sidebarToggle.onclick = toggleSidebar;
+
+    var inner1 = document.createElement("div");
+    inner1.style.position = "relative";
+
+    var inner2 = document.createElement("div");
+    inner2.style.marginTop = "-2px";
+    if (getCurrentValue("rustdoc-source-sidebar-show") === "true") {
+        inner2.innerText = "<";
+    } else {
+        inner2.innerText = ">";
+        sidebarToggle.style.left = "0";
+    }
+
+    inner1.appendChild(inner2);
+    sidebarToggle.appendChild(inner1);
+    return sidebarToggle;
+}
+
+function createSourceSidebar() {
+    if (window.rootPath.endsWith("/") === false) {
+        window.rootPath += "/";
+    }
+    var main = document.getElementById("main");
+
+    var sidebarToggle = createSidebarToggle();
+    main.insertBefore(sidebarToggle, main.firstChild);
+
+    var sidebar = document.createElement("div");
+    sidebar.id = "source-sidebar";
+    if (getCurrentValue("rustdoc-source-sidebar-show") !== "true") {
+        sidebar.style.left = "-300px";
+    }
+
+    var currentFile = getCurrentFilePath();
+    var hasFoundFile = false;
+
+    var title = document.createElement("div");
+    title.className = "title";
+    title.innerText = "Files";
+    sidebar.appendChild(title);
+    Object.keys(sourcesIndex).forEach(function(key) {
+        sourcesIndex[key].name = key;
+        hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "",
+                                      currentFile, hasFoundFile);
+    });
+
+    main.insertBefore(sidebar, main.firstChild);
+}
+
+createSourceSidebar();
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index 5f7a8c7..e8f0c03 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -10,11 +10,54 @@
  * except according to those terms.
  */
 
+// From rust:
+/* global resourcesSuffix */
+
 var currentTheme = document.getElementById("themeStyle");
 var mainTheme = document.getElementById("mainThemeStyle");
 
 var savedHref = [];
 
+function hasClass(elem, className) {
+    if (elem && className && elem.className) {
+        var elemClass = elem.className;
+        var start = elemClass.indexOf(className);
+        if (start === -1) {
+            return false;
+        } else if (elemClass.length === className.length) {
+            return true;
+        } else {
+            if (start > 0 && elemClass[start - 1] !== ' ') {
+                return false;
+            }
+            var end = start + className.length;
+            return !(end < elemClass.length && elemClass[end] !== ' ');
+        }
+    }
+    return false;
+}
+
+function addClass(elem, className) {
+    if (elem && className && !hasClass(elem, className)) {
+        if (elem.className && elem.className.length > 0) {
+            elem.className += ' ' + className;
+        } else {
+            elem.className = className;
+        }
+    }
+}
+
+function removeClass(elem, className) {
+    if (elem && className && elem.className) {
+        elem.className = (" " + elem.className + " ").replace(" " + className + " ", " ")
+                                                     .trim();
+    }
+}
+
+function isHidden(elem) {
+    return (elem.offsetParent === null)
+}
+
 function onEach(arr, func, reversed) {
     if (arr && arr.length > 0 && func) {
         if (reversed !== true) {
diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css
index 4a8950b..2cd1a85 100644
--- a/src/librustdoc/html/static/themes/dark.css
+++ b/src/librustdoc/html/static/themes/dark.css
@@ -182,9 +182,15 @@
 	color: #999;
 }
 
+#crate-search {
+	color: #111;
+	background-color: #f0f0f0;
+	border-color: #000;
+}
+
 .search-input {
 	color: #111;
-	box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent;
+	box-shadow: 1px 0 0 1px #000, 0 0 0 2px transparent;
 	background-color: #f0f0f0;
 }
 
@@ -285,7 +291,7 @@
 	color: rgba(255,142,0,1);
 }
 
-.search-failed > a {
+.search-failed a {
 	color: #0089ff;
 }
 
@@ -416,3 +422,22 @@
 .impl-items code {
 	background-color: rgba(0, 0, 0, 0);
 }
+
+#sidebar-toggle {
+	background-color: #565656;
+}
+#sidebar-toggle:hover {
+	background-color: #676767;
+}
+#source-sidebar {
+	background-color: #565656;
+}
+#source-sidebar > .title {
+	border-bottom-color: #ccc;
+}
+div.files > a:hover, div.name:hover {
+	background-color: #444;
+}
+div.files > .selected {
+	background-color: #333;
+}
diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css
index b3b0b6b..4cf35f6 100644
--- a/src/librustdoc/html/static/themes/light.css
+++ b/src/librustdoc/html/static/themes/light.css
@@ -182,9 +182,16 @@
 	color: #999;
 }
 
+#crate-search {
+	color: #555;
+	background-color: white;
+	border-color: #e0e0e0;
+	box-shadow: 0px 0 0 1px #e0e0e0, 0 0 0 2px transparent;
+}
+
 .search-input {
 	color: #555;
-	box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent;
+	box-shadow: 1px 0 0 1px #e0e0e0, 0 0 0 2px transparent;
 	background-color: white;
 }
 
@@ -279,7 +286,7 @@
 	color: rgba(255,142,0,1);
 }
 
-.search-failed > a {
+.search-failed a {
 	color: #0089ff;
 }
 
@@ -410,3 +417,22 @@
 .impl-items code {
 	background-color: rgba(0, 0, 0, 0);
 }
+
+#sidebar-toggle {
+	background-color: #F1F1F1;
+}
+#sidebar-toggle:hover {
+	background-color: #E0E0E0;
+}
+#source-sidebar {
+	background-color: #F1F1F1;
+}
+#source-sidebar > .title {
+	border-bottom-color: #ccc;
+}
+div.files > a:hover, div.name:hover {
+	background-color: #E0E0E0;
+}
+div.files > .selected {
+	background-color: #fff;
+}
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index 3baa082..a485fac 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -45,6 +45,9 @@
 /// The file contents of `wheel.svg`, the icon used for the settings button.
 pub static WHEEL_SVG: &'static [u8] = include_bytes!("static/wheel.svg");
 
+/// The file contents of `down-arrow.svg`, the icon used for the crate choice combobox.
+pub static DOWN_ARROW_SVG: &'static [u8] = include_bytes!("static/down-arrow.svg");
+
 /// The contents of `COPYRIGHT.txt`, the license listing for files distributed with documentation
 /// output.
 pub static COPYRIGHT: &'static [u8] = include_bytes!("static/COPYRIGHT.txt");
@@ -109,3 +112,9 @@
     /// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font.
     pub static LICENSE: &'static [u8] = include_bytes!("static/SourceCodePro-LICENSE.txt");
 }
+
+/// Files related to the sidebar in rustdoc sources.
+pub mod sidebar {
+    /// File script to handle sidebar.
+    pub static SOURCE_SCRIPT: &'static str = include_str!("static/source-script.js");
+}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 4b043b2..b21f005 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -387,9 +387,21 @@
         info!("going to format");
         let (error_format, treat_err_as_bug, ui_testing) = diag_opts;
         let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing);
-        html::render::run(krate, renderopts, passes.into_iter().collect(), renderinfo, &diag)
-            .expect("failed to generate documentation");
-        0
+        match html::render::run(
+            krate,
+            renderopts,
+            passes.into_iter().collect(),
+            renderinfo,
+            &diag,
+        ) {
+            Ok(_) => rustc_driver::EXIT_SUCCESS,
+            Err(e) => {
+                diag.struct_err(&format!("couldn't generate documentation: {}", e.error))
+                    .note(&format!("failed to create or modify \"{}\"", e.file.display()))
+                    .emit();
+                rustc_driver::EXIT_FAILURE
+            }
+        }
     })
 }
 
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index d9bab91..7458319 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -197,8 +197,14 @@
     let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts);
     // FIXME(#44940): if doctests ever support path remapping, then this filename
     // needs to be the result of SourceMap::span_to_unmapped_path
+
+    let path = match filename {
+        FileName::Real(path) => path.clone(),
+        _ => PathBuf::from(r"doctest.rs"),
+    };
+
     let input = config::Input::Str {
-        name: filename.to_owned(),
+        name: FileName::DocTest(path, line as isize - line_offset as isize),
         input: test,
     };
     let outputs = OutputTypes::new(&[(OutputType::Exe, None)]);
@@ -252,9 +258,7 @@
     let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout()));
 
     let (libdir, outdir, compile_result) = driver::spawn_thread_pool(sessopts, |sessopts| {
-        let source_map = Lrc::new(SourceMap::new_doctest(
-            sessopts.file_path_mapping(), filename.clone(), line as isize - line_offset as isize
-        ));
+        let source_map = Lrc::new(SourceMap::new(sessopts.file_path_mapping()));
         let emitter = errors::emitter::EmitterWriter::new(box Sink(data.clone()),
                                                         Some(source_map.clone()),
                                                         false,
@@ -401,7 +405,7 @@
         use errors::emitter::EmitterWriter;
         use errors::Handler;
 
-        let filename = FileName::Anon;
+        let filename = FileName::anon_source_code(s);
         let source = crates + &everything_else;
 
         // any errors in parsing should also appear when the doctest is compiled for real, so just
@@ -411,8 +415,6 @@
         let handler = Handler::with_emitter(false, false, box emitter);
         let sess = ParseSess::with_span_handler(handler, cm);
 
-        debug!("about to parse: \n{}", source);
-
         let mut found_main = false;
         let mut found_extern_crate = cratename.is_none();
 
@@ -487,8 +489,6 @@
         prog.push_str("\n}");
     }
 
-    info!("final test program: {}", prog);
-
     (prog, line_offset)
 }
 
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 5d221d3..31adb2e 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -100,7 +100,7 @@
                                               None);
         // attach the crate's exported macros to the top-level module:
         let macro_exports: Vec<_> =
-            krate.exported_macros.iter().map(|def| self.visit_local_macro(def)).collect();
+            krate.exported_macros.iter().map(|def| self.visit_local_macro(def, None)).collect();
         self.module.macros.extend(macro_exports);
         self.module.is_crate = true;
 
@@ -376,6 +376,10 @@
                 });
                 true
             }
+            Node::MacroDef(def) if !glob => {
+                om.macros.push(self.visit_local_macro(def, renamed));
+                true
+            }
             _ => false,
         };
         self.view_item_stack.remove(&def_node_id);
@@ -593,7 +597,11 @@
     }
 
     // convert each exported_macro into a doc item
-    fn visit_local_macro(&self, def: &hir::MacroDef) -> Macro {
+    fn visit_local_macro(
+        &self,
+        def: &hir::MacroDef,
+        renamed: Option<ast::Name>
+    ) -> Macro {
         debug!("visit_local_macro: {}", def.name);
         let tts = def.body.trees().collect::<Vec<_>>();
         // Extract the spans of all matchers. They represent the "interface" of the macro.
@@ -602,7 +610,7 @@
         Macro {
             def_id: self.cx.tcx.hir.local_def_id(def.id),
             attrs: def.attrs.clone(),
-            name: def.name,
+            name: renamed.unwrap_or(def.name),
             whence: def.span,
             matchers,
             stab: self.stability(def.id),
diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs
index 3e028d7..cbd642d 100644
--- a/src/libserialize/collection_impls.rs
+++ b/src/libserialize/collection_impls.rs
@@ -86,7 +86,7 @@
 impl<T:Decodable> Decodable for VecDeque<T> {
     fn decode<D: Decoder>(d: &mut D) -> Result<VecDeque<T>, D::Error> {
         d.read_seq(|d, len| {
-            let mut deque: VecDeque<T> = VecDeque::new();
+            let mut deque: VecDeque<T> = VecDeque::with_capacity(len);
             for i in 0..len {
                 deque.push_back(d.read_seq_elt(i, |d| Decodable::decode(d))?);
             }
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 2b1d515..cae2f40 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -43,9 +43,15 @@
 build_helper = { path = "../build_helper" }
 
 [features]
+default = ["compiler_builtins_c"]
+
 backtrace = []
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
+compiler_builtins_c = ["compiler_builtins/c"]
+
+# Make panics and failed asserts immediately abort without formatting any message
+panic_immediate_abort = ["core/panic_immediate_abort"]
 
 # An off-by-default feature which enables a linux-syscall-like ABI for libstd to
 # interoperate with the host environment. Currently not well documented and
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 7c717d8..536ce2e 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -849,6 +849,7 @@
     /// let mut map: HashMap<&str, i32> = HashMap::new();
     /// map.reserve(10);
     /// ```
+    #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn reserve(&mut self, additional: usize) {
         match self.reserve_internal(additional, Infallible) {
@@ -880,6 +881,7 @@
         self.reserve_internal(additional, Fallible)
     }
 
+    #[inline]
     fn reserve_internal(&mut self, additional: usize, fallibility: Fallibility)
         -> Result<(), CollectionAllocErr> {
 
@@ -1016,7 +1018,7 @@
     /// map.shrink_to(0);
     /// assert!(map.capacity() >= 2);
     /// ```
-    #[unstable(feature = "shrink_to", reason = "new API", issue="0")]
+    #[unstable(feature = "shrink_to", reason = "new API", issue="56431")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity");
 
@@ -1571,6 +1573,7 @@
     /// so that the map now contains keys which compare equal, search may start
     /// acting erratically, with two keys randomly masking each other. Implementations
     /// are free to assume this doesn't happen (within the limits of memory-safety).
+    #[inline(always)]
     #[unstable(feature = "hash_raw_entry", issue = "56167")]
     pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<K, V, S> {
         self.reserve(1);
@@ -1911,6 +1914,7 @@
     }
 
     /// Create a `RawEntryMut` from the given key and its hash.
+    #[inline]
     #[unstable(feature = "hash_raw_entry", issue = "56167")]
     pub fn from_key_hashed_nocheck<Q: ?Sized>(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S>
         where K: Borrow<Q>,
@@ -1919,6 +1923,7 @@
         self.from_hash(hash, |q| q.borrow().eq(k))
     }
 
+    #[inline]
     fn search<F>(self, hash: u64, is_match: F, compare_hashes: bool)  -> RawEntryMut<'a, K, V, S>
         where for<'b> F: FnMut(&'b K) -> bool,
     {
@@ -1941,6 +1946,7 @@
         }
     }
     /// Create a `RawEntryMut` from the given hash.
+    #[inline]
     #[unstable(feature = "hash_raw_entry", issue = "56167")]
     pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S>
         where for<'b> F: FnMut(&'b K) -> bool,
@@ -2215,6 +2221,7 @@
 
     /// Sets the value of the entry with the VacantEntry's key,
     /// and returns a mutable reference to it.
+    #[inline]
     #[unstable(feature = "hash_raw_entry", issue = "56167")]
     pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) {
         let hash = SafeHash::new(hash);
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 5ac3e8f..4bb3ce0 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -315,7 +315,7 @@
     /// assert!(set.capacity() >= 2);
     /// ```
     #[inline]
-    #[unstable(feature = "shrink_to", reason = "new API", issue="0")]
+    #[unstable(feature = "shrink_to", reason = "new API", issue="56431")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.map.shrink_to(min_capacity)
     }
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 547f97c..479e6dc 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -329,6 +329,7 @@
 }
 
 impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
+    #[inline]
     pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> {
         Bucket::at_index(table, hash.inspect() as usize)
     }
@@ -342,6 +343,7 @@
         }
     }
 
+    #[inline]
     pub fn at_index(table: M, ib_index: usize) -> Bucket<K, V, M> {
         // if capacity is 0, then the RawBucket will be populated with bogus pointers.
         // This is an uncommon case though, so avoid it in release builds.
@@ -654,6 +656,7 @@
 
 // Returns a Layout which describes the allocation required for a hash table,
 // and the offset of the array of (key, value) pairs in the allocation.
+#[inline(always)]
 fn calculate_layout<K, V>(capacity: usize) -> Result<(Layout, usize), LayoutErr> {
     let hashes = Layout::array::<HashUint>(capacity)?;
     let pairs = Layout::array::<(K, V)>(capacity)?;
@@ -722,6 +725,7 @@
         }
     }
 
+    #[inline(always)]
     fn raw_bucket_at(&self, index: usize) -> RawBucket<K, V> {
         let (_, pairs_offset) = calculate_layout::<K, V>(self.capacity())
             .unwrap_or_else(|_| unsafe { hint::unreachable_unchecked() });
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index 9066c0b..d14efa2 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -828,7 +828,7 @@
     /// - s390x
     /// - sparc64
     #[stable(feature = "env", since = "1.0.0")]
-    pub const ARCH: &'static str = super::arch::ARCH;
+    pub const ARCH: &str = super::arch::ARCH;
 
     /// The family of the operating system. Example value is `unix`.
     ///
@@ -837,7 +837,7 @@
     /// - unix
     /// - windows
     #[stable(feature = "env", since = "1.0.0")]
-    pub const FAMILY: &'static str = os::FAMILY;
+    pub const FAMILY: &str = os::FAMILY;
 
     /// A string describing the specific operating system in use.
     /// Example value is `linux`.
@@ -856,7 +856,7 @@
     /// - android
     /// - windows
     #[stable(feature = "env", since = "1.0.0")]
-    pub const OS: &'static str = os::OS;
+    pub const OS: &str = os::OS;
 
     /// Specifies the filename prefix used for shared libraries on this
     /// platform. Example value is `lib`.
@@ -866,7 +866,7 @@
     /// - lib
     /// - `""` (an empty string)
     #[stable(feature = "env", since = "1.0.0")]
-    pub const DLL_PREFIX: &'static str = os::DLL_PREFIX;
+    pub const DLL_PREFIX: &str = os::DLL_PREFIX;
 
     /// Specifies the filename suffix used for shared libraries on this
     /// platform. Example value is `.so`.
@@ -877,7 +877,7 @@
     /// - .dylib
     /// - .dll
     #[stable(feature = "env", since = "1.0.0")]
-    pub const DLL_SUFFIX: &'static str = os::DLL_SUFFIX;
+    pub const DLL_SUFFIX: &str = os::DLL_SUFFIX;
 
     /// Specifies the file extension used for shared libraries on this
     /// platform that goes after the dot. Example value is `so`.
@@ -888,7 +888,7 @@
     /// - dylib
     /// - dll
     #[stable(feature = "env", since = "1.0.0")]
-    pub const DLL_EXTENSION: &'static str = os::DLL_EXTENSION;
+    pub const DLL_EXTENSION: &str = os::DLL_EXTENSION;
 
     /// Specifies the filename suffix used for executable binaries on this
     /// platform. Example value is `.exe`.
@@ -900,7 +900,7 @@
     /// - .pexe
     /// - `""` (an empty string)
     #[stable(feature = "env", since = "1.0.0")]
-    pub const EXE_SUFFIX: &'static str = os::EXE_SUFFIX;
+    pub const EXE_SUFFIX: &str = os::EXE_SUFFIX;
 
     /// Specifies the file extension, if any, used for executable binaries
     /// on this platform. Example value is `exe`.
@@ -910,72 +910,72 @@
     /// - exe
     /// - `""` (an empty string)
     #[stable(feature = "env", since = "1.0.0")]
-    pub const EXE_EXTENSION: &'static str = os::EXE_EXTENSION;
+    pub const EXE_EXTENSION: &str = os::EXE_EXTENSION;
 }
 
 #[cfg(target_arch = "x86")]
 mod arch {
-    pub const ARCH: &'static str = "x86";
+    pub const ARCH: &str = "x86";
 }
 
 #[cfg(target_arch = "x86_64")]
 mod arch {
-    pub const ARCH: &'static str = "x86_64";
+    pub const ARCH: &str = "x86_64";
 }
 
 #[cfg(target_arch = "arm")]
 mod arch {
-    pub const ARCH: &'static str = "arm";
+    pub const ARCH: &str = "arm";
 }
 
 #[cfg(target_arch = "aarch64")]
 mod arch {
-    pub const ARCH: &'static str = "aarch64";
+    pub const ARCH: &str = "aarch64";
 }
 
 #[cfg(target_arch = "mips")]
 mod arch {
-    pub const ARCH: &'static str = "mips";
+    pub const ARCH: &str = "mips";
 }
 
 #[cfg(target_arch = "mips64")]
 mod arch {
-    pub const ARCH: &'static str = "mips64";
+    pub const ARCH: &str = "mips64";
 }
 
 #[cfg(target_arch = "powerpc")]
 mod arch {
-    pub const ARCH: &'static str = "powerpc";
+    pub const ARCH: &str = "powerpc";
 }
 
 #[cfg(target_arch = "powerpc64")]
 mod arch {
-    pub const ARCH: &'static str = "powerpc64";
+    pub const ARCH: &str = "powerpc64";
 }
 
 #[cfg(target_arch = "s390x")]
 mod arch {
-    pub const ARCH: &'static str = "s390x";
+    pub const ARCH: &str = "s390x";
 }
 
 #[cfg(target_arch = "sparc64")]
 mod arch {
-    pub const ARCH: &'static str = "sparc64";
+    pub const ARCH: &str = "sparc64";
 }
 
 #[cfg(target_arch = "le32")]
 mod arch {
-    pub const ARCH: &'static str = "le32";
+    pub const ARCH: &str = "le32";
 }
 
 #[cfg(target_arch = "asmjs")]
 mod arch {
-    pub const ARCH: &'static str = "asmjs";
+    pub const ARCH: &str = "asmjs";
 }
 
 #[cfg(target_arch = "wasm32")]
 mod arch {
-    pub const ARCH: &'static str = "wasm32";
+    pub const ARCH: &str = "wasm32";
 }
 
 #[cfg(test)]
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 66718b9..7c7f839 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -671,7 +671,7 @@
 #[stable(feature = "cstr_default", since = "1.10.0")]
 impl<'a> Default for &'a CStr {
     fn default() -> &'a CStr {
-        const SLICE: &'static [c_char] = &[0];
+        const SLICE: &[c_char] = &[0];
         unsafe { CStr::from_ptr(SLICE.as_ptr()) }
     }
 }
@@ -1475,7 +1475,7 @@
 
     #[test]
     fn cstr_const_constructor() {
-        const CSTR: &'static CStr = unsafe {
+        const CSTR: &CStr = unsafe {
             CStr::from_bytes_with_nul_unchecked(b"Hello, world!\0")
         };
 
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index a3345df..bd5fc3f 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -112,12 +112,12 @@
 //! ## On Unix
 //!
 //! On Unix, [`OsStr`] implements the
-//! `std::os::unix:ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
+//! `std::os::unix::ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
 //! augments it with two methods, [`from_bytes`] and [`as_bytes`].
 //! These do inexpensive conversions from and to UTF-8 byte slices.
 //!
 //! Additionally, on Unix [`OsString`] implements the
-//! `std::os::unix:ffi::`[`OsStringExt`][unix.OsStringExt] trait,
+//! `std::os::unix::ffi::`[`OsStringExt`][unix.OsStringExt] trait,
 //! which provides [`from_vec`] and [`into_vec`] methods that consume
 //! their arguments, and take or produce vectors of [`u8`].
 //!
@@ -174,5 +174,12 @@
 #[stable(feature = "raw_os", since = "1.1.0")]
 pub use core::ffi::c_void;
 
+#[cfg(not(stage0))]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "27745")]
+pub use core::ffi::VaList;
+
 mod c_str;
 mod os_str;
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index e939063..9c40a31 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -42,6 +42,13 @@
 /// in each pair are owned strings; the latter are borrowed
 /// references.
 ///
+/// Note, `OsString` and `OsStr` internally do not necessarily hold strings in
+/// the form native to the platform; While on Unix, strings are stored as a
+/// sequence of 8-bit values, on Windows, where strings are 16-bit value based
+/// as just discussed, strings are also actually stored as a sequence of 8-bit
+/// values, encoded in a less-strict variant of UTF-8. This is useful to
+/// understand when handling capacity and length values.
+///
 /// # Creating an `OsString`
 ///
 /// **From a Rust string**: `OsString` implements
@@ -324,7 +331,7 @@
     /// assert!(s.capacity() >= 3);
     /// ```
     #[inline]
-    #[unstable(feature = "shrink_to", reason = "new API", issue="0")]
+    #[unstable(feature = "shrink_to", reason = "new API", issue="56431")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.inner.shrink_to(min_capacity)
     }
@@ -583,14 +590,19 @@
 
     /// Returns the length of this `OsStr`.
     ///
-    /// Note that this does **not** return the number of bytes in this string
-    /// as, for example, OS strings on Windows are encoded as a list of [`u16`]
-    /// rather than a list of bytes. This number is simply useful for passing to
-    /// other methods like [`OsString::with_capacity`] to avoid reallocations.
+    /// Note that this does **not** return the number of bytes in the string in
+    /// OS string form.
     ///
-    /// See `OsStr` introduction for more information about encoding.
+    /// The length returned is that of the underlying storage used by `OsStr`;
+    /// As discussed in the [`OsString`] introduction, [`OsString`] and `OsStr`
+    /// store strings in a form best suited for cheap inter-conversion between
+    /// native-platform and Rust string forms, which may differ significantly
+    /// from both of them, including in storage size and encoding.
     ///
-    /// [`u16`]: ../primitive.u16.html
+    /// This number is simply useful for passing to other methods, like
+    /// [`OsString::with_capacity`] to avoid reallocations.
+    ///
+    /// [`OsString`]: struct.OsString.html
     /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
     ///
     /// # Examples
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 92678dd..7d054a3 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -2065,7 +2065,7 @@
             Err(e) => return Err(e),
         }
         match path.parent() {
-            Some(p) => try!(self.create_dir_all(p)),
+            Some(p) => self.create_dir_all(p)?,
             None => return Err(io::Error::new(io::ErrorKind::Other, "failed to create whole tree")),
         }
         match self.inner.mkdir(path) {
diff --git a/src/libstd/future.rs b/src/libstd/future.rs
index 1cadbdc..d5e6cab 100644
--- a/src/libstd/future.rs
+++ b/src/libstd/future.rs
@@ -95,10 +95,10 @@
     });
     let _reset_waker = SetOnDrop(waker_ptr);
 
-    let mut waker_ptr = waker_ptr.expect(
+    let waker_ptr = waker_ptr.expect(
         "TLS LocalWaker not set. This is a rustc bug. \
         Please file an issue on https://github.com/rust-lang/rust.");
-    unsafe { f(waker_ptr.as_mut()) }
+    unsafe { f(waker_ptr.as_ref()) }
 }
 
 #[unstable(feature = "gen_future", issue = "50547")]
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index e263db2..076524e 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -431,7 +431,7 @@
 ///     // read up to 10 bytes
 ///     f.read(&mut buffer)?;
 ///
-///     let mut buffer = vec![0; 10];
+///     let mut buffer = Vec::new();
 ///     // read the whole file
 ///     f.read_to_end(&mut buffer)?;
 ///
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index 13cf313..c1eaf29 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -65,7 +65,7 @@
 /// look like this:
 ///
 /// ```rust
-/// const WORDS: &'static str = "hello rust!";
+/// const WORDS: &str = "hello rust!";
 /// ```
 ///
 /// Thanks to static lifetime elision, you usually don't have to explicitly use 'static:
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 575903d..78109a1 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -244,6 +244,7 @@
 #![feature(array_error_internals)]
 #![feature(asm)]
 #![feature(box_syntax)]
+#![feature(c_variadic)]
 #![feature(cfg_target_has_atomic)]
 #![feature(cfg_target_thread_local)]
 #![feature(cfg_target_vendor)]
@@ -310,6 +311,7 @@
 #![feature(panic_info_message)]
 #![feature(non_exhaustive)]
 #![feature(alloc_layout_extra)]
+#![feature(maybe_uninit)]
 
 #![default_lib_allocator]
 
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 0995ab3..94827d2 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -224,11 +224,9 @@
 /// the value of a given expression. An example:
 ///
 /// ```rust
-/// #![feature(dbg_macro)]
-///
 /// let a = 2;
 /// let b = dbg!(a * 2) + 1;
-/// //      ^-- prints: [src/main.rs:4] a * 2 = 4
+/// //      ^-- prints: [src/main.rs:2] a * 2 = 4
 /// assert_eq!(b, 5);
 /// ```
 ///
@@ -262,8 +260,6 @@
 /// With a method call:
 ///
 /// ```rust
-/// #![feature(dbg_macro)]
-///
 /// fn foo(n: usize) {
 ///     if let Some(_) = dbg!(n.checked_sub(4)) {
 ///         // ...
@@ -282,8 +278,6 @@
 /// Naive factorial implementation:
 ///
 /// ```rust
-/// #![feature(dbg_macro)]
-///
 /// fn factorial(n: u32) -> u32 {
 ///     if dbg!(n <= 1) {
 ///         dbg!(1)
@@ -312,8 +306,6 @@
 /// The `dbg!(..)` macro moves the input:
 ///
 /// ```compile_fail
-/// #![feature(dbg_macro)]
-///
 /// /// A wrapper around `usize` which importantly is not Copyable.
 /// #[derive(Debug)]
 /// struct NoCopy(usize);
@@ -325,7 +317,7 @@
 ///
 /// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)
 #[macro_export]
-#[unstable(feature = "dbg_macro", issue = "54306")]
+#[stable(feature = "dbg_macro", since = "1.32.0")]
 macro_rules! dbg {
     ($val:expr) => {
         // Use of `match` here is intentional because it affects the lifetimes
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index ad212a5..be79780 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -1548,8 +1548,9 @@
 
         let mut buf = [0; 10];
         let start = Instant::now();
-        let kind = stream.read(&mut buf).err().expect("expected error").kind();
-        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+                "unexpected_error: {:?}", kind);
         assert!(start.elapsed() > Duration::from_millis(400));
         drop(listener);
     }
@@ -1570,8 +1571,9 @@
         assert_eq!(b"hello world", &buf[..]);
 
         let start = Instant::now();
-        let kind = stream.read(&mut buf).err().expect("expected error").kind();
-        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+                "unexpected_error: {:?}", kind);
         assert!(start.elapsed() > Duration::from_millis(400));
         drop(listener);
     }
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index 0ebe328..fc68aba 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -1030,8 +1030,14 @@
         let mut buf = [0; 10];
 
         let start = Instant::now();
-        let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
-        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        loop {
+            let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
+            if kind != ErrorKind::Interrupted {
+                assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+                        "unexpected_error: {:?}", kind);
+                break;
+            }
+        }
         assert!(start.elapsed() > Duration::from_millis(400));
     }
 
@@ -1049,8 +1055,14 @@
         assert_eq!(b"hello world", &buf[..]);
 
         let start = Instant::now();
-        let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
-        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        loop {
+            let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
+            if kind != ErrorKind::Interrupted {
+                assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+                        "unexpected_error: {:?}", kind);
+                break;
+            }
+        }
         assert!(start.elapsed() > Duration::from_millis(400));
     }
 
diff --git a/src/libstd/os/linux/fs.rs b/src/libstd/os/linux/fs.rs
index 76fb10d..b518f52 100644
--- a/src/libstd/os/linux/fs.rs
+++ b/src/libstd/os/linux/fs.rs
@@ -191,7 +191,7 @@
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_size(&self) -> u64;
-    /// Returns the last access time.
+    /// Returns the last access time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -208,7 +208,9 @@
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_atime(&self) -> i64;
-    /// Returns the last access time, nano seconds part.
+    /// Returns the last access time of the file, in nanoseconds since [`st_atime`].
+    ///
+    /// [`st_atime`]: #tymethod.st_atime
     ///
     /// # Examples
     ///
@@ -225,7 +227,7 @@
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_atime_nsec(&self) -> i64;
-    /// Returns the last modification time.
+    /// Returns the last modification time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -242,7 +244,9 @@
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_mtime(&self) -> i64;
-    /// Returns the last modification time, nano seconds part.
+    /// Returns the last modification time of the file, in nanoseconds since [`st_mtime`].
+    ///
+    /// [`st_mtime`]: #tymethod.st_mtime
     ///
     /// # Examples
     ///
@@ -259,7 +263,7 @@
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_mtime_nsec(&self) -> i64;
-    /// Returns the last status change time.
+    /// Returns the last status change time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -276,7 +280,9 @@
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_ctime(&self) -> i64;
-    /// Returns the last status change time, nano seconds part.
+    /// Returns the last status change time of the file, in nanoseconds since [`st_ctime`].
+    ///
+    /// [`st_ctime`]: #tymethod.st_ctime
     ///
     /// # Examples
     ///
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index a0590a8..4930d35 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -334,9 +334,17 @@
 #[unstable(feature = "libstd_sys_internals",
            reason = "used by the panic! macro",
            issue = "0")]
-#[inline(never)] #[cold]
+#[cold]
+// If panic_immediate_abort, inline the abort call,
+// otherwise avoid inlining because of it is cold path.
+#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
+#[cfg_attr(    feature="panic_immediate_abort" ,inline)]
 pub fn begin_panic_fmt(msg: &fmt::Arguments,
                        file_line_col: &(&'static str, u32, u32)) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { intrinsics::abort() }
+    }
+
     let (file, line, col) = *file_line_col;
     let info = PanicInfo::internal_constructor(
         Some(msg),
@@ -398,8 +406,15 @@
            reason = "used by the panic! macro",
            issue = "0")]
 #[cfg_attr(not(test), lang = "begin_panic")]
-#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
+// never inline unless panic_immediate_abort to avoid code
+// bloat at the call sites as much as possible
+#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
+#[cold]
 pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u32)) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { intrinsics::abort() }
+    }
+
     // Note that this should be the only allocation performed in this code path.
     // Currently this means that panic!() on OOM will invoke this code path,
     // but then again we're not really ready for panic on OOM anyway. If
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index a153456..9fad40c 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -1397,6 +1397,9 @@
 
 #[stable(feature = "path_buf_from_box", since = "1.18.0")]
 impl From<Box<Path>> for PathBuf {
+    /// Converts a `Box<Path>` into a `PathBuf`
+    ///
+    /// This conversion does not allocate or copy memory.
     fn from(boxed: Box<Path>) -> PathBuf {
         boxed.into_path_buf()
     }
@@ -1404,6 +1407,10 @@
 
 #[stable(feature = "box_from_path_buf", since = "1.20.0")]
 impl From<PathBuf> for Box<Path> {
+    /// Converts a `PathBuf` into a `Box<Path>`
+    ///
+    /// This conversion currently should not allocate memory,
+    /// but this behavior is not guaranteed on all platforms or in all future versions.
     fn from(p: PathBuf) -> Box<Path> {
         p.into_boxed_path()
     }
@@ -1426,6 +1433,9 @@
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl From<OsString> for PathBuf {
+    /// Converts a `OsString` into a `PathBuf`
+    ///
+    /// This conversion does not allocate or copy memory.
     fn from(s: OsString) -> PathBuf {
         PathBuf { inner: s }
     }
@@ -1433,6 +1443,9 @@
 
 #[stable(feature = "from_path_buf_for_os_string", since = "1.14.0")]
 impl From<PathBuf> for OsString {
+    /// Converts a `PathBuf` into a `OsString`
+    ///
+    /// This conversion does not allocate or copy memory.
     fn from(path_buf : PathBuf) -> OsString {
         path_buf.inner
     }
@@ -1440,6 +1453,9 @@
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl From<String> for PathBuf {
+    /// Converts a `String` into a `PathBuf`
+    ///
+    /// This conversion does not allocate or copy memory.
     fn from(s: String) -> PathBuf {
         PathBuf::from(OsString::from(s))
     }
@@ -1536,6 +1552,7 @@
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<PathBuf> for Arc<Path> {
+    /// Converts a Path into a Rc by copying the Path data into a new Rc buffer.
     #[inline]
     fn from(s: PathBuf) -> Arc<Path> {
         let arc: Arc<OsStr> = Arc::from(s.into_os_string());
@@ -1545,6 +1562,7 @@
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl<'a> From<&'a Path> for Arc<Path> {
+    /// Converts a Path into a Rc by copying the Path data into a new Rc buffer.
     #[inline]
     fn from(s: &Path) -> Arc<Path> {
         let arc: Arc<OsStr> = Arc::from(s.as_os_str());
@@ -1554,6 +1572,7 @@
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<PathBuf> for Rc<Path> {
+    /// Converts a Path into a Rc by copying the Path data into a new Rc buffer.
     #[inline]
     fn from(s: PathBuf) -> Rc<Path> {
         let rc: Rc<OsStr> = Rc::from(s.into_os_string());
@@ -1563,6 +1582,7 @@
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl<'a> From<&'a Path> for Rc<Path> {
+    /// Converts a Path into a Rc by copying the Path data into a new Rc buffer.
     #[inline]
     fn from(s: &Path) -> Rc<Path> {
         let rc: Rc<OsStr> = Rc::from(s.as_os_str());
diff --git a/src/libstd/sys/cloudabi/shims/env.rs b/src/libstd/sys/cloudabi/shims/env.rs
index 31777aa..c7691e3 100644
--- a/src/libstd/sys/cloudabi/shims/env.rs
+++ b/src/libstd/sys/cloudabi/shims/env.rs
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 pub mod os {
-    pub const FAMILY: &'static str = "cloudabi";
-    pub const OS: &'static str = "cloudabi";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "cloudabi";
+    pub const OS: &str = "cloudabi";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
diff --git a/src/libstd/sys/redox/env.rs b/src/libstd/sys/redox/env.rs
index 669b752..75e3504 100644
--- a/src/libstd/sys/redox/env.rs
+++ b/src/libstd/sys/redox/env.rs
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 pub mod os {
-    pub const FAMILY: &'static str = "redox";
-    pub const OS: &'static str = "redox";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "redox";
+    pub const OS: &str = "redox";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
diff --git a/src/libstd/sys/redox/path.rs b/src/libstd/sys/redox/path.rs
index e6a267d..b1a4ed3 100644
--- a/src/libstd/sys/redox/path.rs
+++ b/src/libstd/sys/redox/path.rs
@@ -35,5 +35,5 @@
     }
 }
 
-pub const MAIN_SEP_STR: &'static str = "/";
+pub const MAIN_SEP_STR: &str = "/";
 pub const MAIN_SEP: char = '/';
diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs
index 4370c1e..8f6d83c 100644
--- a/src/libstd/sys/redox/process.rs
+++ b/src/libstd/sys/redox/process.rs
@@ -143,7 +143,7 @@
 
     pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
                  -> io::Result<(Process, StdioPipes)> {
-         const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX";
+         const CLOEXEC_MSG_FOOTER: &[u8] = b"NOEX";
 
          if self.saw_nul {
              return Err(io::Error::new(ErrorKind::InvalidInput,
diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs
index ad116c5..1b6838f 100644
--- a/src/libstd/sys/unix/env.rs
+++ b/src/libstd/sys/unix/env.rs
@@ -10,176 +10,176 @@
 
 #[cfg(target_os = "linux")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "linux";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "linux";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "macos")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "macos";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".dylib";
-    pub const DLL_EXTENSION: &'static str = "dylib";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "macos";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".dylib";
+    pub const DLL_EXTENSION: &str = "dylib";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "ios")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "ios";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".dylib";
-    pub const DLL_EXTENSION: &'static str = "dylib";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "ios";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".dylib";
+    pub const DLL_EXTENSION: &str = "dylib";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "freebsd")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "freebsd";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "freebsd";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "dragonfly")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "dragonfly";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "dragonfly";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "bitrig")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "bitrig";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "bitrig";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "netbsd")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "netbsd";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "netbsd";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "openbsd")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "openbsd";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "openbsd";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "android")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "android";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "android";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "solaris")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "solaris";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "solaris";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "haiku")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "haiku";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "haiku";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(all(target_os = "emscripten", target_arch = "asmjs"))]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "emscripten";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = ".js";
-    pub const EXE_EXTENSION: &'static str = "js";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "emscripten";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = ".js";
+    pub const EXE_EXTENSION: &str = "js";
 }
 
 #[cfg(all(target_os = "emscripten", target_arch = "wasm32"))]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "emscripten";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = ".js";
-    pub const EXE_EXTENSION: &'static str = "js";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "emscripten";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = ".js";
+    pub const EXE_EXTENSION: &str = "js";
 }
 
 #[cfg(target_os = "fuchsia")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "fuchsia";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "fuchsia";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "l4re")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "l4re";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "l4re";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
 
 #[cfg(target_os = "hermit")]
 pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "hermit";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = "";
-    pub const EXE_EXTENSION: &'static str = "";
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "hermit";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
 }
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index 507e9d8..7e65bbd 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -522,7 +522,7 @@
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn size(&self) -> u64;
-    /// Returns the time of the last access to the file.
+    /// Returns the last access time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -539,7 +539,9 @@
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn atime(&self) -> i64;
-    /// Returns the time of the last access to the file in nanoseconds.
+    /// Returns the last access time of the file, in nanoseconds since [`atime`].
+    ///
+    /// [`atime`]: #tymethod.atime
     ///
     /// # Examples
     ///
@@ -556,7 +558,7 @@
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn atime_nsec(&self) -> i64;
-    /// Returns the time of the last modification of the file.
+    /// Returns the last modification time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -573,7 +575,9 @@
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mtime(&self) -> i64;
-    /// Returns the time of the last modification of the file in nanoseconds.
+    /// Returns the last modification time of the file, in nanoseconds since [`mtime`].
+    ///
+    /// [`mtime`]: #tymethod.mtime
     ///
     /// # Examples
     ///
@@ -590,7 +594,7 @@
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mtime_nsec(&self) -> i64;
-    /// Returns the time of the last status change of the file.
+    /// Returns the last status change time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -607,7 +611,9 @@
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn ctime(&self) -> i64;
-    /// Returns the time of the last status change of the file in nanoseconds.
+    /// Returns the last status change time of the file, in nanoseconds since [`ctime`].
+    ///
+    /// [`ctime`]: #tymethod.ctime
     ///
     /// # Examples
     ///
diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs
index 55f43cc..737437c 100644
--- a/src/libstd/sys/unix/ext/net.rs
+++ b/src/libstd/sys/unix/ext/net.rs
@@ -1654,8 +1654,9 @@
         or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
 
         let mut buf = [0; 10];
-        let kind = stream.read(&mut buf).err().expect("expected error").kind();
-        assert!(kind == io::ErrorKind::WouldBlock || kind == io::ErrorKind::TimedOut);
+        let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+                "unexpected_error: {:?}", kind);
     }
 
     #[test]
@@ -1675,8 +1676,9 @@
         or_panic!(stream.read(&mut buf));
         assert_eq!(b"hello world", &buf[..]);
 
-        let kind = stream.read(&mut buf).err().expect("expected error").kind();
-        assert!(kind == io::ErrorKind::WouldBlock || kind == io::ErrorKind::TimedOut);
+        let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+                "unexpected_error: {:?}", kind);
     }
 
     // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index b387a8d..03e81a7 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -283,11 +283,14 @@
 
 #[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))]
 pub fn current_exe() -> io::Result<PathBuf> {
-    let selfexe = PathBuf::from("/proc/self/exe");
-    if selfexe.exists() {
-        ::fs::read_link(selfexe)
-    } else {
-        Err(io::Error::new(io::ErrorKind::Other, "no /proc/self/exe available. Is /proc mounted?"))
+    match ::fs::read_link("/proc/self/exe") {
+        Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
+            Err(io::Error::new(
+                io::ErrorKind::Other,
+                "no /proc/self/exe available. Is /proc mounted?"
+            ))
+        },
+        other => other,
     }
 }
 
diff --git a/src/libstd/sys/unix/path.rs b/src/libstd/sys/unix/path.rs
index bf9af7a..834b4b4 100644
--- a/src/libstd/sys/unix/path.rs
+++ b/src/libstd/sys/unix/path.rs
@@ -25,5 +25,5 @@
     None
 }
 
-pub const MAIN_SEP_STR: &'static str = "/";
+pub const MAIN_SEP_STR: &str = "/";
 pub const MAIN_SEP: char = '/';
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index bfbf12f..3248f42 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -22,7 +22,7 @@
 impl Command {
     pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
                  -> io::Result<(Process, StdioPipes)> {
-        const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX";
+        const CLOEXEC_MSG_FOOTER: &[u8] = b"NOEX";
 
         let envp = self.capture_env();
 
diff --git a/src/libstd/sys/wasm/env.rs b/src/libstd/sys/wasm/env.rs
index 1422042..09235a9 100644
--- a/src/libstd/sys/wasm/env.rs
+++ b/src/libstd/sys/wasm/env.rs
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 pub mod os {
-    pub const FAMILY: &'static str = "";
-    pub const OS: &'static str = "";
-    pub const DLL_PREFIX: &'static str = "";
-    pub const DLL_SUFFIX: &'static str = ".wasm";
-    pub const DLL_EXTENSION: &'static str = "wasm";
-    pub const EXE_SUFFIX: &'static str = ".wasm";
-    pub const EXE_EXTENSION: &'static str = "wasm";
+    pub const FAMILY: &str = "";
+    pub const OS: &str = "";
+    pub const DLL_PREFIX: &str = "";
+    pub const DLL_SUFFIX: &str = ".wasm";
+    pub const DLL_EXTENSION: &str = "wasm";
+    pub const EXE_SUFFIX: &str = ".wasm";
+    pub const EXE_EXTENSION: &str = "wasm";
 }
diff --git a/src/libstd/sys/wasm/path.rs b/src/libstd/sys/wasm/path.rs
index 395b8c1..fcc9d61 100644
--- a/src/libstd/sys/wasm/path.rs
+++ b/src/libstd/sys/wasm/path.rs
@@ -25,5 +25,5 @@
     None
 }
 
-pub const MAIN_SEP_STR: &'static str = "/";
+pub const MAIN_SEP_STR: &str = "/";
 pub const MAIN_SEP: char = '/';
diff --git a/src/libstd/sys/windows/env.rs b/src/libstd/sys/windows/env.rs
index e6d7489..4523df0 100644
--- a/src/libstd/sys/windows/env.rs
+++ b/src/libstd/sys/windows/env.rs
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 pub mod os {
-    pub const FAMILY: &'static str = "windows";
-    pub const OS: &'static str = "windows";
-    pub const DLL_PREFIX: &'static str = "";
-    pub const DLL_SUFFIX: &'static str = ".dll";
-    pub const DLL_EXTENSION: &'static str = "dll";
-    pub const EXE_SUFFIX: &'static str = ".exe";
-    pub const EXE_EXTENSION: &'static str = "exe";
+    pub const FAMILY: &str = "windows";
+    pub const OS: &str = "windows";
+    pub const DLL_PREFIX: &str = "";
+    pub const DLL_SUFFIX: &str = ".dll";
+    pub const DLL_EXTENSION: &str = "dll";
+    pub const EXE_SUFFIX: &str = ".exe";
+    pub const EXE_EXTENSION: &str = "exe";
 }
diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs
index b0e7331..2bd5dee 100644
--- a/src/libstd/sys/windows/mutex.rs
+++ b/src/libstd/sys/windows/mutex.rs
@@ -30,7 +30,7 @@
 //! detect recursive locks.
 
 use cell::UnsafeCell;
-use mem;
+use mem::{self, MaybeUninit};
 use sync::atomic::{AtomicUsize, Ordering};
 use sys::c;
 use sys::compat;
@@ -157,34 +157,34 @@
     return ret;
 }
 
-pub struct ReentrantMutex { inner: UnsafeCell<c::CRITICAL_SECTION> }
+pub struct ReentrantMutex { inner: UnsafeCell<MaybeUninit<c::CRITICAL_SECTION>> }
 
 unsafe impl Send for ReentrantMutex {}
 unsafe impl Sync for ReentrantMutex {}
 
 impl ReentrantMutex {
-    pub unsafe fn uninitialized() -> ReentrantMutex {
-        mem::uninitialized()
+    pub fn uninitialized() -> ReentrantMutex {
+        ReentrantMutex { inner: UnsafeCell::new(MaybeUninit::uninitialized()) }
     }
 
     pub unsafe fn init(&mut self) {
-        c::InitializeCriticalSection(self.inner.get());
+        c::InitializeCriticalSection((&mut *self.inner.get()).as_mut_ptr());
     }
 
     pub unsafe fn lock(&self) {
-        c::EnterCriticalSection(self.inner.get());
+        c::EnterCriticalSection((&mut *self.inner.get()).as_mut_ptr());
     }
 
     #[inline]
     pub unsafe fn try_lock(&self) -> bool {
-        c::TryEnterCriticalSection(self.inner.get()) != 0
+        c::TryEnterCriticalSection((&mut *self.inner.get()).as_mut_ptr()) != 0
     }
 
     pub unsafe fn unlock(&self) {
-        c::LeaveCriticalSection(self.inner.get());
+        c::LeaveCriticalSection((&mut *self.inner.get()).as_mut_ptr());
     }
 
     pub unsafe fn destroy(&self) {
-        c::DeleteCriticalSection(self.inner.get());
+        c::DeleteCriticalSection((&mut *self.inner.get()).as_mut_ptr());
     }
 }
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index 29ea82c..4d7b723 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -48,8 +48,8 @@
         // `[MS-ERREF]`: https://msdn.microsoft.com/en-us/library/cc231198.aspx
         if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
             // format according to https://support.microsoft.com/en-us/help/259693
-            const NTDLL_DLL: &'static [u16] = &['N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _,
-                                                '.' as _, 'D' as _, 'L' as _, 'L' as _, 0];
+            const NTDLL_DLL: &[u16] = &['N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _,
+                                        '.' as _, 'D' as _, 'L' as _, 'L' as _, 0];
             module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
 
             if module != ptr::null_mut() {
diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs
index 98d62a0..385ea8e 100644
--- a/src/libstd/sys/windows/path.rs
+++ b/src/libstd/sys/windows/path.rs
@@ -91,10 +91,7 @@
     }
 
     fn parse_two_comps(mut path: &[u8], f: fn(u8) -> bool) -> Option<(&[u8], &[u8])> {
-        let first = match path.iter().position(|x| f(*x)) {
-            None => return None,
-            Some(x) => &path[..x],
-        };
+        let first = &path[..path.iter().position(|x| f(*x))?];
         path = &path[(first.len() + 1)..];
         let idx = path.iter().position(|x| f(*x));
         let second = &path[..idx.unwrap_or(path.len())];
@@ -102,5 +99,5 @@
     }
 }
 
-pub const MAIN_SEP_STR: &'static str = "\\";
+pub const MAIN_SEP_STR: &str = "\\";
 pub const MAIN_SEP: char = '\\';
diff --git a/src/libstd/sys/windows/stdio.rs b/src/libstd/sys/windows/stdio.rs
index 81b89da..c3a9469 100644
--- a/src/libstd/sys/windows/stdio.rs
+++ b/src/libstd/sys/windows/stdio.rs
@@ -48,7 +48,7 @@
 }
 
 fn write(handle: c::DWORD, data: &[u8]) -> io::Result<usize> {
-    let handle = match try!(get(handle)) {
+    let handle = match get(handle)? {
         Output::Console(c) => c,
         Output::Pipe(p) => {
             let handle = Handle::new(p);
@@ -99,7 +99,7 @@
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        let handle = match try!(get(c::STD_INPUT_HANDLE)) {
+        let handle = match get(c::STD_INPUT_HANDLE)? {
             Output::Console(c) => c,
             Output::Pipe(p) => {
                 let handle = Handle::new(p);
diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs
index 19ce932..3530b7a 100644
--- a/src/libstd/sys_common/wtf8.rs
+++ b/src/libstd/sys_common/wtf8.rs
@@ -40,7 +40,7 @@
 use sync::Arc;
 use sys_common::AsInner;
 
-const UTF8_REPLACEMENT_CHARACTER: &'static str = "\u{FFFD}";
+const UTF8_REPLACEMENT_CHARACTER: &str = "\u{FFFD}";
 
 /// A Unicode code point: from U+0000 to U+10FFFF.
 ///
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 8a845ef..3a9f3ec 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -326,7 +326,7 @@
     /// Sets the size of the stack (in bytes) for the new thread.
     ///
     /// The actual stack size may be greater than this value if
-    /// the platform specifies minimal stack size.
+    /// the platform specifies a minimal stack size.
     ///
     /// For more information about the stack size for threads, see
     /// [this module-level documentation][stack-size].
diff --git a/src/libsyntax/README.md b/src/libsyntax/README.md
index 7214203..daa252e 100644
--- a/src/libsyntax/README.md
+++ b/src/libsyntax/README.md
@@ -5,5 +5,5 @@
 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)
+- [Parsing](https://rust-lang.github.io/rustc-guide/the-parser.html)
+- [Macro Expansion](https://rust-lang.github.io/rustc-guide/macro-expansion.html)
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 227017a..8722571 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -73,7 +73,7 @@
 pub struct Path {
     pub span: Span,
     /// The segments in the path: the things separated by `::`.
-    /// Global paths begin with `keywords::CrateRoot`.
+    /// Global paths begin with `keywords::PathRoot`.
     pub segments: Vec<PathSegment>,
 }
 
@@ -105,19 +105,8 @@
         }
     }
 
-    // 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.ident) {
-            if ident.is_path_segment_keyword() {
-                return None;
-            }
-        }
-        Some(PathSegment::crate_root(self.span.shrink_to_lo()))
-    }
-
     pub fn is_global(&self) -> bool {
-        !self.segments.is_empty() && self.segments[0].ident.name == keywords::CrateRoot.name()
+        !self.segments.is_empty() && self.segments[0].ident.name == keywords::PathRoot.name()
     }
 }
 
@@ -144,8 +133,8 @@
     pub fn from_ident(ident: Ident) -> Self {
         PathSegment { ident, id: DUMMY_NODE_ID, args: None }
     }
-    pub fn crate_root(span: Span) -> Self {
-        PathSegment::from_ident(Ident::new(keywords::CrateRoot.name(), span))
+    pub fn path_root(span: Span) -> Self {
+        PathSegment::from_ident(Ident::new(keywords::PathRoot.name(), span))
     }
 }
 
@@ -1688,7 +1677,7 @@
 impl Arg {
     pub fn to_self(&self) -> Option<ExplicitSelf> {
         if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.node {
-            if ident.name == keywords::SelfValue.name() {
+            if ident.name == keywords::SelfLower.name() {
                 return match self.ty.node {
                     TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
                     TyKind::Rptr(lt, MutTy { ref ty, mutbl }) if ty.node.is_implicit_self() => {
@@ -1706,7 +1695,7 @@
 
     pub fn is_self(&self) -> bool {
         if let PatKind::Ident(_, ident, _) = self.pat.node {
-            ident.name == keywords::SelfValue.name()
+            ident.name == keywords::SelfLower.name()
         } else {
             false
         }
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 6487665..518b34e 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -803,7 +803,7 @@
     for raw_attr in attrs {
         let mut parser = parse::new_parser_from_source_str(
             parse_sess,
-            FileName::CliCrateAttr,
+            FileName::cli_crate_attr_source_code(&raw_attr),
             raw_attr.clone(),
         );
 
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index cacec86..5770f6b 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -318,9 +318,13 @@
                 args: Vec<ast::GenericArg>,
                 bindings: Vec<ast::TypeBinding> )
                 -> ast::Path {
+        assert!(!idents.is_empty());
+        let add_root = global && !idents[0].is_path_segment_keyword();
+        let mut segments = Vec::with_capacity(idents.len() + add_root as usize);
+        if add_root {
+            segments.push(ast::PathSegment::path_root(span));
+        }
         let last_ident = idents.pop().unwrap();
-        let mut segments: Vec<ast::PathSegment> = vec![];
-
         segments.extend(idents.into_iter().map(|ident| {
             ast::PathSegment::from_ident(ident.with_span_pos(span))
         }));
@@ -334,13 +338,7 @@
             id: ast::DUMMY_NODE_ID,
             args,
         });
-        let mut path = ast::Path { span, segments };
-        if global {
-            if let Some(seg) = path.make_root() {
-                path.segments.insert(0, seg);
-            }
-        }
-        path
+        ast::Path { span, segments }
     }
 
     /// Constructs a qualified path.
@@ -625,7 +623,7 @@
         self.expr_path(self.path_ident(span, id))
     }
     fn expr_self(&self, span: Span) -> P<ast::Expr> {
-        self.expr_ident(span, keywords::SelfValue.ident())
+        self.expr_ident(span, keywords::SelfLower.ident())
     }
 
     fn expr_binary(&self, sp: Span, op: ast::BinOpKind,
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index cc8af70..67f3dc1 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -204,7 +204,7 @@
             path_str.push_str("::");
         }
 
-        if segment.ident.name != keywords::CrateRoot.name() &&
+        if segment.ident.name != keywords::PathRoot.name() &&
             segment.ident.name != keywords::DollarCrate.name()
         {
             path_str.push_str(&segment.ident.as_str())
@@ -1201,50 +1201,62 @@
 
 impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let mut expr = self.cfg.configure_expr(expr).into_inner();
-        expr.node = self.cfg.configure_expr_kind(expr.node);
+        let expr = self.cfg.configure_expr(expr);
+        expr.map(|mut expr| {
+            expr.node = self.cfg.configure_expr_kind(expr.node);
 
-        // ignore derives so they remain unused
-        let (attr, expr, after_derive) = self.classify_nonitem(expr);
+            // ignore derives so they remain unused
+            let (attr, expr, after_derive) = self.classify_nonitem(expr);
 
-        if attr.is_some() {
-            // collect the invoc regardless of whether or not attributes are permitted here
-            // expansion will eat the attribute so it won't error later
-            attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
+            if attr.is_some() {
+                // Collect the invoc regardless of whether or not attributes are permitted here
+                // expansion will eat the attribute so it won't error later.
+                attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
 
-            // AstFragmentKind::Expr requires the macro to emit an expression
-            return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
-                                     AstFragmentKind::Expr, after_derive).make_expr();
-        }
+                // AstFragmentKind::Expr requires the macro to emit an expression.
+                return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
+                                         AstFragmentKind::Expr, after_derive)
+                    .make_expr()
+                    .into_inner()
+            }
 
-        if let ast::ExprKind::Mac(mac) = expr.node {
-            self.check_attributes(&expr.attrs);
-            self.collect_bang(mac, expr.span, AstFragmentKind::Expr).make_expr()
-        } else {
-            P(noop_fold_expr(expr, self))
-        }
+            if let ast::ExprKind::Mac(mac) = expr.node {
+                self.check_attributes(&expr.attrs);
+                self.collect_bang(mac, expr.span, AstFragmentKind::Expr)
+                    .make_expr()
+                    .into_inner()
+            } else {
+                noop_fold_expr(expr, self)
+            }
+        })
     }
 
     fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
-        let mut expr = configure!(self, expr).into_inner();
-        expr.node = self.cfg.configure_expr_kind(expr.node);
+        let expr = configure!(self, expr);
+        expr.filter_map(|mut expr| {
+            expr.node = self.cfg.configure_expr_kind(expr.node);
 
-        // ignore derives so they remain unused
-        let (attr, expr, after_derive) = self.classify_nonitem(expr);
+            // Ignore derives so they remain unused.
+            let (attr, expr, after_derive) = self.classify_nonitem(expr);
 
-        if attr.is_some() {
-            attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
+            if attr.is_some() {
+                attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
 
-            return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
-                                     AstFragmentKind::OptExpr, after_derive).make_opt_expr();
-        }
+                return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
+                                         AstFragmentKind::OptExpr, after_derive)
+                    .make_opt_expr()
+                    .map(|expr| expr.into_inner())
+            }
 
-        if let ast::ExprKind::Mac(mac) = expr.node {
-            self.check_attributes(&expr.attrs);
-            self.collect_bang(mac, expr.span, AstFragmentKind::OptExpr).make_opt_expr()
-        } else {
-            Some(P(noop_fold_expr(expr, self)))
-        }
+            if let ast::ExprKind::Mac(mac) = expr.node {
+                self.check_attributes(&expr.attrs);
+                self.collect_bang(mac, expr.span, AstFragmentKind::OptExpr)
+                    .make_opt_expr()
+                    .map(|expr| expr.into_inner())
+            } else {
+                Some(noop_fold_expr(expr, self))
+            }
+        })
     }
 
     fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index c6e0adb..9181899 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -353,27 +353,27 @@
     impl<'a> ExtParseUtils for ExtCtxt<'a> {
         fn parse_item(&self, s: String) -> P<ast::Item> {
             panictry!(parse::parse_item_from_source_str(
-                FileName::QuoteExpansion,
+                FileName::quote_expansion_source_code(&s),
                 s,
                 self.parse_sess())).expect("parse error")
         }
 
         fn parse_stmt(&self, s: String) -> ast::Stmt {
             panictry!(parse::parse_stmt_from_source_str(
-                FileName::QuoteExpansion,
+                FileName::quote_expansion_source_code(&s),
                 s,
                 self.parse_sess())).expect("parse error")
         }
 
         fn parse_expr(&self, s: String) -> P<ast::Expr> {
             panictry!(parse::parse_expr_from_source_str(
-                FileName::QuoteExpansion,
+                FileName::quote_expansion_source_code(&s),
                 s,
                 self.parse_sess()))
         }
 
         fn parse_tts(&self, s: String) -> Vec<TokenTree> {
-            let source_name = FileName::QuoteExpansion;
+            let source_name = FileName::quote_expansion_source_code(&s);
             parse::parse_stream_from_source_str(source_name, s, self.parse_sess(), None)
                 .into_trees().collect()
         }
@@ -703,7 +703,6 @@
         token::At           => "At",
         token::Dot          => "Dot",
         token::DotDot       => "DotDot",
-        token::DotEq        => "DotEq",
         token::DotDotDot    => "DotDotDot",
         token::DotDotEq     => "DotDotEq",
         token::Comma        => "Comma",
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index e1ba889..75e2508 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -182,9 +182,12 @@
             DummyResult::expr(sp)
         }
         Ok(..) => {
-            // Add this input file to the code map to make it available as
-            // dependency information, but don't enter it's contents
-            cx.source_map().new_source_file(file.into(), String::new());
+            let src = match String::from_utf8(bytes.clone()) {
+                Ok(contents) => contents,
+                Err(..) => "".to_string()
+            };
+
+            cx.source_map().new_source_file(file.into(), src);
 
             base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::new(bytes))))
         }
@@ -201,6 +204,7 @@
         let callsite = sp.source_callsite();
         let mut path = match cx.source_map().span_to_unmapped_path(callsite) {
             FileName::Real(path) => path,
+            FileName::DocTest(path, _) => path,
             other => panic!("cannot resolve relative path in non-file source `{}`", other),
         };
         path.pop();
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 8fd9590..68d94b4 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -309,7 +309,7 @@
         vec![]
     } else {
         let empty_matches = Rc::new(SmallVec::new());
-        vec![empty_matches.clone(); len]
+        vec![empty_matches; len]
     }.into_boxed_slice()
 }
 
diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs
index 2184867..a7415e8 100644
--- a/src/libsyntax/ext/tt/quoted.rs
+++ b/src/libsyntax/ext/tt/quoted.rs
@@ -11,13 +11,13 @@
 use ast::NodeId;
 use early_buffered_lints::BufferedEarlyLintId;
 use ext::tt::macro_parser;
-use feature_gate::{self, emit_feature_err, Features, GateIssue};
+use feature_gate::Features;
 use parse::{token, ParseSess};
 use print::pprust;
 use symbol::keywords;
 use syntax_pos::{edition::Edition, BytePos, Span};
 use tokenstream::{self, DelimSpan};
-use {ast, attr};
+use ast;
 
 use rustc_data_structures::sync::Lrc;
 use std::iter::Peekable;
@@ -444,7 +444,6 @@
             macro_node_id,
         ),
         Edition::Edition2018 => parse_sep_and_kleene_op_2018(input, span, sess, features, attrs),
-        _ => unimplemented!(),
     }
 }
 
@@ -566,8 +565,8 @@
     input: &mut Peekable<I>,
     span: Span,
     sess: &ParseSess,
-    features: &Features,
-    attrs: &[ast::Attribute],
+    _features: &Features,
+    _attrs: &[ast::Attribute],
 ) -> (Option<token::Token>, KleeneOp)
 where
     I: Iterator<Item = tokenstream::TokenTree>,
@@ -575,23 +574,8 @@
     // We basically look at two token trees here, denoted as #1 and #2 below
     let span = match parse_kleene_op(input, span) {
         // #1 is a `?` (needs feature gate)
-        Ok(Ok((op, op1_span))) if op == KleeneOp::ZeroOrOne => {
-            if !features.macro_at_most_once_rep
-                && !attr::contains_name(attrs, "allow_internal_unstable")
-            {
-                let explain = feature_gate::EXPLAIN_MACRO_AT_MOST_ONCE_REP;
-                emit_feature_err(
-                    sess,
-                    "macro_at_most_once_rep",
-                    op1_span,
-                    GateIssue::Language,
-                    explain,
-                );
-
-                op1_span
-            } else {
-                return (None, op);
-            }
+        Ok(Ok((op, _op1_span))) if op == KleeneOp::ZeroOrOne => {
+            return (None, op);
         }
 
         // #1 is a `+` or `*` KleeneOp
@@ -600,24 +584,12 @@
         // #1 is a separator followed by #2, a KleeneOp
         Ok(Err((tok, span))) => match parse_kleene_op(input, span) {
             // #2 is the `?` Kleene op, which does not take a separator (error)
-            Ok(Ok((op, op2_span))) if op == KleeneOp::ZeroOrOne => {
+            Ok(Ok((op, _op2_span))) if op == KleeneOp::ZeroOrOne => {
                 // Error!
-
-                if !features.macro_at_most_once_rep
-                    && !attr::contains_name(attrs, "allow_internal_unstable")
-                {
-                    // FIXME: when `?` as a Kleene op is stabilized, we only need the "does not
-                    // take a macro separator" error (i.e. the `else` case).
-                    sess.span_diagnostic
-                        .struct_span_err(op2_span, "expected `*` or `+`")
-                        .note("`?` is not a macro repetition operator")
-                        .emit();
-                } else {
-                    sess.span_diagnostic.span_err(
-                        span,
-                        "the `?` macro repetition operator does not take a separator",
-                    );
-                }
+                sess.span_diagnostic.span_err(
+                    span,
+                    "the `?` macro repetition operator does not take a separator",
+                );
 
                 // Return a dummy
                 return (None, KleeneOp::ZeroOrMore);
@@ -638,13 +610,8 @@
     };
 
     // If we ever get to this point, we have experienced an "unexpected token" error
-
-    if !features.macro_at_most_once_rep && !attr::contains_name(attrs, "allow_internal_unstable") {
-        sess.span_diagnostic.span_err(span, "expected `*` or `+`");
-    } else {
-        sess.span_diagnostic
-            .span_err(span, "expected one of: `*`, `+`, or `?`");
-    }
+    sess.span_diagnostic
+        .span_err(span, "expected one of: `*`, `+`, or `?`");
 
     // Return a dummy
     (None, KleeneOp::ZeroOrMore)
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 7356776..5e0176d 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -53,8 +53,7 @@
         /// 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<Edition>, fn(&mut Features, Span))] =
+            &[(&str, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
             &[$((stringify!($feature), $ver, $issue, $edition, set!($feature))),+];
 
         /// A set of features to be used by later passes.
@@ -393,9 +392,6 @@
     // `extern` in paths
     (active, extern_in_paths, "1.23.0", Some(55600), None),
 
-    // Use `?` as the Kleene "at most one" operator
-    (active, macro_at_most_once_rep, "1.25.0", Some(48075), None),
-
     // Infer static outlives requirements; RFC 2093
     (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
 
@@ -442,8 +438,8 @@
     // 'a: { break 'a; }
     (active, label_break_value, "1.28.0", Some(48594), None),
 
-    // Integer match exhaustiveness checking
-    (active, exhaustive_integer_patterns, "1.30.0", Some(50907), None),
+    // Exhaustive pattern matching on `usize` and `isize`.
+    (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
 
     // #[doc(keyword = "...")]
     (active, doc_keyword, "1.28.0", Some(51315), None),
@@ -465,9 +461,6 @@
     // Allows `use x::y;` to resolve through `self::x`, not just `::x`
     (active, uniform_paths, "1.30.0", Some(53130), None),
 
-    // Allows `Self` in type definitions
-    (active, self_in_typedefs, "1.30.0", Some(49303), None),
-
     // Allows unsized rvalues at arguments and parameters
     (active, unsized_locals, "1.30.0", Some(48055), None),
 
@@ -478,9 +471,6 @@
     // Non-builtin attributes in inner attribute position
     (active, custom_inner_attributes, "1.30.0", Some(54726), None),
 
-    // Self struct constructor  (RFC 2302)
-    (active, self_struct_ctor, "1.30.0", Some(51994), None),
-
     // allow mixing of bind-by-move in patterns and references to
     // those identifiers in guards, *if* we are using MIR-borrowck
     // (aka NLL). Essentially this means you need to be on
@@ -498,6 +488,12 @@
 
     // `reason = ` in lint attributes and `expect` lint attribute
     (active, lint_reasons, "1.31.0", Some(54503), None),
+
+    // `extern crate self as foo;` puts local crate root into extern prelude under name `foo`.
+    (active, extern_crate_self, "1.31.0", Some(56409), None),
+
+    // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
+    (active, min_const_unsafe_fn, "1.31.0", Some(55607), None),
 );
 
 declare_features! (
@@ -678,20 +674,28 @@
     (accepted, extern_prelude, "1.30.0", Some(44660), None),
     // Parentheses in patterns
     (accepted, pattern_parentheses, "1.31.0", Some(51087), None),
-    // Allows the definition of `const fn` functions.
+    // Allows the definition of `const fn` functions
     (accepted, min_const_fn, "1.31.0", Some(53555), None),
     // Scoped lints
     (accepted, tool_lints, "1.31.0", Some(44690), None),
     // impl<I:Iterator> Iterator for &mut Iterator
     // impl Debug for Foo<'_>
     (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None),
-    // `extern crate foo as bar;` puts `bar` into extern prelude.
+    // `extern crate foo as bar;` puts `bar` into extern prelude
     (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
     // Allows use of the :literal macro fragment specifier (RFC 1576)
     (accepted, macro_literal_matcher, "1.31.0", Some(35625), None),
+    // Integer match exhaustiveness checking (RFC 2591)
+    (accepted, exhaustive_integer_patterns, "1.32.0", Some(50907), None),
+    // Use `?` as the Kleene "at most one" operator
+    (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
+    // `Self` struct constructor (RFC 2302)
+    (accepted, self_struct_ctor, "1.32.0", Some(51994), None),
+    // `Self` in type definitions (RFC 2300)
+    (accepted, self_in_typedefs, "1.32.0", Some(49303), None),
 );
 
-// If you change this, please modify src/doc/unstable-book as well. You must
+// If you change this, please modify `src/doc/unstable-book` as well. You must
 // move that documentation into the relevant place in the other docs, and
 // remove the chapter on the flag.
 
@@ -769,7 +773,7 @@
 }
 
 // Attributes that have a special meaning to rustc or rustdoc
-pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGate)] = &[
+pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeGate)] = &[
     // Normal attributes
 
     ("warn", Normal, Ungated),
@@ -1123,8 +1127,8 @@
     ("proc_macro_attribute", Normal, Ungated),
     ("proc_macro", Normal, Ungated),
 
-    ("rustc_derive_registrar", Normal, Gated(Stability::Unstable,
-                                             "rustc_derive_registrar",
+    ("rustc_proc_macro_decls", Normal, Gated(Stability::Unstable,
+                                             "rustc_proc_macro_decls",
                                              "used internally by rustc",
                                              cfg_fn!(rustc_attrs))),
 
@@ -1383,53 +1387,50 @@
 
 }
 
-const EXPLAIN_BOX_SYNTAX: &'static str =
+const EXPLAIN_BOX_SYNTAX: &str =
     "box expression syntax is experimental; you can call `Box::new` instead.";
 
-pub const EXPLAIN_STMT_ATTR_SYNTAX: &'static str =
+pub const EXPLAIN_STMT_ATTR_SYNTAX: &str =
     "attributes on expressions are experimental.";
 
-pub const EXPLAIN_ASM: &'static str =
+pub const EXPLAIN_ASM: &str =
     "inline assembly is not stable enough for use and is subject to change";
 
-pub const EXPLAIN_GLOBAL_ASM: &'static str =
+pub const EXPLAIN_GLOBAL_ASM: &str =
     "`global_asm!` is not stable enough for use and is subject to change";
 
-pub const EXPLAIN_CUSTOM_TEST_FRAMEWORKS: &'static str =
+pub const EXPLAIN_CUSTOM_TEST_FRAMEWORKS: &str =
     "custom test frameworks are an unstable feature";
 
-pub const EXPLAIN_LOG_SYNTAX: &'static str =
+pub const EXPLAIN_LOG_SYNTAX: &str =
     "`log_syntax!` is not stable enough for use and is subject to change";
 
-pub const EXPLAIN_CONCAT_IDENTS: &'static str =
+pub const EXPLAIN_CONCAT_IDENTS: &str =
     "`concat_idents` is not stable enough for use and is subject to change";
 
-pub const EXPLAIN_FORMAT_ARGS_NL: &'static str =
+pub const EXPLAIN_FORMAT_ARGS_NL: &str =
     "`format_args_nl` is only for internal language use and is subject to change";
 
-pub const EXPLAIN_TRACE_MACROS: &'static str =
+pub const EXPLAIN_TRACE_MACROS: &str =
     "`trace_macros` is not stable enough for use and is subject to change";
-pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &'static str =
+pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str =
     "allow_internal_unstable side-steps feature gating and stability checks";
-pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &'static str =
+pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str =
     "allow_internal_unsafe side-steps the unsafe_code lint";
 
-pub const EXPLAIN_CUSTOM_DERIVE: &'static str =
+pub const EXPLAIN_CUSTOM_DERIVE: &str =
     "`#[derive]` for custom traits is deprecated and will be removed in the future.";
 
-pub const EXPLAIN_DEPR_CUSTOM_DERIVE: &'static str =
+pub const EXPLAIN_DEPR_CUSTOM_DERIVE: &str =
     "`#[derive]` for custom traits is deprecated and will be removed in the future. \
     Prefer using procedural macro custom derive.";
 
-pub const EXPLAIN_DERIVE_UNDERSCORE: &'static str =
+pub const EXPLAIN_DERIVE_UNDERSCORE: &str =
     "attributes of the form `#[derive_*]` are reserved for the compiler";
 
-pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &'static str =
+pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str =
     "unsized tuple coercion is not stable enough for use and is subject to change";
 
-pub const EXPLAIN_MACRO_AT_MOST_ONCE_REP: &'static str =
-    "using the `?` macro Kleene operator for \"at most one\" repetition is unstable";
-
 struct PostExpansionVisitor<'a> {
     context: &'a Context<'a>,
 }
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 9bbd59e..3c66db0 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -20,7 +20,6 @@
        test(attr(deny(warnings))))]
 
 #![feature(crate_visibility_modifier)]
-#![feature(macro_at_most_once_rep)]
 #![feature(nll)]
 #![feature(rustc_attrs)]
 #![feature(rustc_diagnostic_macros)]
@@ -174,7 +173,6 @@
 pub mod ptr;
 pub mod show_span;
 pub mod std_inject;
-pub mod str;
 pub use syntax_pos::edition;
 pub use syntax_pos::symbol;
 pub mod test;
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index a240604..4ff6048 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -22,8 +22,8 @@
     NotPermitted { reason: &'a str },
 }
 
-const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &'static str = "an inner attribute is not \
-                                                             permitted in this context";
+const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
+                                                     permitted in this context";
 
 impl<'a> Parser<'a> {
     /// Parse attributes that appear before an item
diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs
index 172a48d..d303932 100644
--- a/src/libsyntax/parse/lexer/comments.rs
+++ b/src/libsyntax/parse/lexer/comments.rs
@@ -16,7 +16,6 @@
 use parse::lexer::{is_block_doc_comment, is_pattern_whitespace};
 use parse::lexer::{self, ParseSess, StringReader, TokenAndSpan};
 use print::pprust;
-use str::char_at;
 
 use std::io::Read;
 use std::usize;
@@ -207,20 +206,14 @@
 /// Otherwise returns Some(k) where k is first char offset after that leading
 /// whitespace.  Note k may be outside bounds of s.
 fn all_whitespace(s: &str, col: CharPos) -> Option<usize> {
-    let len = s.len();
-    let mut col = col.to_usize();
-    let mut cursor: usize = 0;
-
-    while col > 0 && cursor < len {
-        let ch = char_at(s, cursor);
+    let mut idx = 0;
+    for (i, ch) in s.char_indices().take(col.to_usize()) {
         if !ch.is_whitespace() {
             return None;
         }
-        cursor += ch.len_utf8();
-        col -= 1;
+        idx = i + ch.len_utf8();
     }
-
-    Some(cursor)
+    Some(idx)
 }
 
 fn trim_whitespace_prefix_and_push_line(lines: &mut Vec<String>, s: String, col: CharPos) {
@@ -228,7 +221,7 @@
     let s1 = match all_whitespace(&s[..], col) {
         Some(col) => {
             if col < len {
-                (&s[col..len]).to_string()
+                s[col..len].to_string()
             } else {
                 String::new()
             }
@@ -247,20 +240,13 @@
     let mut lines: Vec<String> = Vec::new();
 
     // Count the number of chars since the start of the line by rescanning.
-    let mut src_index = rdr.src_index(rdr.source_file.line_begin_pos(rdr.pos));
+    let src_index = rdr.src_index(rdr.source_file.line_begin_pos(rdr.pos));
     let end_src_index = rdr.src_index(rdr.pos);
     assert!(src_index <= end_src_index,
         "src_index={}, end_src_index={}, line_begin_pos={}",
         src_index, end_src_index, rdr.source_file.line_begin_pos(rdr.pos).to_u32());
-    let mut n = 0;
 
-    while src_index < end_src_index {
-        let c = char_at(&rdr.src, src_index);
-        src_index += c.len_utf8();
-        n += 1;
-    }
-
-    let col = CharPos(n);
+    let col = CharPos(rdr.src[src_index..end_src_index].chars().count());
 
     rdr.bump();
     rdr.bump();
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 0584cd5..80227fd 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -13,12 +13,12 @@
 use source_map::{SourceMap, FilePathMapping};
 use errors::{Applicability, FatalError, Diagnostic, DiagnosticBuilder};
 use parse::{token, ParseSess};
-use str::char_at;
 use symbol::{Symbol, keywords};
 use core::unicode::property::Pattern_White_Space;
 
 use std::borrow::Cow;
 use std::char;
+use std::iter;
 use std::mem::replace;
 use rustc_data_structures::sync::Lrc;
 
@@ -60,11 +60,11 @@
     // cache a direct reference to the source text, so that we don't have to
     // retrieve it via `self.source_file.src.as_ref().unwrap()` all the time.
     src: Lrc<String>,
-    /// Stack of open delimiters and their spans. Used for error message.
     token: token::Token,
     span: Span,
     /// The raw source span which *does not* take `override_span` into account
     span_src_raw: Span,
+    /// Stack of open delimiters and their spans. Used for error message.
     open_braces: Vec<(token::DelimToken, Span)>,
     /// The type and spans for all braces
     ///
@@ -459,45 +459,42 @@
 
     /// Converts CRLF to LF in the given string, raising an error on bare CR.
     fn translate_crlf<'b>(&self, start: BytePos, s: &'b str, errmsg: &'b str) -> Cow<'b, str> {
-        let mut i = 0;
-        while i < s.len() {
-            let ch = char_at(s, i);
-            let next = i + ch.len_utf8();
+        let mut chars = s.char_indices().peekable();
+        while let Some((i, ch)) = chars.next() {
             if ch == '\r' {
-                if next < s.len() && char_at(s, next) == '\n' {
-                    return translate_crlf_(self, start, s, errmsg, i).into();
+                if let Some((lf_idx, '\n')) = chars.peek() {
+                    return translate_crlf_(self, start, s, *lf_idx, chars, errmsg).into();
                 }
                 let pos = start + BytePos(i as u32);
-                let end_pos = start + BytePos(next as u32);
+                let end_pos = start + BytePos((i + ch.len_utf8()) as u32);
                 self.err_span_(pos, end_pos, errmsg);
             }
-            i = next;
         }
         return s.into();
 
         fn translate_crlf_(rdr: &StringReader,
                            start: BytePos,
                            s: &str,
-                           errmsg: &str,
-                           mut i: usize)
+                           mut j: usize,
+                           mut chars: iter::Peekable<impl Iterator<Item = (usize, char)>>,
+                           errmsg: &str)
                            -> String {
             let mut buf = String::with_capacity(s.len());
-            let mut j = 0;
-            while i < s.len() {
-                let ch = char_at(s, i);
-                let next = i + ch.len_utf8();
+            // Skip first CR
+            buf.push_str(&s[.. j - 1]);
+            while let Some((i, ch)) = chars.next() {
                 if ch == '\r' {
                     if j < i {
                         buf.push_str(&s[j..i]);
                     }
+                    let next = i + ch.len_utf8();
                     j = next;
-                    if next >= s.len() || char_at(s, next) != '\n' {
+                    if chars.peek().map(|(_, ch)| *ch) != Some('\n') {
                         let pos = start + BytePos(i as u32);
                         let end_pos = start + BytePos(next as u32);
                         rdr.err_span_(pos, end_pos, errmsg);
                     }
                 }
-                i = next;
             }
             if j < s.len() {
                 buf.push_str(&s[j..]);
@@ -506,8 +503,7 @@
         }
     }
 
-    /// Advance the StringReader by one character. If a newline is
-    /// discovered, add it to the SourceFile's list of line start offsets.
+    /// Advance the StringReader by one character.
     crate fn bump(&mut self) {
         let next_src_index = self.src_index(self.next_pos);
         if next_src_index < self.end_src_index {
@@ -1859,6 +1855,11 @@
     (c > '\x7f' && c.is_xid_continue())
 }
 
+#[inline]
+fn char_at(s: &str, byte: usize) -> char {
+    s[byte..].chars().next().unwrap()
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -1899,7 +1900,7 @@
                  sess: &'a ParseSess,
                  teststr: String)
                  -> StringReader<'a> {
-        let sf = sm.new_source_file(PathBuf::from("zebra.rs").into(), teststr);
+        let sf = sm.new_source_file(PathBuf::from(teststr.clone()).into(), teststr);
         StringReader::new(sess, sf, None)
     }
 
diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs
index 03bf1b5..8a620c8 100644
--- a/src/libsyntax/parse/lexer/unicode_chars.rs
+++ b/src/libsyntax/parse/lexer/unicode_chars.rs
@@ -306,7 +306,7 @@
     ('>', "Fullwidth Greater-Than Sign", '>'), ];
 
 
-const ASCII_ARRAY: &'static [(char, &'static str)] = &[
+const ASCII_ARRAY: &[(char, &str)] = &[
     (' ', "Space"),
     ('_', "Underscore"),
     ('-', "Minus/Hyphen"),
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index ac972f2..866dba2 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -19,7 +19,6 @@
 use feature_gate::UnstableFeatures;
 use parse::parser::Parser;
 use ptr::P;
-use str::char_at;
 use symbol::Symbol;
 use tokenstream::{TokenStream, TokenTree};
 use diagnostics::plugin::ErrorMap;
@@ -436,9 +435,7 @@
 
 // check if `s` looks like i32 or u1234 etc.
 fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
-    s.len() > 1 &&
-        first_chars.contains(&char_at(s, 0)) &&
-        s[1..].chars().all(|c| '0' <= c && c <= '9')
+    s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
 }
 
 macro_rules! err {
@@ -645,11 +642,11 @@
     let orig = s;
     let mut ty = ast::LitIntType::Unsuffixed;
 
-    if char_at(s, 0) == '0' && s.len() > 1 {
-        match char_at(s, 1) {
-            'x' => base = 16,
-            'o' => base = 8,
-            'b' => base = 2,
+    if s.starts_with('0') && s.len() > 1 {
+        match s.as_bytes()[1] {
+            b'x' => base = 16,
+            b'o' => base = 8,
+            b'b' => base = 2,
             _ => { }
         }
     }
@@ -977,23 +974,25 @@
         with_globals(|| {
             let sess = ParseSess::new(FilePathMapping::empty());
 
-            let name = FileName::Custom("source".to_string());
+            let name_1 = FileName::Custom("crlf_source_1".to_string());
             let source = "/// doc comment\r\nfn foo() {}".to_string();
-            let item = parse_item_from_source_str(name.clone(), source, &sess)
+            let item = parse_item_from_source_str(name_1, source, &sess)
                 .unwrap().unwrap();
             let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
             assert_eq!(doc, "/// doc comment");
 
+            let name_2 = FileName::Custom("crlf_source_2".to_string());
             let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
-            let item = parse_item_from_source_str(name.clone(), source, &sess)
+            let item = parse_item_from_source_str(name_2, source, &sess)
                 .unwrap().unwrap();
             let docs = item.attrs.iter().filter(|a| a.path == "doc")
                         .map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
             let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
             assert_eq!(&docs[..], b);
 
+            let name_3 = FileName::Custom("clrf_source_3".to_string());
             let source = "/** doc comment\r\n *  with CRLF */\r\nfn foo() {}".to_string();
-            let item = parse_item_from_source_str(name, source, &sess).unwrap().unwrap();
+            let item = parse_item_from_source_str(name_3, source, &sess).unwrap().unwrap();
             let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
             assert_eq!(doc, "/** doc comment\n *  with CRLF */");
         });
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index c82ebd6..c7eaf4d 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2017,6 +2017,17 @@
         }
     }
 
+    fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> {
+        match self.token {
+            token::Ident(ident, false) if ident.name == keywords::Underscore.name() => {
+                let span = self.span;
+                self.bump();
+                Ok(Ident::new(ident.name, span))
+            }
+            _ => self.parse_ident(),
+        }
+    }
+
     /// Parses qualified path.
     /// Assumes that the leading `<` has been parsed already.
     ///
@@ -2082,7 +2093,7 @@
         let mut segments = Vec::new();
         let mod_sep_ctxt = self.span.ctxt();
         if self.eat(&token::ModSep) {
-            segments.push(PathSegment::crate_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
+            segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
         }
         self.parse_path_segments(&mut segments, style, enable_warning)?;
 
@@ -2791,7 +2802,7 @@
                             s.print_usize(float.trunc() as usize)?;
                             s.pclose()?;
                             s.s.word(".")?;
-                            s.s.word(fstr.splitn(2, ".").last().unwrap())
+                            s.s.word(fstr.splitn(2, ".").last().unwrap().to_string())
                         });
                         err.span_suggestion_with_applicability(
                             lo.to(self.prev_span),
@@ -3145,7 +3156,7 @@
                     RangeLimits::Closed
                 };
 
-                let r = try!(self.mk_range(Some(lhs), rhs, limits));
+                let r = self.mk_range(Some(lhs), rhs, limits)?;
                 lhs = self.mk_expr(lhs_span.to(rhs_span), r, ThinVec::new());
                 break
             }
@@ -3353,9 +3364,7 @@
             RangeLimits::Closed
         };
 
-        let r = try!(self.mk_range(None,
-                                   opt_end,
-                                   limits));
+        let r = self.mk_range(None, opt_end, limits)?;
         Ok(self.mk_expr(lo.to(hi), r, attrs))
     }
 
@@ -3952,7 +3961,7 @@
                     );
                     err.emit();
                 }
-                self.bump();  // `..` || `...`:w
+                self.bump();  // `..` || `...`
 
                 if self.token == token::CloseDelim(token::Brace) {
                     etc_span = Some(etc_sp);
@@ -3972,7 +3981,7 @@
                     ate_comma = true;
                 }
 
-                etc_span = Some(etc_sp);
+                etc_span = Some(etc_sp.until(self.span));
                 if self.token == token::CloseDelim(token::Brace) {
                     // If the struct looks otherwise well formed, recover and continue.
                     if let Some(sp) = comma_sp {
@@ -5172,8 +5181,12 @@
     /// Parses (possibly empty) list of lifetime and type parameters, possibly including
     /// trailing comma and erroneous trailing attributes.
     crate fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
+        let mut lifetimes = Vec::new();
         let mut params = Vec::new();
-        let mut seen_ty_param = false;
+        let mut seen_ty_param: Option<Span> = None;
+        let mut last_comma_span = None;
+        let mut bad_lifetime_pos = vec![];
+        let mut suggestions = vec![];
         loop {
             let attrs = self.parse_outer_attributes()?;
             if self.check_lifetime() {
@@ -5184,25 +5197,42 @@
                 } else {
                     Vec::new()
                 };
-                params.push(ast::GenericParam {
+                lifetimes.push(ast::GenericParam {
                     ident: lifetime.ident,
                     id: lifetime.id,
                     attrs: attrs.into(),
                     bounds,
                     kind: ast::GenericParamKind::Lifetime,
                 });
-                if seen_ty_param {
-                    self.span_err(self.prev_span,
-                        "lifetime parameters must be declared prior to type parameters");
+                if let Some(sp) = seen_ty_param {
+                    let param_span = self.prev_span;
+                    let ate_comma = self.eat(&token::Comma);
+                    let remove_sp = if ate_comma {
+                        param_span.until(self.span)
+                    } else {
+                        last_comma_span.unwrap_or(param_span).to(param_span)
+                    };
+                    bad_lifetime_pos.push(param_span);
+
+                    if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) {
+                        suggestions.push((remove_sp, String::new()));
+                        suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet)));
+                    }
+                    if ate_comma {
+                        last_comma_span = Some(self.prev_span);
+                        continue
+                    }
                 }
             } else if self.check_ident() {
                 // Parse type parameter.
                 params.push(self.parse_ty_param(attrs)?);
-                seen_ty_param = true;
+                if seen_ty_param.is_none() {
+                    seen_ty_param = Some(self.prev_span);
+                }
             } else {
                 // Check for trailing attributes and stop parsing.
                 if !attrs.is_empty() {
-                    let param_kind = if seen_ty_param { "type" } else { "lifetime" };
+                    let param_kind = if seen_ty_param.is_some() { "type" } else { "lifetime" };
                     self.span_err(attrs[0].span,
                         &format!("trailing attribute after {} parameters", param_kind));
                 }
@@ -5212,8 +5242,24 @@
             if !self.eat(&token::Comma) {
                 break
             }
+            last_comma_span = Some(self.prev_span);
         }
-        Ok(params)
+        if !bad_lifetime_pos.is_empty() {
+            let mut err = self.struct_span_err(
+                bad_lifetime_pos,
+                "lifetime parameters must be declared prior to type parameters",
+            );
+            if !suggestions.is_empty() {
+                err.multipart_suggestion_with_applicability(
+                    "move the lifetime parameter prior to the first type parameter",
+                    suggestions,
+                    Applicability::MachineApplicable,
+                );
+            }
+            err.emit();
+        }
+        lifetimes.extend(params);  // ensure the correct order of lifetimes and type params
+        Ok(lifetimes)
     }
 
     /// Parse a set of optional generic type parameter declarations. Where
@@ -5473,7 +5519,7 @@
             _ => unreachable!()
         };
         let isolated_self = |this: &mut Self, n| {
-            this.look_ahead(n, |t| t.is_keyword(keywords::SelfValue)) &&
+            this.look_ahead(n, |t| t.is_keyword(keywords::SelfLower)) &&
             this.look_ahead(n + 1, |t| t != &token::ModSep)
         };
 
@@ -6245,9 +6291,10 @@
         self.parse_single_struct_field(lo, vis, attrs)
     }
 
-    /// Parse `pub`, `pub(crate)` and `pub(in path)` plus shortcuts `pub(self)` for `pub(in self)`
-    /// and `pub(super)` for `pub(in super)`.  If the following element can't be a tuple (i.e. it's
-    /// a function definition, it's not a tuple struct field) and the contents within the parens
+    /// Parse `pub`, `pub(crate)` and `pub(in path)` plus shortcuts `crate` for `pub(crate)`,
+    /// `pub(self)` for `pub(in self)` and `pub(super)` for `pub(in super)`.
+    /// If the following element can't be a tuple (i.e. it's a function definition,
+    /// it's not a tuple struct field) and the contents within the parens
     /// isn't valid, emit a proper diagnostic.
     pub fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibility> {
         maybe_whole!(self, NtVis, |x| x);
@@ -6294,7 +6341,7 @@
                 return Ok(vis)
             } else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren)) &&
                       self.look_ahead(1, |t| t.is_keyword(keywords::Super) ||
-                                             t.is_keyword(keywords::SelfValue))
+                                             t.is_keyword(keywords::SelfLower))
             {
                 // `pub(self)` or `pub(super)`
                 self.bump(); // `(`
@@ -6398,13 +6445,7 @@
     }
 
     fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
-        let id = match self.token {
-                token::Ident(ident, false) if ident.name == keywords::Underscore.name() => {
-                    self.bump(); // `_`
-                    ident.gensym()
-                    },
-                _ => self.parse_ident()?,
-            };
+        let id = if m.is_none() { self.parse_ident_or_underscore() } else { self.parse_ident() }?;
         self.expect(&token::Colon)?;
         let ty = self.parse_ty()?;
         self.expect(&token::Eq)?;
@@ -6746,7 +6787,11 @@
         let error_msg = "crate name using dashes are not valid in `extern crate` statements";
         let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
                               in the code";
-        let mut ident = self.parse_ident()?;
+        let mut ident = if self.token.is_keyword(keywords::SelfLower) {
+            self.parse_path_segment_ident()
+        } else {
+            self.parse_ident()
+        }?;
         let mut idents = vec![];
         let mut replacement = vec![];
         let mut fixed_crate_name = false;
@@ -7645,7 +7690,7 @@
             let mod_sep_ctxt = self.span.ctxt();
             if self.eat(&token::ModSep) {
                 prefix.segments.push(
-                    PathSegment::crate_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))
+                    PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))
                 );
             }
 
@@ -7685,13 +7730,7 @@
 
     fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
         if self.eat_keyword(keywords::As) {
-            match self.token {
-                token::Ident(ident, false) if ident.name == keywords::Underscore.name() => {
-                    self.bump(); // `_`
-                    Ok(Some(ident.gensym()))
-                }
-                _ => self.parse_ident().map(Some),
-            }
+            self.parse_ident_or_underscore().map(Some)
         } else {
             Ok(None)
         }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 46fc645..04a791f 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -163,7 +163,6 @@
     DotDot,
     DotDotDot,
     DotDotEq,
-    DotEq, // HACK(durka42) never produced by the parser, only used for libproc_macro
     Comma,
     Semi,
     Colon,
@@ -454,7 +453,6 @@
             Dot => match joint {
                 Dot => DotDot,
                 DotDot => DotDotDot,
-                DotEq => DotDotEq,
                 _ => return None,
             },
             DotDot => match joint {
@@ -477,7 +475,7 @@
                 _ => return None,
             },
 
-            Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotEq |
+            Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot |
             DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar |
             Question | OpenDelim(..) | CloseDelim(..) => return None,
 
@@ -547,7 +545,8 @@
         let tokens_for_real = nt.1.force(|| {
             // FIXME(#43081): Avoid this pretty-print + reparse hack
             let source = pprust::token_to_string(self);
-            parse_stream_from_source_str(FileName::MacroExpansion, source, sess, Some(span))
+            let filename = FileName::macro_expansion_source_code(&source);
+            parse_stream_from_source_str(filename, source, sess, Some(span))
         });
 
         // During early phases of the compiler the AST could get modified
@@ -606,7 +605,6 @@
             (&DotDot, &DotDot) |
             (&DotDotDot, &DotDotDot) |
             (&DotDotEq, &DotDotEq) |
-            (&DotEq, &DotEq) |
             (&Comma, &Comma) |
             (&Semi, &Semi) |
             (&Colon, &Colon) |
@@ -784,10 +782,12 @@
         assert_eq!(attr.style, ast::AttrStyle::Outer,
                    "inner attributes should prevent cached tokens from existing");
 
+        let source = pprust::attr_to_string(attr);
+        let macro_filename = FileName::macro_expansion_source_code(&source);
         if attr.is_sugared_doc {
             let stream = parse_stream_from_source_str(
-                FileName::MacroExpansion,
-                pprust::attr_to_string(attr),
+                macro_filename,
+                source,
                 sess,
                 Some(span),
             );
@@ -808,8 +808,8 @@
         // should eventually be removed.
         } else {
             let stream = parse_stream_from_source_str(
-                FileName::MacroExpansion,
-                pprust::path_to_string(&attr.path),
+                macro_filename,
+                source,
                 sess,
                 Some(span),
             );
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 086de35..aaed56d 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -140,13 +140,14 @@
 //! calculation, SCAN will write "infinity" to the size and let PRINT consume
 //! it.
 //!
-//! In this implementation (following the paper, again) the SCAN process is
-//! the method called `Printer::pretty_print`, and the 'PRINT' process is the method
-//! called `Printer::print`.
+//! In this implementation (following the paper, again) the SCAN process is the
+//! methods called `Printer::pretty_print_*`, and the 'PRINT' process is the
+//! method called `Printer::print`.
 
 use std::collections::VecDeque;
 use std::fmt;
 use std::io;
+use std::borrow::Cow;
 
 /// How to break. Described in more detail in the module docs.
 #[derive(Clone, Copy, PartialEq)]
@@ -169,7 +170,10 @@
 
 #[derive(Clone)]
 pub enum Token {
-    String(String, isize),
+    // In practice a string token contains either a `&'static str` or a
+    // `String`. `Cow` is overkill for this because we never modify the data,
+    // but it's more convenient than rolling our own more specialized type.
+    String(Cow<'static, str>, isize),
     Break(BreakToken),
     Begin(BeginToken),
     End,
@@ -309,84 +313,86 @@
     pub fn last_token(&mut self) -> Token {
         self.buf[self.right].token.clone()
     }
-    /// be very careful with this!
+
+    /// Be very careful with this!
     pub fn replace_last_token(&mut self, t: Token) {
         self.buf[self.right].token = t;
     }
-    pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
-        debug!("pp Vec<{},{}>", self.left, self.right);
-        match token {
-          Token::Eof => {
-            if !self.scan_stack.is_empty() {
-                self.check_stack(0);
-                self.advance_left()?;
-            }
-            self.indent(0);
-            Ok(())
-          }
-          Token::Begin(b) => {
-            if self.scan_stack.is_empty() {
-                self.left_total = 1;
-                self.right_total = 1;
-                self.left = 0;
-                self.right = 0;
-            } else {
-                self.advance_right();
-            }
-            debug!("pp Begin({})/buffer Vec<{},{}>",
-                   b.offset, self.left, self.right);
-            self.buf[self.right] = BufEntry { token: token, size: -self.right_total };
-            let right = self.right;
-            self.scan_push(right);
-            Ok(())
-          }
-          Token::End => {
-            if self.scan_stack.is_empty() {
-                debug!("pp End/print Vec<{},{}>", self.left, self.right);
-                self.print(token, 0)
-            } else {
-                debug!("pp End/buffer Vec<{},{}>", self.left, self.right);
-                self.advance_right();
-                self.buf[self.right] = BufEntry { token: token, size: -1 };
-                let right = self.right;
-                self.scan_push(right);
-                Ok(())
-            }
-          }
-          Token::Break(b) => {
-            if self.scan_stack.is_empty() {
-                self.left_total = 1;
-                self.right_total = 1;
-                self.left = 0;
-                self.right = 0;
-            } else {
-                self.advance_right();
-            }
-            debug!("pp Break({})/buffer Vec<{},{}>",
-                   b.offset, self.left, self.right);
+
+    fn pretty_print_eof(&mut self) -> io::Result<()> {
+        if !self.scan_stack.is_empty() {
             self.check_stack(0);
+            self.advance_left()?;
+        }
+        self.indent(0);
+        Ok(())
+    }
+
+    fn pretty_print_begin(&mut self, b: BeginToken) -> io::Result<()> {
+        if self.scan_stack.is_empty() {
+            self.left_total = 1;
+            self.right_total = 1;
+            self.left = 0;
+            self.right = 0;
+        } else {
+            self.advance_right();
+        }
+        debug!("pp Begin({})/buffer Vec<{},{}>",
+               b.offset, self.left, self.right);
+        self.buf[self.right] = BufEntry { token: Token::Begin(b), size: -self.right_total };
+        let right = self.right;
+        self.scan_push(right);
+        Ok(())
+    }
+
+    fn pretty_print_end(&mut self) -> io::Result<()> {
+        if self.scan_stack.is_empty() {
+            debug!("pp End/print Vec<{},{}>", self.left, self.right);
+            self.print_end()
+        } else {
+            debug!("pp End/buffer Vec<{},{}>", self.left, self.right);
+            self.advance_right();
+            self.buf[self.right] = BufEntry { token: Token::End, size: -1 };
             let right = self.right;
             self.scan_push(right);
-            self.buf[self.right] = BufEntry { token: token, size: -self.right_total };
-            self.right_total += b.blank_space;
             Ok(())
-          }
-          Token::String(s, len) => {
-            if self.scan_stack.is_empty() {
-                debug!("pp String('{}')/print Vec<{},{}>",
-                       s, self.left, self.right);
-                self.print(Token::String(s, len), len)
-            } else {
-                debug!("pp String('{}')/buffer Vec<{},{}>",
-                       s, self.left, self.right);
-                self.advance_right();
-                self.buf[self.right] = BufEntry { token: Token::String(s, len), size: len };
-                self.right_total += len;
-                self.check_stream()
-            }
-          }
         }
     }
+
+    fn pretty_print_break(&mut self, b: BreakToken) -> io::Result<()> {
+        if self.scan_stack.is_empty() {
+            self.left_total = 1;
+            self.right_total = 1;
+            self.left = 0;
+            self.right = 0;
+        } else {
+            self.advance_right();
+        }
+        debug!("pp Break({})/buffer Vec<{},{}>",
+               b.offset, self.left, self.right);
+        self.check_stack(0);
+        let right = self.right;
+        self.scan_push(right);
+        self.buf[self.right] = BufEntry { token: Token::Break(b), size: -self.right_total };
+        self.right_total += b.blank_space;
+        Ok(())
+    }
+
+    fn pretty_print_string(&mut self, s: Cow<'static, str>, len: isize) -> io::Result<()> {
+        if self.scan_stack.is_empty() {
+            debug!("pp String('{}')/print Vec<{},{}>",
+                   s, self.left, self.right);
+            self.print_string(s, len)
+        } else {
+            debug!("pp String('{}')/buffer Vec<{},{}>",
+                   s, self.left, self.right);
+            self.advance_right();
+            self.buf[self.right] = BufEntry { token: Token::String(s, len), size: len };
+            self.right_total += len;
+            self.check_stream()
+        }
+    }
+
     pub fn check_stream(&mut self) -> io::Result<()> {
         debug!("check_stream Vec<{}, {}> with left_total={}, right_total={}",
                self.left, self.right, self.left_total, self.right_total);
@@ -405,19 +411,24 @@
         }
         Ok(())
     }
+
     pub fn scan_push(&mut self, x: usize) {
         debug!("scan_push {}", x);
         self.scan_stack.push_front(x);
     }
+
     pub fn scan_pop(&mut self) -> usize {
         self.scan_stack.pop_front().unwrap()
     }
+
     pub fn scan_top(&mut self) -> usize {
         *self.scan_stack.front().unwrap()
     }
+
     pub fn scan_pop_bottom(&mut self) -> usize {
         self.scan_stack.pop_back().unwrap()
     }
+
     pub fn advance_right(&mut self) {
         self.right += 1;
         self.right %= self.buf_max_len;
@@ -427,6 +438,7 @@
         }
         assert_ne!(self.right, self.left);
     }
+
     pub fn advance_left(&mut self) -> io::Result<()> {
         debug!("advance_left Vec<{},{}>, sizeof({})={}", self.left, self.right,
                self.left, self.buf[self.left].size);
@@ -461,6 +473,7 @@
 
         Ok(())
     }
+
     pub fn check_stack(&mut self, k: isize) {
         if !self.scan_stack.is_empty() {
             let x = self.scan_top();
@@ -488,6 +501,7 @@
             }
         }
     }
+
     pub fn print_newline(&mut self, amount: isize) -> io::Result<()> {
         debug!("NEWLINE {}", amount);
         let ret = write!(self.out, "\n");
@@ -495,10 +509,12 @@
         self.indent(amount);
         ret
     }
+
     pub fn indent(&mut self, amount: isize) {
         debug!("INDENT {}", amount);
         self.pending_indentation += amount;
     }
+
     pub fn get_top(&mut self) -> PrintStackElem {
         match self.print_stack.last() {
             Some(el) => *el,
@@ -508,62 +524,50 @@
             }
         }
     }
-    pub fn print_str(&mut self, s: &str) -> io::Result<()> {
-        while self.pending_indentation > 0 {
-            write!(self.out, " ")?;
-            self.pending_indentation -= 1;
+
+    pub fn print_begin(&mut self, b: BeginToken, l: isize) -> io::Result<()> {
+        if l > self.space {
+            let col = self.margin - self.space + b.offset;
+            debug!("print Begin -> push broken block at col {}", col);
+            self.print_stack.push(PrintStackElem {
+                offset: col,
+                pbreak: PrintStackBreak::Broken(b.breaks)
+            });
+        } else {
+            debug!("print Begin -> push fitting block");
+            self.print_stack.push(PrintStackElem {
+                offset: 0,
+                pbreak: PrintStackBreak::Fits
+            });
         }
-        write!(self.out, "{}", s)
+        Ok(())
     }
-    pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
-        debug!("print {} {} (remaining line space={})", token, l,
-               self.space);
-        debug!("{}", buf_str(&self.buf,
-                             self.left,
-                             self.right,
-                             6));
-        match token {
-          Token::Begin(b) => {
-            if l > self.space {
-                let col = self.margin - self.space + b.offset;
-                debug!("print Begin -> push broken block at col {}", col);
-                self.print_stack.push(PrintStackElem {
-                    offset: col,
-                    pbreak: PrintStackBreak::Broken(b.breaks)
-                });
-            } else {
-                debug!("print Begin -> push fitting block");
-                self.print_stack.push(PrintStackElem {
-                    offset: 0,
-                    pbreak: PrintStackBreak::Fits
-                });
-            }
-            Ok(())
-          }
-          Token::End => {
-            debug!("print End -> pop End");
-            let print_stack = &mut self.print_stack;
-            assert!(!print_stack.is_empty());
-            print_stack.pop().unwrap();
-            Ok(())
-          }
-          Token::Break(b) => {
-            let top = self.get_top();
-            match top.pbreak {
-              PrintStackBreak::Fits => {
+
+    pub fn print_end(&mut self) -> io::Result<()> {
+        debug!("print End -> pop End");
+        let print_stack = &mut self.print_stack;
+        assert!(!print_stack.is_empty());
+        print_stack.pop().unwrap();
+        Ok(())
+    }
+
+    pub fn print_break(&mut self, b: BreakToken, l: isize) -> io::Result<()> {
+        let top = self.get_top();
+        match top.pbreak {
+            PrintStackBreak::Fits => {
                 debug!("print Break({}) in fitting block", b.blank_space);
                 self.space -= b.blank_space;
                 self.indent(b.blank_space);
                 Ok(())
-              }
-              PrintStackBreak::Broken(Breaks::Consistent) => {
+            }
+            PrintStackBreak::Broken(Breaks::Consistent) => {
                 debug!("print Break({}+{}) in consistent block",
                        top.offset, b.offset);
                 let ret = self.print_newline(top.offset + b.offset);
                 self.space = self.margin - (top.offset + b.offset);
                 ret
-              }
-              PrintStackBreak::Broken(Breaks::Inconsistent) => {
+            }
+            PrintStackBreak::Broken(Breaks::Inconsistent) => {
                 if l > self.space {
                     debug!("print Break({}+{}) w/ newline in inconsistent",
                            top.offset, b.offset);
@@ -577,20 +581,37 @@
                     self.space -= b.blank_space;
                     Ok(())
                 }
-              }
             }
-          }
-          Token::String(ref s, len) => {
-            debug!("print String({})", s);
-            assert_eq!(l, len);
-            // assert!(l <= space);
-            self.space -= len;
-            self.print_str(s)
-          }
-          Token::Eof => {
-            // Eof should never get here.
-            panic!();
-          }
+        }
+    }
+
+    pub fn print_string(&mut self, s: Cow<'static, str>, len: isize) -> io::Result<()> {
+        debug!("print String({})", s);
+        // assert!(len <= space);
+        self.space -= len;
+        while self.pending_indentation > 0 {
+            write!(self.out, " ")?;
+            self.pending_indentation -= 1;
+        }
+        write!(self.out, "{}", s)
+    }
+
+    pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
+        debug!("print {} {} (remaining line space={})", token, l,
+               self.space);
+        debug!("{}", buf_str(&self.buf,
+                             self.left,
+                             self.right,
+                             6));
+        match token {
+            Token::Begin(b) => self.print_begin(b, l),
+            Token::End => self.print_end(),
+            Token::Break(b) => self.print_break(b, l),
+            Token::String(s, len) => {
+                assert_eq!(len, l);
+                self.print_string(s, len)
+            }
+            Token::Eof => panic!(), // Eof should never get here.
         }
     }
 
@@ -598,10 +619,10 @@
 
     /// "raw box"
     pub fn rbox(&mut self, indent: usize, b: Breaks) -> io::Result<()> {
-        self.pretty_print(Token::Begin(BeginToken {
+        self.pretty_print_begin(BeginToken {
             offset: indent as isize,
             breaks: b
-        }))
+        })
     }
 
     /// Inconsistent breaking box
@@ -615,30 +636,24 @@
     }
 
     pub fn break_offset(&mut self, n: usize, off: isize) -> io::Result<()> {
-        self.pretty_print(Token::Break(BreakToken {
+        self.pretty_print_break(BreakToken {
             offset: off,
             blank_space: n as isize
-        }))
+        })
     }
 
     pub fn end(&mut self) -> io::Result<()> {
-        self.pretty_print(Token::End)
+        self.pretty_print_end()
     }
 
     pub fn eof(&mut self) -> io::Result<()> {
-        self.pretty_print(Token::Eof)
+        self.pretty_print_eof()
     }
 
-    pub fn word(&mut self, wrd: &str) -> io::Result<()> {
-        self.pretty_print(Token::String(wrd.to_string(), wrd.len() as isize))
-    }
-
-    pub fn huge_word(&mut self, wrd: &str) -> io::Result<()> {
-        self.pretty_print(Token::String(wrd.to_string(), SIZE_INFINITY))
-    }
-
-    pub fn zero_word(&mut self, wrd: &str) -> io::Result<()> {
-        self.pretty_print(Token::String(wrd.to_string(), 0))
+    pub fn word<S: Into<Cow<'static, str>>>(&mut self, wrd: S) -> io::Result<()> {
+        let s = wrd.into();
+        let len = s.len() as isize;
+        self.pretty_print_string(s, len)
     }
 
     fn spaces(&mut self, n: usize) -> io::Result<()> {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index ce7708c..e50f288 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -29,6 +29,7 @@
 use tokenstream::{self, TokenStream, TokenTree};
 
 use std::ascii;
+use std::borrow::Cow;
 use std::io::{self, Write, Read};
 use std::iter::Peekable;
 use std::vec;
@@ -209,7 +210,6 @@
         token::DotDot               => "..".to_string(),
         token::DotDotDot            => "...".to_string(),
         token::DotDotEq             => "..=".to_string(),
-        token::DotEq                => ".=".to_string(),
         token::Comma                => ",".to_string(),
         token::Semi                 => ";".to_string(),
         token::Colon                => ":".to_string(),
@@ -444,7 +444,7 @@
     fn cur_lit(&mut self) -> Option<&comments::Literal>;
     fn bump_lit(&mut self) -> Option<comments::Literal>;
 
-    fn word_space(&mut self, w: &str) -> io::Result<()> {
+    fn word_space<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
         self.writer().word(w)?;
         self.writer().space()
     }
@@ -539,7 +539,7 @@
             comments::Mixed => {
                 assert_eq!(cmnt.lines.len(), 1);
                 self.writer().zerobreak()?;
-                self.writer().word(&cmnt.lines[0])?;
+                self.writer().word(cmnt.lines[0].clone())?;
                 self.writer().zerobreak()
             }
             comments::Isolated => {
@@ -548,7 +548,7 @@
                     // Don't print empty lines because they will end up as trailing
                     // whitespace
                     if !line.is_empty() {
-                        self.writer().word(&line[..])?;
+                        self.writer().word(line.clone())?;
                     }
                     self.writer().hardbreak()?;
                 }
@@ -559,13 +559,13 @@
                     self.writer().word(" ")?;
                 }
                 if cmnt.lines.len() == 1 {
-                    self.writer().word(&cmnt.lines[0])?;
+                    self.writer().word(cmnt.lines[0].clone())?;
                     self.writer().hardbreak()
                 } else {
                     self.ibox(0)?;
                     for line in &cmnt.lines {
                         if !line.is_empty() {
-                            self.writer().word(&line[..])?;
+                            self.writer().word(line.clone())?;
                         }
                         self.writer().hardbreak()?;
                     }
@@ -610,7 +610,7 @@
     fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> {
         self.maybe_print_comment(lit.span.lo())?;
         if let Some(ltrl) = self.next_lit(lit.span.lo()) {
-            return self.writer().word(&ltrl.lit);
+            return self.writer().word(ltrl.lit.clone());
         }
         match lit.node {
             ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style),
@@ -618,31 +618,31 @@
                 let mut res = String::from("b'");
                 res.extend(ascii::escape_default(byte).map(|c| c as char));
                 res.push('\'');
-                self.writer().word(&res[..])
+                self.writer().word(res)
             }
             ast::LitKind::Char(ch) => {
                 let mut res = String::from("'");
                 res.extend(ch.escape_default());
                 res.push('\'');
-                self.writer().word(&res[..])
+                self.writer().word(res)
             }
             ast::LitKind::Int(i, t) => {
                 match t {
                     ast::LitIntType::Signed(st) => {
-                        self.writer().word(&st.val_to_string(i as i128))
+                        self.writer().word(st.val_to_string(i as i128))
                     }
                     ast::LitIntType::Unsigned(ut) => {
-                        self.writer().word(&ut.val_to_string(i))
+                        self.writer().word(ut.val_to_string(i))
                     }
                     ast::LitIntType::Unsuffixed => {
-                        self.writer().word(&i.to_string())
+                        self.writer().word(i.to_string())
                     }
                 }
             }
             ast::LitKind::Float(ref f, t) => {
-                self.writer().word(&format!("{}{}", &f, t.ty_to_string()))
+                self.writer().word(format!("{}{}", &f, t.ty_to_string()))
             }
-            ast::LitKind::FloatUnsuffixed(ref f) => self.writer().word(&f.as_str()),
+            ast::LitKind::FloatUnsuffixed(ref f) => self.writer().word(f.as_str().get()),
             ast::LitKind::Bool(val) => {
                 if val { self.writer().word("true") } else { self.writer().word("false") }
             }
@@ -652,7 +652,7 @@
                     escaped.extend(ascii::escape_default(ch)
                                          .map(|c| c as char));
                 }
-                self.writer().word(&format!("b\"{}\"", escaped))
+                self.writer().word(format!("b\"{}\"", escaped))
             }
         }
     }
@@ -669,7 +669,7 @@
                          string=st))
             }
         };
-        self.writer().word(&st[..])
+        self.writer().word(st)
     }
 
     fn print_inner_attributes(&mut self,
@@ -724,10 +724,10 @@
             if i > 0 {
                 self.writer().word("::")?
             }
-            if segment.ident.name != keywords::CrateRoot.name() &&
+            if segment.ident.name != keywords::PathRoot.name() &&
                segment.ident.name != keywords::DollarCrate.name()
             {
-                self.writer().word(&segment.ident.as_str())?;
+                self.writer().word(segment.ident.as_str().get())?;
             } else if segment.ident.name == keywords::DollarCrate.name() {
                 self.print_dollar_crate(segment.ident.span.ctxt())?;
             }
@@ -746,7 +746,7 @@
         }
         self.maybe_print_comment(attr.span.lo())?;
         if attr.is_sugared_doc {
-            self.writer().word(&attr.value_str().unwrap().as_str())?;
+            self.writer().word(attr.value_str().unwrap().as_str().get())?;
             self.writer().hardbreak()
         } else {
             match attr.style {
@@ -807,7 +807,7 @@
     fn print_tt(&mut self, tt: tokenstream::TokenTree) -> io::Result<()> {
         match tt {
             TokenTree::Token(_, ref tk) => {
-                self.writer().word(&token_to_string(tk))?;
+                self.writer().word(token_to_string(tk))?;
                 match *tk {
                     parse::token::DocComment(..) => {
                         self.writer().hardbreak()
@@ -816,11 +816,11 @@
                 }
             }
             TokenTree::Delimited(_, ref delimed) => {
-                self.writer().word(&token_to_string(&delimed.open_token()))?;
+                self.writer().word(token_to_string(&delimed.open_token()))?;
                 self.writer().space()?;
                 self.print_tts(delimed.stream())?;
                 self.writer().space()?;
-                self.writer().word(&token_to_string(&delimed.close_token()))
+                self.writer().word(token_to_string(&delimed.close_token()))
             },
         }
     }
@@ -889,12 +889,13 @@
         self.s.cbox(u)
     }
 
-    pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> {
+    pub fn word_nbsp<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
         self.s.word(w)?;
         self.nbsp()
     }
 
-    pub fn head(&mut self, w: &str) -> io::Result<()> {
+    pub fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
+        let w = w.into();
         // outer-box is consistent
         self.cbox(INDENT_UNIT)?;
         // head-box is inconsistent
@@ -956,7 +957,7 @@
     pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
         self.s.word("/*")?;
         self.s.space()?;
-        self.s.word(&text[..])?;
+        self.s.word(text)?;
         self.s.space()?;
         self.s.word("*/")
     }
@@ -1129,7 +1130,7 @@
                 self.end() // end the outer fn box
             }
             ast::ForeignItemKind::Static(ref t, m) => {
-                self.head(&visibility_qualified(&item.vis, "static"))?;
+                self.head(visibility_qualified(&item.vis, "static"))?;
                 if m {
                     self.word_space("mut")?;
                 }
@@ -1141,7 +1142,7 @@
                 self.end() // end the outer cbox
             }
             ast::ForeignItemKind::Ty => {
-                self.head(&visibility_qualified(&item.vis, "type"))?;
+                self.head(visibility_qualified(&item.vis, "type"))?;
                 self.print_ident(item.ident)?;
                 self.s.word(";")?;
                 self.end()?; // end the head-ibox
@@ -1164,7 +1165,7 @@
                               vis: &ast::Visibility)
                               -> io::Result<()>
     {
-        self.s.word(&visibility_qualified(vis, ""))?;
+        self.s.word(visibility_qualified(vis, ""))?;
         self.word_space("const")?;
         self.print_ident(ident)?;
         self.word_space(":")?;
@@ -1203,7 +1204,7 @@
         self.ann.pre(self, AnnNode::Item(item))?;
         match item.node {
             ast::ItemKind::ExternCrate(orig_name) => {
-                self.head(&visibility_qualified(&item.vis, "extern crate"))?;
+                self.head(visibility_qualified(&item.vis, "extern crate"))?;
                 if let Some(orig_name) = orig_name {
                     self.print_name(orig_name)?;
                     self.s.space()?;
@@ -1216,14 +1217,14 @@
                 self.end()?; // end outer head-block
             }
             ast::ItemKind::Use(ref tree) => {
-                self.head(&visibility_qualified(&item.vis, "use"))?;
+                self.head(visibility_qualified(&item.vis, "use"))?;
                 self.print_use_tree(tree)?;
                 self.s.word(";")?;
                 self.end()?; // end inner head-block
                 self.end()?; // end outer head-block
             }
             ast::ItemKind::Static(ref ty, m, ref expr) => {
-                self.head(&visibility_qualified(&item.vis, "static"))?;
+                self.head(visibility_qualified(&item.vis, "static"))?;
                 if m == ast::Mutability::Mutable {
                     self.word_space("mut")?;
                 }
@@ -1239,7 +1240,7 @@
                 self.end()?; // end the outer cbox
             }
             ast::ItemKind::Const(ref ty, ref expr) => {
-                self.head(&visibility_qualified(&item.vis, "const"))?;
+                self.head(visibility_qualified(&item.vis, "const"))?;
                 self.print_ident(item.ident)?;
                 self.word_space(":")?;
                 self.print_type(ty)?;
@@ -1264,7 +1265,7 @@
                 self.print_block_with_attrs(body, &item.attrs)?;
             }
             ast::ItemKind::Mod(ref _mod) => {
-                self.head(&visibility_qualified(&item.vis, "mod"))?;
+                self.head(visibility_qualified(&item.vis, "mod"))?;
                 self.print_ident(item.ident)?;
 
                 if _mod.inline || self.is_expanded {
@@ -1281,18 +1282,18 @@
             }
             ast::ItemKind::ForeignMod(ref nmod) => {
                 self.head("extern")?;
-                self.word_nbsp(&nmod.abi.to_string())?;
+                self.word_nbsp(nmod.abi.to_string())?;
                 self.bopen()?;
                 self.print_foreign_mod(nmod, &item.attrs)?;
                 self.bclose(item.span)?;
             }
             ast::ItemKind::GlobalAsm(ref ga) => {
-                self.head(&visibility_qualified(&item.vis, "global_asm!"))?;
-                self.s.word(&ga.asm.as_str())?;
+                self.head(visibility_qualified(&item.vis, "global_asm!"))?;
+                self.s.word(ga.asm.as_str().get())?;
                 self.end()?;
             }
             ast::ItemKind::Ty(ref ty, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "type"))?;
+                self.head(visibility_qualified(&item.vis, "type"))?;
                 self.print_ident(item.ident)?;
                 self.print_generic_params(&generics.params)?;
                 self.end()?; // end the inner ibox
@@ -1305,7 +1306,7 @@
                 self.end()?; // end the outer ibox
             }
             ast::ItemKind::Existential(ref bounds, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "existential type"))?;
+                self.head(visibility_qualified(&item.vis, "existential type"))?;
                 self.print_ident(item.ident)?;
                 self.print_generic_params(&generics.params)?;
                 self.end()?; // end the inner ibox
@@ -1326,11 +1327,11 @@
                 )?;
             }
             ast::ItemKind::Struct(ref struct_def, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "struct"))?;
+                self.head(visibility_qualified(&item.vis, "struct"))?;
                 self.print_struct(struct_def, generics, item.ident, item.span, true)?;
             }
             ast::ItemKind::Union(ref struct_def, ref generics) => {
-                self.head(&visibility_qualified(&item.vis, "union"))?;
+                self.head(visibility_qualified(&item.vis, "union"))?;
                 self.print_struct(struct_def, generics, item.ident, item.span, true)?;
             }
             ast::ItemKind::Impl(unsafety,
@@ -1479,7 +1480,7 @@
                           generics: &ast::Generics, ident: ast::Ident,
                           span: syntax_pos::Span,
                           visibility: &ast::Visibility) -> io::Result<()> {
-        self.head(&visibility_qualified(visibility, "enum"))?;
+        self.head(visibility_qualified(visibility, "enum"))?;
         self.print_ident(ident)?;
         self.print_generic_params(&generics.params)?;
         self.print_where_clause(&generics.where_clause)?;
@@ -1514,9 +1515,9 @@
             ast::VisibilityKind::Restricted { ref path, .. } => {
                 let path = to_string(|s| s.print_path(path, false, 0));
                 if path == "self" || path == "super" {
-                    self.word_nbsp(&format!("pub({})", path))
+                    self.word_nbsp(format!("pub({})", path))
                 } else {
-                    self.word_nbsp(&format!("pub(in {})", path))
+                    self.word_nbsp(format!("pub(in {})", path))
                 }
             }
             ast::VisibilityKind::Inherited => Ok(())
@@ -1525,7 +1526,7 @@
 
     pub fn print_defaultness(&mut self, defaultness: ast::Defaultness) -> io::Result<()> {
         if let ast::Defaultness::Default = defaultness {
-            try!(self.word_nbsp("default"));
+            self.word_nbsp("default")?;
         }
         Ok(())
     }
@@ -2415,19 +2416,19 @@
 
     pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
         if ident.is_raw_guess() {
-            self.s.word(&format!("r#{}", ident))?;
+            self.s.word(format!("r#{}", ident))?;
         } else {
-            self.s.word(&ident.as_str())?;
+            self.s.word(ident.as_str().get())?;
         }
         self.ann.post(self, AnnNode::Ident(&ident))
     }
 
     pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
-        self.s.word(&i.to_string())
+        self.s.word(i.to_string())
     }
 
     pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
-        self.s.word(&name.as_str())?;
+        self.s.word(name.as_str().get())?;
         self.ann.post(self, AnnNode::Name(&name))
     }
 
@@ -2462,7 +2463,7 @@
                           colons_before_params: bool)
                           -> io::Result<()>
     {
-        if segment.ident.name != keywords::CrateRoot.name() &&
+        if segment.ident.name != keywords::PathRoot.name() &&
            segment.ident.name != keywords::DollarCrate.name() {
             self.print_ident(segment.ident)?;
             if let Some(ref args) = segment.args {
@@ -2851,10 +2852,8 @@
         }
     }
 
-    pub fn print_type_bounds(&mut self,
-                        prefix: &str,
-                        bounds: &[ast::GenericBound])
-                        -> io::Result<()> {
+    pub fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::GenericBound])
+                             -> io::Result<()> {
         if !bounds.is_empty() {
             self.s.word(prefix)?;
             let mut first = true;
@@ -3146,7 +3145,7 @@
             Some(Abi::Rust) => Ok(()),
             Some(abi) => {
                 self.word_nbsp("extern")?;
-                self.word_nbsp(&abi.to_string())
+                self.word_nbsp(abi.to_string())
             }
             None => Ok(())
         }
@@ -3157,7 +3156,7 @@
         match opt_abi {
             Some(abi) => {
                 self.word_nbsp("extern")?;
-                self.word_nbsp(&abi.to_string())
+                self.word_nbsp(abi.to_string())
             }
             None => Ok(())
         }
@@ -3166,7 +3165,7 @@
     pub fn print_fn_header_info(&mut self,
                                 header: ast::FnHeader,
                                 vis: &ast::Visibility) -> io::Result<()> {
-        self.s.word(&visibility_qualified(vis, ""))?;
+        self.s.word(visibility_qualified(vis, ""))?;
 
         match header.constness.node {
             ast::Constness::NotConst => {}
@@ -3178,7 +3177,7 @@
 
         if header.abi != Abi::Rust {
             self.word_nbsp("extern")?;
-            self.word_nbsp(&header.abi.to_string())?;
+            self.word_nbsp(header.abi.to_string())?;
         }
 
         self.s.word("fn")
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs
index bb47d9b..9fbc647 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -72,7 +72,7 @@
         *self.ptr
     }
 
-    /// Transform the inner value, consuming `self` and producing a new `P<T>`.
+    /// Produce a new `P<T>` from `self` without reallocating.
     pub fn map<F>(mut self, f: F) -> P<T> where
         F: FnOnce(T) -> T,
     {
@@ -88,8 +88,30 @@
             ptr::write(p, f(ptr::read(p)));
 
             // Recreate self from the raw pointer.
-            P {
-                ptr: Box::from_raw(p)
+            P { ptr: Box::from_raw(p) }
+        }
+    }
+
+    /// Optionally produce a new `P<T>` from `self` without reallocating.
+    pub fn filter_map<F>(mut self, f: F) -> Option<P<T>> where
+        F: FnOnce(T) -> Option<T>,
+    {
+        let p: *mut T = &mut *self.ptr;
+
+        // Leak self in case of panic.
+        // FIXME(eddyb) Use some sort of "free guard" that
+        // only deallocates, without dropping the pointee,
+        // in case the call the `f` below ends in a panic.
+        mem::forget(self);
+
+        unsafe {
+            if let Some(v) = f(ptr::read(p)) {
+                ptr::write(p, v);
+
+                // Recreate self from the raw pointer.
+                Some(P { ptr: Box::from_raw(p) })
+            } else {
+                None
             }
         }
     }
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index e8cacc3..ee60d2d 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -110,11 +110,19 @@
 
 impl StableSourceFileId {
     pub fn new(source_file: &SourceFile) -> StableSourceFileId {
+        StableSourceFileId::new_from_pieces(&source_file.name,
+                                         source_file.name_was_remapped,
+                                         source_file.unmapped_path.as_ref())
+    }
+
+    pub fn new_from_pieces(name: &FileName,
+                           name_was_remapped: bool,
+                           unmapped_path: Option<&FileName>) -> StableSourceFileId {
         let mut hasher = StableHasher::new();
 
-        source_file.name.hash(&mut hasher);
-        source_file.name_was_remapped.hash(&mut hasher);
-        source_file.unmapped_path.hash(&mut hasher);
+        name.hash(&mut hasher);
+        name_was_remapped.hash(&mut hasher);
+        unmapped_path.hash(&mut hasher);
 
         StableSourceFileId(hasher.finish())
     }
@@ -136,9 +144,6 @@
     // This is used to apply the file path remapping as specified via
     // --remap-path-prefix to all SourceFiles allocated within this SourceMap.
     path_mapping: FilePathMapping,
-    /// In case we are in a doctest, replace all file names with the PathBuf,
-    /// and add the given offsets to the line info
-    doctest_offset: Option<(FileName, isize)>,
 }
 
 impl SourceMap {
@@ -147,19 +152,9 @@
             files: Default::default(),
             file_loader: Box::new(RealFileLoader),
             path_mapping,
-            doctest_offset: None,
         }
     }
 
-    pub fn new_doctest(path_mapping: FilePathMapping,
-                       file: FileName, line: isize) -> SourceMap {
-        SourceMap {
-            doctest_offset: Some((file, line)),
-            ..SourceMap::new(path_mapping)
-        }
-
-    }
-
     pub fn with_file_loader(file_loader: Box<dyn FileLoader + Sync + Send>,
                             path_mapping: FilePathMapping)
                             -> SourceMap {
@@ -167,7 +162,6 @@
             files: Default::default(),
             file_loader: file_loader,
             path_mapping,
-            doctest_offset: None,
         }
     }
 
@@ -181,11 +175,7 @@
 
     pub fn load_file(&self, path: &Path) -> io::Result<Lrc<SourceFile>> {
         let src = self.file_loader.read_file(path)?;
-        let filename = if let Some((ref name, _)) = self.doctest_offset {
-            name.clone()
-        } else {
-            path.to_owned().into()
-        };
+        let filename = path.to_owned().into();
         Ok(self.new_source_file(filename, src))
     }
 
@@ -208,7 +198,8 @@
     }
 
     /// Creates a new source_file.
-    /// This does not ensure that only one SourceFile exists per file name.
+    /// If a file already exists in the source_map with the same id, that file is returned
+    /// unmodified
     pub fn new_source_file(&self, filename: FileName, src: String) -> Lrc<SourceFile> {
         let start_pos = self.next_start_pos();
 
@@ -226,21 +217,30 @@
             },
             other => (other, false),
         };
-        let source_file = Lrc::new(SourceFile::new(
-            filename,
-            was_remapped,
-            unmapped_path,
-            src,
-            Pos::from_usize(start_pos),
-        ));
 
-        let mut files = self.files.borrow_mut();
+        let file_id = StableSourceFileId::new_from_pieces(&filename,
+                                                       was_remapped,
+                                                       Some(&unmapped_path));
 
-        files.source_files.push(source_file.clone());
-        files.stable_id_to_source_file.insert(StableSourceFileId::new(&source_file),
-                                              source_file.clone());
+        return match self.source_file_by_stable_id(file_id) {
+            Some(lrc_sf) => lrc_sf,
+            None => {
+                let source_file = Lrc::new(SourceFile::new(
+                    filename,
+                    was_remapped,
+                    unmapped_path,
+                    src,
+                    Pos::from_usize(start_pos),
+                ));
 
-        source_file
+                let mut files = self.files.borrow_mut();
+
+                files.source_files.push(source_file.clone());
+                files.stable_id_to_source_file.insert(file_id, source_file.clone());
+
+                source_file
+            }
+        }
     }
 
     /// Allocates a new SourceFile representing a source file from an external
@@ -310,15 +310,17 @@
     }
 
     // If there is a doctest_offset, apply it to the line
-    pub fn doctest_offset_line(&self, mut orig: usize) -> usize {
-        if let Some((_, line)) = self.doctest_offset {
-            if line >= 0 {
-                orig = orig + line as usize;
-            } else {
-                orig = orig - (-line) as usize;
-            }
+    pub fn doctest_offset_line(&self, file: &FileName, orig: usize) -> usize {
+        return match file {
+            FileName::DocTest(_, offset) => {
+                return if *offset >= 0 {
+                    orig + *offset as usize
+                } else {
+                    orig - (-(*offset)) as usize
+                }
+            },
+            _ => orig
         }
-        orig
     }
 
     /// Lookup source information about a BytePos
@@ -983,8 +985,8 @@
             }
         )
     }
-    fn doctest_offset_line(&self, line: usize) -> usize {
-        self.doctest_offset_line(line)
+    fn doctest_offset_line(&self, file: &FileName, line: usize) -> usize {
+        self.doctest_offset_line(file, line)
     }
 }
 
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index 1210f33..5c99455 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -112,7 +112,7 @@
         vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
         node: ast::ItemKind::Use(P(ast::UseTree {
             prefix: ast::Path {
-                segments: iter::once(keywords::CrateRoot.ident())
+                segments: iter::once(keywords::PathRoot.ident())
                     .chain(
                         [name, "prelude", "v1"].iter().cloned()
                             .map(ast::Ident::from_str)
diff --git a/src/libsyntax/str.rs b/src/libsyntax/str.rs
deleted file mode 100644
index 2818619..0000000
--- a/src/libsyntax/str.rs
+++ /dev/null
@@ -1,14 +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.
-
-#[inline]
-pub fn char_at(s: &str, byte: usize) -> char {
-    s[byte..].chars().next().unwrap()
-}
diff --git a/src/libsyntax/util/lev_distance.rs b/src/libsyntax/util/lev_distance.rs
index feee242..fb28115 100644
--- a/src/libsyntax/util/lev_distance.rs
+++ b/src/libsyntax/util/lev_distance.rs
@@ -38,7 +38,8 @@
             current = next;
             t_last = j;
         }
-    } dcol[t_last + 1]
+    }
+    dcol[t_last + 1]
 }
 
 /// Find the best match for a given word in the given iterator
diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml
index 5a691bd..4979d0b 100644
--- a/src/libsyntax_ext/Cargo.toml
+++ b/src/libsyntax_ext/Cargo.toml
@@ -10,7 +10,6 @@
 
 [dependencies]
 fmt_macros = { path = "../libfmt_macros" }
-proc_macro = { path = "../libproc_macro" }
 rustc_errors = { path = "../librustc_errors" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 026ddcc..2ff9fb4 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -47,7 +47,7 @@
     }
 }
 
-const OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
+const OPTIONS: &[&str] = &["volatile", "alignstack", "intel"];
 
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                        sp: Span,
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index ec935b3..b9e0933 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -140,7 +140,7 @@
     let mut stmts = Vec::new();
     if is_union {
         // let _: AssertParamIsCopy<Self>;
-        let self_ty = cx.ty_path(cx.path_ident(trait_span, keywords::SelfType.ident()));
+        let self_ty = cx.ty_path(cx.path_ident(trait_span, keywords::SelfUpper.ident()));
         assert_ty_bounds(cx, &mut stmts, self_ty, trait_span, "AssertParamIsCopy");
     } else {
         match *substr.fields {
diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs
index 55b3928..5c82d19 100644
--- a/src/libsyntax_ext/deriving/custom.rs
+++ b/src/libsyntax_ext/deriving/custom.rs
@@ -8,15 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::panic;
-
 use errors::FatalError;
-use proc_macro::{TokenStream, __internal};
 use syntax::ast::{self, ItemKind, Attribute, Mac};
 use syntax::attr::{mark_used, mark_known};
 use syntax::source_map::Span;
 use syntax::ext::base::*;
+use syntax::parse;
+use syntax::parse::token::{self, Token};
+use syntax::tokenstream;
 use syntax::visit::Visitor;
+use syntax_pos::DUMMY_SP;
+
+use proc_macro_impl::EXEC_STRATEGY;
 
 struct MarkAttrs<'a>(&'a [ast::Name]);
 
@@ -32,14 +35,10 @@
 }
 
 pub struct ProcMacroDerive {
-    inner: fn(TokenStream) -> TokenStream,
-    attrs: Vec<ast::Name>,
-}
-
-impl ProcMacroDerive {
-    pub fn new(inner: fn(TokenStream) -> TokenStream, attrs: Vec<ast::Name>) -> ProcMacroDerive {
-        ProcMacroDerive { inner: inner, attrs: attrs }
-    }
+    pub client: ::proc_macro::bridge::client::Client<
+        fn(::proc_macro::TokenStream) -> ::proc_macro::TokenStream,
+    >,
+    pub attrs: Vec<ast::Name>,
 }
 
 impl MultiItemModifier for ProcMacroDerive {
@@ -75,21 +74,17 @@
         // Mark attributes as known, and used.
         MarkAttrs(&self.attrs).visit_item(&item);
 
-        let input = __internal::new_token_stream(ecx.resolver.eliminate_crate_var(item));
-        let res = __internal::set_sess(ecx, || {
-            let inner = self.inner;
-            panic::catch_unwind(panic::AssertUnwindSafe(|| inner(input)))
-        });
+        let item = ecx.resolver.eliminate_crate_var(item);
+        let token = Token::interpolated(token::NtItem(item));
+        let input = tokenstream::TokenTree::Token(DUMMY_SP, token).into();
 
-        let stream = match res {
+        let server = ::proc_macro_server::Rustc::new(ecx);
+        let stream = match self.client.run(&EXEC_STRATEGY, server, input) {
             Ok(stream) => stream,
             Err(e) => {
                 let msg = "proc-macro derive panicked";
                 let mut err = ecx.struct_span_fatal(span, msg);
-                if let Some(s) = e.downcast_ref::<String>() {
-                    err.help(&format!("message: {}", s));
-                }
-                if let Some(s) = e.downcast_ref::<&'static str>() {
+                if let Some(s) = e.as_str() {
                     err.help(&format!("message: {}", s));
                 }
 
@@ -99,21 +94,33 @@
         };
 
         let error_count_before = ecx.parse_sess.span_diagnostic.err_count();
-        __internal::set_sess(ecx, || {
-            let msg = "proc-macro derive produced unparseable tokens";
-            match __internal::token_stream_parse_items(stream) {
-                // fail if there have been errors emitted
-                Ok(_) if ecx.parse_sess.span_diagnostic.err_count() > error_count_before => {
-                    ecx.struct_span_fatal(span, msg).emit();
-                    FatalError.raise();
+        let msg = "proc-macro derive produced unparseable tokens";
+
+        let mut parser = parse::stream_to_parser(ecx.parse_sess, stream);
+        let mut items = vec![];
+
+        loop {
+            match parser.parse_item() {
+                Ok(None) => break,
+                Ok(Some(item)) => {
+                    items.push(Annotatable::Item(item))
                 }
-                Ok(new_items) => new_items.into_iter().map(Annotatable::Item).collect(),
-                Err(_) => {
+                Err(mut err) => {
                     // FIXME: handle this better
+                    err.cancel();
                     ecx.struct_span_fatal(span, msg).emit();
                     FatalError.raise();
                 }
             }
-        })
+        }
+
+
+        // fail if there have been errors emitted
+        if ecx.parse_sess.span_diagnostic.err_count() > error_count_before {
+            ecx.struct_span_fatal(span, msg).emit();
+            FatalError.raise();
+        }
+
+        items
     }
 }
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index a5b12ce..c0c11f6 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -938,7 +938,7 @@
         let args = {
             let self_args = explicit_self.map(|explicit_self| {
                 ast::Arg::from_self(explicit_self,
-                                    keywords::SelfValue.ident().with_span_pos(trait_.span))
+                                    keywords::SelfLower.ident().with_span_pos(trait_.span))
             });
             let nonself_args = arg_types.into_iter()
                 .map(|(name, ty)| cx.arg(trait_.span, name, ty));
diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs
index 6eba3c4..9c85401 100644
--- a/src/libsyntax_ext/format_foreign.rs
+++ b/src/libsyntax_ext/format_foreign.rs
@@ -264,7 +264,7 @@
             match *self {
                 Num::Num(n) => write!(s, "{}", n),
                 Num::Arg(n) => {
-                    let n = try!(n.checked_sub(1).ok_or(::std::fmt::Error));
+                    let n = n.checked_sub(1).ok_or(::std::fmt::Error)?;
                     write!(s, "{}$", n)
                 },
                 Num::Next => write!(s, "*"),
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 1130a50..000bede 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -28,7 +28,7 @@
 use syntax_pos::Span;
 use syntax::tokenstream;
 
-pub const MACRO: &'static str = "global_asm";
+pub const MACRO: &str = "global_asm";
 
 pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 7c023fc..1d814a6 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -14,7 +14,10 @@
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
 
+#![feature(in_band_lifetimes)]
+#![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
+#![feature(proc_macro_span)]
 #![feature(decl_macro)]
 #![feature(nll)]
 #![feature(str_escape)]
@@ -55,10 +58,9 @@
 mod test;
 mod test_case;
 
-pub mod proc_macro_registrar;
-
-
+pub mod proc_macro_decls;
 pub mod proc_macro_impl;
+mod proc_macro_server;
 
 use rustc_data_structures::sync::Lrc;
 use syntax::ast;
diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_decls.rs
similarity index 75%
rename from src/libsyntax_ext/proc_macro_registrar.rs
rename to src/libsyntax_ext/proc_macro_decls.rs
index 65e175f..f4ff098 100644
--- a/src/libsyntax_ext/proc_macro_registrar.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -30,8 +30,7 @@
 
 use deriving;
 
-const PROC_MACRO_KINDS: [&'static str; 3] =
-    ["proc_macro_derive", "proc_macro_attribute", "proc_macro"];
+const PROC_MACRO_KINDS: [&str; 3] = ["proc_macro_derive", "proc_macro_attribute", "proc_macro"];
 
 struct ProcMacroDerive {
     trait_name: ast::Name,
@@ -91,7 +90,7 @@
         return krate;
     }
 
-    krate.module.items.push(mk_registrar(&mut cx, &derives, &attr_macros, &bang_macros));
+    krate.module.items.push(mk_decls(&mut cx, &derives, &attr_macros, &bang_macros));
 
     krate
 }
@@ -339,19 +338,21 @@
 //      mod $gensym {
 //          extern crate proc_macro;
 //
-//          use proc_macro::__internal::Registry;
+//          use proc_macro::bridge::client::ProcMacro;
 //
-//          #[plugin_registrar]
-//          fn registrar(registrar: &mut Registry) {
-//              registrar.register_custom_derive($name_trait1, ::$name1, &[]);
-//              registrar.register_custom_derive($name_trait2, ::$name2, &["attribute_name"]);
+//          #[rustc_proc_macro_decls]
+//          static DECLS: &[ProcMacro] = &[
+//              ProcMacro::custom_derive($name_trait1, &[], ::$name1);
+//              ProcMacro::custom_derive($name_trait2, &["attribute_name"], ::$name2);
 //              // ...
-//          }
+//          ];
 //      }
-fn mk_registrar(cx: &mut ExtCtxt,
-                custom_derives: &[ProcMacroDerive],
-                custom_attrs: &[ProcMacroDef],
-                custom_macros: &[ProcMacroDef]) -> P<ast::Item> {
+fn mk_decls(
+    cx: &mut ExtCtxt,
+    custom_derives: &[ProcMacroDerive],
+    custom_attrs: &[ProcMacroDef],
+    custom_macros: &[ProcMacroDef],
+) -> P<ast::Item> {
     let mark = Mark::fresh(Mark::root());
     mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
@@ -370,75 +371,67 @@
                         Vec::new(),
                         ast::ItemKind::ExternCrate(None));
 
-    let __internal = Ident::from_str("__internal");
-    let registry = Ident::from_str("Registry");
-    let registrar = Ident::from_str("_registrar");
-    let register_custom_derive = Ident::from_str("register_custom_derive");
-    let register_attr_proc_macro = Ident::from_str("register_attr_proc_macro");
-    let register_bang_proc_macro = Ident::from_str("register_bang_proc_macro");
+    let bridge = Ident::from_str("bridge");
+    let client = Ident::from_str("client");
+    let proc_macro_ty = Ident::from_str("ProcMacro");
+    let custom_derive = Ident::from_str("custom_derive");
+    let attr = Ident::from_str("attr");
+    let bang = Ident::from_str("bang");
     let crate_kw = Ident::with_empty_ctxt(keywords::Crate.name());
-    let local_path = |cx: &mut ExtCtxt, sp: Span, name: Ident| {
-        cx.path(sp.with_ctxt(span.ctxt()), vec![crate_kw, name])
+
+    let decls = {
+        let local_path = |sp: Span, name| {
+            cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![crate_kw, name]))
+        };
+        let proc_macro_ty_method_path = |method| cx.expr_path(cx.path(span, vec![
+            proc_macro, bridge, client, proc_macro_ty, method,
+        ]));
+        custom_derives.iter().map(|cd| {
+            cx.expr_call(span, proc_macro_ty_method_path(custom_derive), vec![
+                cx.expr_str(cd.span, cd.trait_name),
+                cx.expr_vec_slice(
+                    span,
+                    cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>()
+                ),
+                local_path(cd.span, cd.function_name),
+            ])
+        }).chain(custom_attrs.iter().map(|ca| {
+            cx.expr_call(span, proc_macro_ty_method_path(attr), vec![
+                cx.expr_str(ca.span, ca.function_name.name),
+                local_path(ca.span, ca.function_name),
+            ])
+        })).chain(custom_macros.iter().map(|cm| {
+            cx.expr_call(span, proc_macro_ty_method_path(bang), vec![
+                cx.expr_str(cm.span, cm.function_name.name),
+                local_path(cm.span, cm.function_name),
+            ])
+        })).collect()
     };
 
-    let mut stmts = custom_derives.iter().map(|cd| {
-        let path = local_path(cx, cd.span, cd.function_name);
-        let trait_name = cx.expr_str(cd.span, cd.trait_name);
-        let attrs = cx.expr_vec_slice(
-            span,
-            cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>()
-        );
-        let registrar = cx.expr_ident(span, registrar);
-        let ufcs_path = cx.path(span, vec![proc_macro, __internal, registry,
-                                           register_custom_derive]);
-
-        cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path),
-                                  vec![registrar, trait_name, cx.expr_path(path), attrs]))
-
-    }).collect::<Vec<_>>();
-
-    stmts.extend(custom_attrs.iter().map(|ca| {
-        let name = cx.expr_str(ca.span, ca.function_name.name);
-        let path = local_path(cx, ca.span, ca.function_name);
-        let registrar = cx.expr_ident(ca.span, registrar);
-
-        let ufcs_path = cx.path(span,
-                                vec![proc_macro, __internal, registry, register_attr_proc_macro]);
-
-        cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path),
-                                  vec![registrar, name, cx.expr_path(path)]))
-    }));
-
-    stmts.extend(custom_macros.iter().map(|cm| {
-        let name = cx.expr_str(cm.span, cm.function_name.name);
-        let path = local_path(cx, cm.span, cm.function_name);
-        let registrar = cx.expr_ident(cm.span, registrar);
-
-        let ufcs_path = cx.path(span,
-                                vec![proc_macro, __internal, registry, register_bang_proc_macro]);
-
-        cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path),
-                                  vec![registrar, name, cx.expr_path(path)]))
-    }));
-
-    let path = cx.path(span, vec![proc_macro, __internal, registry]);
-    let registrar_path = cx.ty_path(path);
-    let arg_ty = cx.ty_rptr(span, registrar_path, None, ast::Mutability::Mutable);
-    let func = cx.item_fn(span,
-                          registrar,
-                          vec![cx.arg(span, registrar, arg_ty)],
-                          cx.ty(span, ast::TyKind::Tup(Vec::new())),
-                          cx.block(span, stmts));
-
-    let derive_registrar = cx.meta_word(span, Symbol::intern("rustc_derive_registrar"));
-    let derive_registrar = cx.attribute(span, derive_registrar);
-    let func = func.map(|mut i| {
-        i.attrs.push(derive_registrar);
+    let decls_static = cx.item_static(
+        span,
+        Ident::from_str("_DECLS"),
+        cx.ty_rptr(span,
+            cx.ty(span, ast::TyKind::Slice(
+                cx.ty_path(cx.path(span,
+                    vec![proc_macro, bridge, client, proc_macro_ty])))),
+            None, ast::Mutability::Immutable),
+        ast::Mutability::Immutable,
+        cx.expr_vec_slice(span, decls),
+    ).map(|mut i| {
+        let attr = cx.meta_word(span, Symbol::intern("rustc_proc_macro_decls"));
+        i.attrs.push(cx.attribute(span, attr));
         i.vis = respan(span, ast::VisibilityKind::Public);
         i
     });
-    let ident = ast::Ident::with_empty_ctxt(Symbol::gensym("registrar"));
-    let module = cx.item_mod(span, span, ident, Vec::new(), vec![krate, func]).map(|mut i| {
+
+    let module = cx.item_mod(
+        span,
+        span,
+        ast::Ident::with_empty_ctxt(Symbol::gensym("decls")),
+        vec![],
+        vec![krate, decls_static],
+    ).map(|mut i| {
         i.vis = respan(span, ast::VisibilityKind::Public);
         i
     });
diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs
index ff60262..43ef31a 100644
--- a/src/libsyntax_ext/proc_macro_impl.rs
+++ b/src/libsyntax_ext/proc_macro_impl.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::panic;
 
 use errors::FatalError;
 
@@ -17,11 +16,13 @@
 use syntax::tokenstream::TokenStream;
 use syntax::ext::base;
 
-use proc_macro::TokenStream as TsShim;
-use proc_macro::__internal;
+pub const EXEC_STRATEGY: ::proc_macro::bridge::server::SameThread =
+    ::proc_macro::bridge::server::SameThread;
 
 pub struct AttrProcMacro {
-    pub inner: fn(TsShim, TsShim) -> TsShim,
+    pub client: ::proc_macro::bridge::client::Client<
+        fn(::proc_macro::TokenStream, ::proc_macro::TokenStream) -> ::proc_macro::TokenStream,
+    >,
 }
 
 impl base::AttrProcMacro for AttrProcMacro {
@@ -31,22 +32,13 @@
                    annotation: TokenStream,
                    annotated: TokenStream)
                    -> TokenStream {
-        let annotation = __internal::token_stream_wrap(annotation);
-        let annotated = __internal::token_stream_wrap(annotated);
-
-        let res = __internal::set_sess(ecx, || {
-            panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(annotation, annotated)))
-        });
-
-        match res {
-            Ok(stream) => __internal::token_stream_inner(stream),
+        let server = ::proc_macro_server::Rustc::new(ecx);
+        match self.client.run(&EXEC_STRATEGY, server, annotation, annotated) {
+            Ok(stream) => stream,
             Err(e) => {
                 let msg = "custom attribute panicked";
                 let mut err = ecx.struct_span_fatal(span, msg);
-                if let Some(s) = e.downcast_ref::<String>() {
-                    err.help(&format!("message: {}", s));
-                }
-                if let Some(s) = e.downcast_ref::<&'static str>() {
+                if let Some(s) = e.as_str() {
                     err.help(&format!("message: {}", s));
                 }
 
@@ -58,7 +50,9 @@
 }
 
 pub struct BangProcMacro {
-    pub inner: fn(TsShim) -> TsShim,
+    pub client: ::proc_macro::bridge::client::Client<
+        fn(::proc_macro::TokenStream) -> ::proc_macro::TokenStream,
+    >,
 }
 
 impl base::ProcMacro for BangProcMacro {
@@ -67,21 +61,13 @@
                    span: Span,
                    input: TokenStream)
                    -> TokenStream {
-        let input = __internal::token_stream_wrap(input);
-
-        let res = __internal::set_sess(ecx, || {
-            panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(input)))
-        });
-
-        match res {
-            Ok(stream) => __internal::token_stream_inner(stream),
+        let server = ::proc_macro_server::Rustc::new(ecx);
+        match self.client.run(&EXEC_STRATEGY, server, input) {
+            Ok(stream) => stream,
             Err(e) => {
                 let msg = "proc macro panicked";
                 let mut err = ecx.struct_span_fatal(span, msg);
-                if let Some(s) = e.downcast_ref::<String>() {
-                    err.help(&format!("message: {}", s));
-                }
-                if let Some(s) = e.downcast_ref::<&'static str>() {
+                if let Some(s) = e.as_str() {
                     err.help(&format!("message: {}", s));
                 }
 
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
new file mode 100644
index 0000000..6c7da58
--- /dev/null
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -0,0 +1,750 @@
+// 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 errors::{self, Diagnostic, DiagnosticBuilder};
+use std::panic;
+
+use proc_macro::bridge::{server, TokenTree};
+use proc_macro::{Delimiter, Level, LineColumn, Spacing};
+
+use rustc_data_structures::sync::Lrc;
+use std::ascii;
+use std::ops::Bound;
+use syntax::ast;
+use syntax::ext::base::ExtCtxt;
+use syntax::parse::lexer::comments;
+use syntax::parse::{self, token, ParseSess};
+use syntax::tokenstream::{self, DelimSpan, TokenStream};
+use syntax_pos::hygiene::{SyntaxContext, Transparency};
+use syntax_pos::symbol::{keywords, Symbol};
+use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
+
+trait FromInternal<T> {
+    fn from_internal(x: T) -> Self;
+}
+
+trait ToInternal<T> {
+    fn to_internal(self) -> T;
+}
+
+impl FromInternal<token::DelimToken> for Delimiter {
+    fn from_internal(delim: token::DelimToken) -> Delimiter {
+        match delim {
+            token::Paren => Delimiter::Parenthesis,
+            token::Brace => Delimiter::Brace,
+            token::Bracket => Delimiter::Bracket,
+            token::NoDelim => Delimiter::None,
+        }
+    }
+}
+
+impl ToInternal<token::DelimToken> for Delimiter {
+    fn to_internal(self) -> token::DelimToken {
+        match self {
+            Delimiter::Parenthesis => token::Paren,
+            Delimiter::Brace => token::Brace,
+            Delimiter::Bracket => token::Bracket,
+            Delimiter::None => token::NoDelim,
+        }
+    }
+}
+
+impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
+    for TokenTree<Group, Punct, Ident, Literal>
+{
+    fn from_internal((stream, sess, stack): (TokenStream, &ParseSess, &mut Vec<Self>)) -> Self {
+        use syntax::parse::token::*;
+
+        let (tree, joint) = stream.as_tree();
+        let (span, token) = match tree {
+            tokenstream::TokenTree::Delimited(span, delimed) => {
+                let delimiter = Delimiter::from_internal(delimed.delim);
+                return TokenTree::Group(Group {
+                    delimiter,
+                    stream: delimed.tts.into(),
+                    span,
+                });
+            }
+            tokenstream::TokenTree::Token(span, token) => (span, token),
+        };
+
+        macro_rules! tt {
+            ($ty:ident { $($field:ident $(: $value:expr)*),+ $(,)* }) => (
+                TokenTree::$ty(self::$ty {
+                    $($field $(: $value)*,)*
+                    span,
+                })
+            )
+        }
+        macro_rules! op {
+            ($a:expr) => {
+                tt!(Punct { ch: $a, joint })
+            };
+            ($a:expr, $b:expr) => {{
+                stack.push(tt!(Punct { ch: $b, joint }));
+                tt!(Punct {
+                    ch: $a,
+                    joint: true
+                })
+            }};
+            ($a:expr, $b:expr, $c:expr) => {{
+                stack.push(tt!(Punct { ch: $c, joint }));
+                stack.push(tt!(Punct {
+                    ch: $b,
+                    joint: true
+                }));
+                tt!(Punct {
+                    ch: $a,
+                    joint: true
+                })
+            }};
+        }
+
+        match token {
+            Eq => op!('='),
+            Lt => op!('<'),
+            Le => op!('<', '='),
+            EqEq => op!('=', '='),
+            Ne => op!('!', '='),
+            Ge => op!('>', '='),
+            Gt => op!('>'),
+            AndAnd => op!('&', '&'),
+            OrOr => op!('|', '|'),
+            Not => op!('!'),
+            Tilde => op!('~'),
+            BinOp(Plus) => op!('+'),
+            BinOp(Minus) => op!('-'),
+            BinOp(Star) => op!('*'),
+            BinOp(Slash) => op!('/'),
+            BinOp(Percent) => op!('%'),
+            BinOp(Caret) => op!('^'),
+            BinOp(And) => op!('&'),
+            BinOp(Or) => op!('|'),
+            BinOp(Shl) => op!('<', '<'),
+            BinOp(Shr) => op!('>', '>'),
+            BinOpEq(Plus) => op!('+', '='),
+            BinOpEq(Minus) => op!('-', '='),
+            BinOpEq(Star) => op!('*', '='),
+            BinOpEq(Slash) => op!('/', '='),
+            BinOpEq(Percent) => op!('%', '='),
+            BinOpEq(Caret) => op!('^', '='),
+            BinOpEq(And) => op!('&', '='),
+            BinOpEq(Or) => op!('|', '='),
+            BinOpEq(Shl) => op!('<', '<', '='),
+            BinOpEq(Shr) => op!('>', '>', '='),
+            At => op!('@'),
+            Dot => op!('.'),
+            DotDot => op!('.', '.'),
+            DotDotDot => op!('.', '.', '.'),
+            DotDotEq => op!('.', '.', '='),
+            Comma => op!(','),
+            Semi => op!(';'),
+            Colon => op!(':'),
+            ModSep => op!(':', ':'),
+            RArrow => op!('-', '>'),
+            LArrow => op!('<', '-'),
+            FatArrow => op!('=', '>'),
+            Pound => op!('#'),
+            Dollar => op!('$'),
+            Question => op!('?'),
+            SingleQuote => op!('\''),
+
+            Ident(ident, is_raw) => tt!(Ident {
+                sym: ident.name,
+                is_raw
+            }),
+            Lifetime(ident) => {
+                let ident = ident.without_first_quote();
+                stack.push(tt!(Ident {
+                    sym: ident.name,
+                    is_raw: false
+                }));
+                tt!(Punct {
+                    ch: '\'',
+                    joint: true
+                })
+            }
+            Literal(lit, suffix) => tt!(Literal { lit, suffix }),
+            DocComment(c) => {
+                let style = comments::doc_comment_style(&c.as_str());
+                let stripped = comments::strip_doc_comment_decoration(&c.as_str());
+                let mut escaped = String::new();
+                for ch in stripped.chars() {
+                    escaped.extend(ch.escape_debug());
+                }
+                let stream = vec![
+                    Ident(ast::Ident::new(Symbol::intern("doc"), span), false),
+                    Eq,
+                    Literal(Lit::Str_(Symbol::intern(&escaped)), None),
+                ]
+                .into_iter()
+                .map(|token| tokenstream::TokenTree::Token(span, token))
+                .collect();
+                stack.push(TokenTree::Group(Group {
+                    delimiter: Delimiter::Bracket,
+                    stream,
+                    span: DelimSpan::from_single(span),
+                }));
+                if style == ast::AttrStyle::Inner {
+                    stack.push(tt!(Punct {
+                        ch: '!',
+                        joint: false
+                    }));
+                }
+                tt!(Punct {
+                    ch: '#',
+                    joint: false
+                })
+            }
+
+            Interpolated(_) => {
+                let stream = token.interpolated_to_tokenstream(sess, span);
+                TokenTree::Group(Group {
+                    delimiter: Delimiter::None,
+                    stream,
+                    span: DelimSpan::from_single(span),
+                })
+            }
+
+            OpenDelim(..) | CloseDelim(..) => unreachable!(),
+            Whitespace | Comment | Shebang(..) | Eof => unreachable!(),
+        }
+    }
+}
+
+impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
+    fn to_internal(self) -> TokenStream {
+        use syntax::parse::token::*;
+
+        let (ch, joint, span) = match self {
+            TokenTree::Punct(Punct { ch, joint, span }) => (ch, joint, span),
+            TokenTree::Group(Group {
+                delimiter,
+                stream,
+                span,
+            }) => {
+                return tokenstream::TokenTree::Delimited(
+                    span,
+                    tokenstream::Delimited {
+                        delim: delimiter.to_internal(),
+                        tts: stream.into(),
+                    },
+                )
+                .into();
+            }
+            TokenTree::Ident(self::Ident { sym, span, is_raw }) => {
+                let token = Ident(ast::Ident::new(sym, span), is_raw);
+                return tokenstream::TokenTree::Token(span, token).into();
+            }
+            TokenTree::Literal(self::Literal {
+                lit: Lit::Integer(ref a),
+                suffix,
+                span,
+            }) if a.as_str().starts_with("-") => {
+                let minus = BinOp(BinOpToken::Minus);
+                let integer = Symbol::intern(&a.as_str()[1..]);
+                let integer = Literal(Lit::Integer(integer), suffix);
+                let a = tokenstream::TokenTree::Token(span, minus);
+                let b = tokenstream::TokenTree::Token(span, integer);
+                return vec![a, b].into_iter().collect();
+            }
+            TokenTree::Literal(self::Literal {
+                lit: Lit::Float(ref a),
+                suffix,
+                span,
+            }) if a.as_str().starts_with("-") => {
+                let minus = BinOp(BinOpToken::Minus);
+                let float = Symbol::intern(&a.as_str()[1..]);
+                let float = Literal(Lit::Float(float), suffix);
+                let a = tokenstream::TokenTree::Token(span, minus);
+                let b = tokenstream::TokenTree::Token(span, float);
+                return vec![a, b].into_iter().collect();
+            }
+            TokenTree::Literal(self::Literal { lit, suffix, span }) => {
+                return tokenstream::TokenTree::Token(span, Literal(lit, suffix)).into()
+            }
+        };
+
+        let token = match ch {
+            '=' => Eq,
+            '<' => Lt,
+            '>' => Gt,
+            '!' => Not,
+            '~' => Tilde,
+            '+' => BinOp(Plus),
+            '-' => BinOp(Minus),
+            '*' => BinOp(Star),
+            '/' => BinOp(Slash),
+            '%' => BinOp(Percent),
+            '^' => BinOp(Caret),
+            '&' => BinOp(And),
+            '|' => BinOp(Or),
+            '@' => At,
+            '.' => Dot,
+            ',' => Comma,
+            ';' => Semi,
+            ':' => Colon,
+            '#' => Pound,
+            '$' => Dollar,
+            '?' => Question,
+            '\'' => SingleQuote,
+            _ => unreachable!(),
+        };
+
+        let tree = tokenstream::TokenTree::Token(span, token);
+        if joint {
+            tree.joint()
+        } else {
+            tree.into()
+        }
+    }
+}
+
+impl ToInternal<errors::Level> for Level {
+    fn to_internal(self) -> errors::Level {
+        match self {
+            Level::Error => errors::Level::Error,
+            Level::Warning => errors::Level::Warning,
+            Level::Note => errors::Level::Note,
+            Level::Help => errors::Level::Help,
+            _ => unreachable!("unknown proc_macro::Level variant: {:?}", self),
+        }
+    }
+}
+
+#[derive(Clone)]
+pub struct TokenStreamIter {
+    cursor: tokenstream::Cursor,
+    stack: Vec<TokenTree<Group, Punct, Ident, Literal>>,
+}
+
+#[derive(Clone)]
+pub struct Group {
+    delimiter: Delimiter,
+    stream: TokenStream,
+    span: DelimSpan,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+pub struct Punct {
+    ch: char,
+    // NB. not using `Spacing` here because it doesn't implement `Hash`.
+    joint: bool,
+    span: Span,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+pub struct Ident {
+    sym: Symbol,
+    span: Span,
+    is_raw: bool,
+}
+
+// FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
+#[derive(Clone, Debug)]
+pub struct Literal {
+    lit: token::Lit,
+    suffix: Option<Symbol>,
+    span: Span,
+}
+
+pub(crate) struct Rustc<'a> {
+    sess: &'a ParseSess,
+    def_site: Span,
+    call_site: Span,
+}
+
+impl<'a> Rustc<'a> {
+    pub fn new(cx: &'a ExtCtxt) -> Self {
+        // No way to determine def location for a proc macro right now, so use call location.
+        let location = cx.current_expansion.mark.expn_info().unwrap().call_site;
+        let to_span = |transparency| {
+            location.with_ctxt(
+                SyntaxContext::empty()
+                    .apply_mark_with_transparency(cx.current_expansion.mark, transparency),
+            )
+        };
+        Rustc {
+            sess: cx.parse_sess,
+            def_site: to_span(Transparency::Opaque),
+            call_site: to_span(Transparency::Transparent),
+        }
+    }
+}
+
+impl server::Types for Rustc<'_> {
+    type TokenStream = TokenStream;
+    type TokenStreamBuilder = tokenstream::TokenStreamBuilder;
+    type TokenStreamIter = TokenStreamIter;
+    type Group = Group;
+    type Punct = Punct;
+    type Ident = Ident;
+    type Literal = Literal;
+    type SourceFile = Lrc<SourceFile>;
+    type MultiSpan = Vec<Span>;
+    type Diagnostic = Diagnostic;
+    type Span = Span;
+}
+
+impl server::TokenStream for Rustc<'_> {
+    fn new(&mut self) -> Self::TokenStream {
+        TokenStream::empty()
+    }
+    fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
+        stream.is_empty()
+    }
+    fn from_str(&mut self, src: &str) -> Self::TokenStream {
+        parse::parse_stream_from_source_str(
+            FileName::proc_macro_source_code(src.clone()),
+            src.to_string(),
+            self.sess,
+            Some(self.call_site),
+        )
+    }
+    fn to_string(&mut self, stream: &Self::TokenStream) -> String {
+        stream.to_string()
+    }
+    fn from_token_tree(
+        &mut self,
+        tree: TokenTree<Self::Group, Self::Punct, Self::Ident, Self::Literal>,
+    ) -> Self::TokenStream {
+        tree.to_internal()
+    }
+    fn into_iter(&mut self, stream: Self::TokenStream) -> Self::TokenStreamIter {
+        TokenStreamIter {
+            cursor: stream.trees(),
+            stack: vec![],
+        }
+    }
+}
+
+impl server::TokenStreamBuilder for Rustc<'_> {
+    fn new(&mut self) -> Self::TokenStreamBuilder {
+        tokenstream::TokenStreamBuilder::new()
+    }
+    fn push(&mut self, builder: &mut Self::TokenStreamBuilder, stream: Self::TokenStream) {
+        builder.push(stream);
+    }
+    fn build(&mut self, builder: Self::TokenStreamBuilder) -> Self::TokenStream {
+        builder.build()
+    }
+}
+
+impl server::TokenStreamIter for Rustc<'_> {
+    fn next(
+        &mut self,
+        iter: &mut Self::TokenStreamIter,
+    ) -> Option<TokenTree<Self::Group, Self::Punct, Self::Ident, Self::Literal>> {
+        loop {
+            let tree = iter.stack.pop().or_else(|| {
+                let next = iter.cursor.next_as_stream()?;
+                Some(TokenTree::from_internal((next, self.sess, &mut iter.stack)))
+            })?;
+            // HACK: The condition "dummy span + group with empty delimiter" represents an AST
+            // fragment approximately converted into a token stream. This may happen, for
+            // example, with inputs to proc macro attributes, including derives. Such "groups"
+            // need to flattened during iteration over stream's token trees.
+            // Eventually this needs to be removed in favor of keeping original token trees
+            // and not doing the roundtrip through AST.
+            if let TokenTree::Group(ref group) = tree {
+                if group.delimiter == Delimiter::None && group.span.entire().is_dummy() {
+                    iter.cursor.insert(group.stream.clone());
+                    continue;
+                }
+            }
+            return Some(tree);
+        }
+    }
+}
+
+impl server::Group for Rustc<'_> {
+    fn new(&mut self, delimiter: Delimiter, stream: Self::TokenStream) -> Self::Group {
+        Group {
+            delimiter,
+            stream,
+            span: DelimSpan::from_single(server::Span::call_site(self)),
+        }
+    }
+    fn delimiter(&mut self, group: &Self::Group) -> Delimiter {
+        group.delimiter
+    }
+    fn stream(&mut self, group: &Self::Group) -> Self::TokenStream {
+        group.stream.clone()
+    }
+    fn span(&mut self, group: &Self::Group) -> Self::Span {
+        group.span.entire()
+    }
+    fn span_open(&mut self, group: &Self::Group) -> Self::Span {
+        group.span.open
+    }
+    fn span_close(&mut self, group: &Self::Group) -> Self::Span {
+        group.span.close
+    }
+    fn set_span(&mut self, group: &mut Self::Group, span: Self::Span) {
+        group.span = DelimSpan::from_single(span);
+    }
+}
+
+impl server::Punct for Rustc<'_> {
+    fn new(&mut self, ch: char, spacing: Spacing) -> Self::Punct {
+        Punct {
+            ch,
+            joint: spacing == Spacing::Joint,
+            span: server::Span::call_site(self),
+        }
+    }
+    fn as_char(&mut self, punct: Self::Punct) -> char {
+        punct.ch
+    }
+    fn spacing(&mut self, punct: Self::Punct) -> Spacing {
+        if punct.joint {
+            Spacing::Joint
+        } else {
+            Spacing::Alone
+        }
+    }
+    fn span(&mut self, punct: Self::Punct) -> Self::Span {
+        punct.span
+    }
+    fn with_span(&mut self, punct: Self::Punct, span: Self::Span) -> Self::Punct {
+        Punct { span, ..punct }
+    }
+}
+
+impl server::Ident for Rustc<'_> {
+    fn new(&mut self, string: &str, span: Self::Span, is_raw: bool) -> Self::Ident {
+        let sym = Symbol::intern(string);
+        if is_raw
+            && (sym == keywords::Underscore.name()
+                || ast::Ident::with_empty_ctxt(sym).is_path_segment_keyword())
+        {
+            panic!("`{:?}` is not a valid raw identifier", string)
+        }
+        Ident { sym, span, is_raw }
+    }
+    fn span(&mut self, ident: Self::Ident) -> Self::Span {
+        ident.span
+    }
+    fn with_span(&mut self, ident: Self::Ident, span: Self::Span) -> Self::Ident {
+        Ident { span, ..ident }
+    }
+}
+
+impl server::Literal for Rustc<'_> {
+    // FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
+    fn debug(&mut self, literal: &Self::Literal) -> String {
+        format!("{:?}", literal)
+    }
+    fn integer(&mut self, n: &str) -> Self::Literal {
+        Literal {
+            lit: token::Lit::Integer(Symbol::intern(n)),
+            suffix: None,
+            span: server::Span::call_site(self),
+        }
+    }
+    fn typed_integer(&mut self, n: &str, kind: &str) -> Self::Literal {
+        Literal {
+            lit: token::Lit::Integer(Symbol::intern(n)),
+            suffix: Some(Symbol::intern(kind)),
+            span: server::Span::call_site(self),
+        }
+    }
+    fn float(&mut self, n: &str) -> Self::Literal {
+        Literal {
+            lit: token::Lit::Float(Symbol::intern(n)),
+            suffix: None,
+            span: server::Span::call_site(self),
+        }
+    }
+    fn f32(&mut self, n: &str) -> Self::Literal {
+        Literal {
+            lit: token::Lit::Float(Symbol::intern(n)),
+            suffix: Some(Symbol::intern("f32")),
+            span: server::Span::call_site(self),
+        }
+    }
+    fn f64(&mut self, n: &str) -> Self::Literal {
+        Literal {
+            lit: token::Lit::Float(Symbol::intern(n)),
+            suffix: Some(Symbol::intern("f64")),
+            span: server::Span::call_site(self),
+        }
+    }
+    fn string(&mut self, string: &str) -> Self::Literal {
+        let mut escaped = String::new();
+        for ch in string.chars() {
+            escaped.extend(ch.escape_debug());
+        }
+        Literal {
+            lit: token::Lit::Str_(Symbol::intern(&escaped)),
+            suffix: None,
+            span: server::Span::call_site(self),
+        }
+    }
+    fn character(&mut self, ch: char) -> Self::Literal {
+        let mut escaped = String::new();
+        escaped.extend(ch.escape_unicode());
+        Literal {
+            lit: token::Lit::Char(Symbol::intern(&escaped)),
+            suffix: None,
+            span: server::Span::call_site(self),
+        }
+    }
+    fn byte_string(&mut self, bytes: &[u8]) -> Self::Literal {
+        let string = bytes
+            .iter()
+            .cloned()
+            .flat_map(ascii::escape_default)
+            .map(Into::<char>::into)
+            .collect::<String>();
+        Literal {
+            lit: token::Lit::ByteStr(Symbol::intern(&string)),
+            suffix: None,
+            span: server::Span::call_site(self),
+        }
+    }
+    fn span(&mut self, literal: &Self::Literal) -> Self::Span {
+        literal.span
+    }
+    fn set_span(&mut self, literal: &mut Self::Literal, span: Self::Span) {
+        literal.span = span;
+    }
+    fn subspan(
+        &mut self,
+        literal: &Self::Literal,
+        start: Bound<usize>,
+        end: Bound<usize>,
+    ) -> Option<Self::Span> {
+        let span = literal.span;
+        let length = span.hi().to_usize() - span.lo().to_usize();
+
+        let start = match start {
+            Bound::Included(lo) => lo,
+            Bound::Excluded(lo) => lo + 1,
+            Bound::Unbounded => 0,
+        };
+
+        let end = match end {
+            Bound::Included(hi) => hi + 1,
+            Bound::Excluded(hi) => hi,
+            Bound::Unbounded => length,
+        };
+
+        // Bounds check the values, preventing addition overflow and OOB spans.
+        if start > u32::max_value() as usize
+            || end > u32::max_value() as usize
+            || (u32::max_value() - start as u32) < span.lo().to_u32()
+            || (u32::max_value() - end as u32) < span.lo().to_u32()
+            || start >= end
+            || end > length
+        {
+            return None;
+        }
+
+        let new_lo = span.lo() + BytePos::from_usize(start);
+        let new_hi = span.lo() + BytePos::from_usize(end);
+        Some(span.with_lo(new_lo).with_hi(new_hi))
+    }
+}
+
+impl<'a> server::SourceFile for Rustc<'a> {
+    fn eq(&mut self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool {
+        Lrc::ptr_eq(file1, file2)
+    }
+    fn path(&mut self, file: &Self::SourceFile) -> String {
+        match file.name {
+            FileName::Real(ref path) => path
+                .to_str()
+                .expect("non-UTF8 file path in `proc_macro::SourceFile::path`")
+                .to_string(),
+            _ => file.name.to_string(),
+        }
+    }
+    fn is_real(&mut self, file: &Self::SourceFile) -> bool {
+        file.is_real_file()
+    }
+}
+
+impl server::MultiSpan for Rustc<'_> {
+    fn new(&mut self) -> Self::MultiSpan {
+        vec![]
+    }
+    fn push(&mut self, spans: &mut Self::MultiSpan, span: Self::Span) {
+        spans.push(span)
+    }
+}
+
+impl server::Diagnostic for Rustc<'_> {
+    fn new(&mut self, level: Level, msg: &str, spans: Self::MultiSpan) -> Self::Diagnostic {
+        let mut diag = Diagnostic::new(level.to_internal(), msg);
+        diag.set_span(MultiSpan::from_spans(spans));
+        diag
+    }
+    fn sub(
+        &mut self,
+        diag: &mut Self::Diagnostic,
+        level: Level,
+        msg: &str,
+        spans: Self::MultiSpan,
+    ) {
+        diag.sub(level.to_internal(), msg, MultiSpan::from_spans(spans), None);
+    }
+    fn emit(&mut self, diag: Self::Diagnostic) {
+        DiagnosticBuilder::new_diagnostic(&self.sess.span_diagnostic, diag).emit()
+    }
+}
+
+impl server::Span for Rustc<'_> {
+    fn debug(&mut self, span: Self::Span) -> String {
+        format!("{:?} bytes({}..{})", span.ctxt(), span.lo().0, span.hi().0)
+    }
+    fn def_site(&mut self) -> Self::Span {
+        self.def_site
+    }
+    fn call_site(&mut self) -> Self::Span {
+        self.call_site
+    }
+    fn source_file(&mut self, span: Self::Span) -> Self::SourceFile {
+        self.sess.source_map().lookup_char_pos(span.lo()).file
+    }
+    fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
+        span.ctxt().outer().expn_info().map(|i| i.call_site)
+    }
+    fn source(&mut self, span: Self::Span) -> Self::Span {
+        span.source_callsite()
+    }
+    fn start(&mut self, span: Self::Span) -> LineColumn {
+        let loc = self.sess.source_map().lookup_char_pos(span.lo());
+        LineColumn {
+            line: loc.line,
+            column: loc.col.to_usize(),
+        }
+    }
+    fn end(&mut self, span: Self::Span) -> LineColumn {
+        let loc = self.sess.source_map().lookup_char_pos(span.hi());
+        LineColumn {
+            line: loc.line,
+            column: loc.col.to_usize(),
+        }
+    }
+    fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
+        let self_loc = self.sess.source_map().lookup_char_pos(first.lo());
+        let other_loc = self.sess.source_map().lookup_char_pos(second.lo());
+
+        if self_loc.file.name != other_loc.file.name {
+            return None;
+        }
+
+        Some(first.to(second))
+    }
+    fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span {
+        span.with_ctxt(at.ctxt())
+    }
+}
diff --git a/src/libsyntax_pos/edition.rs b/src/libsyntax_pos/edition.rs
index 5819cd7..127dc43 100644
--- a/src/libsyntax_pos/edition.rs
+++ b/src/libsyntax_pos/edition.rs
@@ -13,7 +13,6 @@
 
 /// The edition of the compiler (RFC 2052)
 #[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, RustcEncodable, RustcDecodable, Eq)]
-#[non_exhaustive]
 pub enum Edition {
     // editions must be kept in order, oldest to newest
 
@@ -33,7 +32,7 @@
 // must be in order from oldest to newest
 pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018];
 
-pub const EDITION_NAME_LIST: &'static str = "2015|2018";
+pub const EDITION_NAME_LIST: &str = "2015|2018";
 
 pub const DEFAULT_EDITION: Edition = Edition::Edition2015;
 
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index bc52a3e..074687f 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -17,7 +17,7 @@
 
 use GLOBALS;
 use Span;
-use edition::Edition;
+use edition::{Edition, DEFAULT_EDITION};
 use symbol::Symbol;
 
 use serialize::{Encodable, Decodable, Encoder, Decoder};
@@ -217,7 +217,7 @@
                 opaque_and_semitransparent: SyntaxContext(0),
             }],
             markings: FxHashMap::default(),
-            default_edition: Edition::Edition2015,
+            default_edition: DEFAULT_EDITION,
         }
     }
 
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 65f6d27..4d42b85 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -90,19 +90,20 @@
     /// A macro.  This includes the full name of the macro, so that there are no clashes.
     Macros(String),
     /// call to `quote!`
-    QuoteExpansion,
+    QuoteExpansion(u64),
     /// Command line
-    Anon,
+    Anon(u64),
     /// Hack in src/libsyntax/parse.rs
     /// FIXME(jseyfried)
-    MacroExpansion,
-    ProcMacroSourceCode,
+    MacroExpansion(u64),
+    ProcMacroSourceCode(u64),
     /// Strings provided as --cfg [cfgspec] stored in a crate_cfg
-    CfgSpec,
+    CfgSpec(u64),
     /// Strings provided as crate attributes in the CLI
-    CliCrateAttr,
+    CliCrateAttr(u64),
     /// Custom sources for explicit parser calls from plugins and drivers
     Custom(String),
+    DocTest(PathBuf, isize),
 }
 
 impl std::fmt::Display for FileName {
@@ -111,13 +112,15 @@
         match *self {
             Real(ref path) => write!(fmt, "{}", path.display()),
             Macros(ref name) => write!(fmt, "<{} macros>", name),
-            QuoteExpansion => write!(fmt, "<quote expansion>"),
-            MacroExpansion => write!(fmt, "<macro expansion>"),
-            Anon => write!(fmt, "<anon>"),
-            ProcMacroSourceCode => write!(fmt, "<proc-macro source code>"),
-            CfgSpec => write!(fmt, "cfgspec"),
-            CliCrateAttr => write!(fmt, "<crate attribute>"),
+            QuoteExpansion(_) => write!(fmt, "<quote expansion>"),
+            MacroExpansion(_) => write!(fmt, "<macro expansion>"),
+            Anon(_) => write!(fmt, "<anon>"),
+            ProcMacroSourceCode(_) =>
+                write!(fmt, "<proc-macro source code>"),
+            CfgSpec(_) => write!(fmt, "<cfgspec>"),
+            CliCrateAttr(_) => write!(fmt, "<crate attribute>"),
             Custom(ref s) => write!(fmt, "<{}>", s),
+            DocTest(ref path, _) => write!(fmt, "{}", path.display()),
         }
     }
 }
@@ -135,13 +138,14 @@
         match *self {
             Real(_) => true,
             Macros(_) |
-            Anon |
-            MacroExpansion |
-            ProcMacroSourceCode |
-            CfgSpec |
-            CliCrateAttr |
+            Anon(_) |
+            MacroExpansion(_) |
+            ProcMacroSourceCode(_) |
+            CfgSpec(_) |
+            CliCrateAttr(_) |
             Custom(_) |
-            QuoteExpansion => false,
+            QuoteExpansion(_) |
+            DocTest(_, _) => false,
         }
     }
 
@@ -149,16 +153,57 @@
         use self::FileName::*;
         match *self {
             Real(_) |
-            Anon |
-            MacroExpansion |
-            ProcMacroSourceCode |
-            CfgSpec |
-            CliCrateAttr |
+            Anon(_) |
+            MacroExpansion(_) |
+            ProcMacroSourceCode(_) |
+            CfgSpec(_) |
+            CliCrateAttr(_) |
             Custom(_) |
-            QuoteExpansion => false,
+            QuoteExpansion(_) |
+            DocTest(_, _) => false,
             Macros(_) => true,
         }
     }
+
+    pub fn quote_expansion_source_code(src: &str) -> FileName {
+        let mut hasher = StableHasher::new();
+        src.hash(&mut hasher);
+        FileName::QuoteExpansion(hasher.finish())
+    }
+
+    pub fn macro_expansion_source_code(src: &str) -> FileName {
+        let mut hasher = StableHasher::new();
+        src.hash(&mut hasher);
+        FileName::MacroExpansion(hasher.finish())
+    }
+
+    pub fn anon_source_code(src: &str) -> FileName {
+        let mut hasher = StableHasher::new();
+        src.hash(&mut hasher);
+        FileName::Anon(hasher.finish())
+    }
+
+    pub fn proc_macro_source_code(src: &str) -> FileName {
+        let mut hasher = StableHasher::new();
+        src.hash(&mut hasher);
+        FileName::ProcMacroSourceCode(hasher.finish())
+    }
+
+    pub fn cfg_spec_source_code(src: &str) -> FileName {
+        let mut hasher = StableHasher::new();
+        src.hash(&mut hasher);
+        FileName::QuoteExpansion(hasher.finish())
+    }
+
+    pub fn cli_crate_attr_source_code(src: &str) -> FileName {
+        let mut hasher = StableHasher::new();
+        src.hash(&mut hasher);
+        FileName::CliCrateAttr(hasher.finish())
+    }
+
+    pub fn doc_test_source_code(path: PathBuf, line: isize) -> FileName{
+        FileName::DocTest(path, line)
+    }
 }
 
 /// Spans represent a region of code, used for error reporting. Positions in spans
@@ -587,6 +632,7 @@
 }
 
 impl MultiSpan {
+    #[inline]
     pub fn new() -> MultiSpan {
         MultiSpan {
             primary_spans: vec![],
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index e333a4f..847bf60 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -80,6 +80,10 @@
         Ident::new(self.name.gensymed(), self.span)
     }
 
+    pub fn gensym_if_underscore(self) -> Ident {
+        if self.name == keywords::Underscore.name() { self.gensym() } else { self }
+    }
+
     pub fn as_str(self) -> LocalInternedString {
         self.name.as_str()
     }
@@ -349,11 +353,11 @@
     // Special reserved identifiers used internally for elided lifetimes,
     // unnamed method parameters, crate root module, error recovery etc.
     (0,  Invalid,            "")
-    (1,  CrateRoot,          "{{root}}")
+    (1,  PathRoot,           "{{root}}")
     (2,  DollarCrate,        "$crate")
     (3,  Underscore,         "_")
 
-    // Keywords used in the language.
+    // Keywords that are used in stable Rust.
     (4,  As,                 "as")
     (5,  Box,                "box")
     (6,  Break,              "break")
@@ -378,8 +382,8 @@
     (25, Pub,                "pub")
     (26, Ref,                "ref")
     (27, Return,             "return")
-    (28, SelfValue,          "self")
-    (29, SelfType,           "Self")
+    (28, SelfLower,          "self")
+    (29, SelfUpper,          "Self")
     (30, Static,             "static")
     (31, Struct,             "struct")
     (32, Super,              "super")
@@ -391,7 +395,7 @@
     (38, Where,              "where")
     (39, While,              "while")
 
-    // Keywords reserved for future use.
+    // Keywords that are used in unstable Rust or reserved for future use.
     (40, Abstract,           "abstract")
     (41, Become,             "become")
     (42, Do,                 "do")
@@ -404,9 +408,11 @@
     (49, Virtual,            "virtual")
     (50, Yield,              "yield")
 
-    // Edition-specific keywords reserved for future use.
-    (51, Async,              "async") // >= 2018 Edition only
-    (52, Dyn,                "dyn") // >= 2018 Edition only
+    // Edition-specific keywords that are used in stable Rust.
+    (51, Dyn,                "dyn") // >= 2018 Edition only
+
+    // Edition-specific keywords that are used in unstable Rust or reserved for future use.
+    (52, Async,              "async") // >= 2018 Edition only
     (53, Try,                "try") // >= 2018 Edition only
 
     // Special lifetime names
@@ -417,11 +423,15 @@
     (56, Auto,               "auto")
     (57, Catch,              "catch")
     (58, Default,            "default")
-    (59, Union,              "union")
-    (60, Existential,        "existential")
+    (59, Existential,        "existential")
+    (60, Union,              "union")
 }
 
 impl Symbol {
+    fn is_used_keyword_2018(self) -> bool {
+        self == keywords::Dyn.name()
+    }
+
     fn is_unused_keyword_2018(self) -> bool {
         self >= keywords::Async.name() && self <= keywords::Try.name()
     }
@@ -436,7 +446,9 @@
 
     /// Returns `true` if the token is a keyword used in the language.
     pub fn is_used_keyword(self) -> bool {
-        self.name >= keywords::As.name() && self.name <= keywords::While.name()
+        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
+        self.name >= keywords::As.name() && self.name <= keywords::While.name() ||
+        self.name.is_used_keyword_2018() && self.span.rust_2018()
     }
 
     /// Returns `true` if the token is a keyword reserved for possible future use.
@@ -454,18 +466,18 @@
     /// A keyword or reserved identifier that can be used as a path segment.
     pub fn is_path_segment_keyword(self) -> bool {
         self.name == keywords::Super.name() ||
-        self.name == keywords::SelfValue.name() ||
-        self.name == keywords::SelfType.name() ||
+        self.name == keywords::SelfLower.name() ||
+        self.name == keywords::SelfUpper.name() ||
         self.name == keywords::Extern.name() ||
         self.name == keywords::Crate.name() ||
-        self.name == keywords::CrateRoot.name() ||
+        self.name == keywords::PathRoot.name() ||
         self.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(self) -> bool {
-        self.name != keywords::Invalid.name() &&
+        self.name != keywords::Invalid.name() && self.name != keywords::Underscore.name() &&
         self.is_reserved() && !self.is_path_segment_keyword()
     }
 }
@@ -492,6 +504,10 @@
             symbol: Symbol::intern(self.string)
         }
     }
+
+    pub fn get(&self) -> &'static str {
+        self.string
+    }
 }
 
 impl<U: ?Sized> ::std::convert::AsRef<U> for LocalInternedString
diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml
index ec77f95..aade10e 100644
--- a/src/libtest/Cargo.toml
+++ b/src/libtest/Cargo.toml
@@ -11,3 +11,6 @@
 [dependencies]
 getopts = "0.2"
 term = { path = "../libterm" }
+
+# not actually used but needed to always have proc_macro in the sysroot
+proc_macro = { path = "../libproc_macro" }
diff --git a/src/llvm b/src/llvm
index 21a0c9e..a784eca 160000
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 21a0c9ebc285d794a298e97717abad8d6135fa87
+Subproject commit a784eca10d2c1f09e65d67e16eca266485e1eac3
diff --git a/src/rustc/compiler_builtins_shim/Cargo.toml b/src/rustc/compiler_builtins_shim/Cargo.toml
index 7d8423c..9804177 100644
--- a/src/rustc/compiler_builtins_shim/Cargo.toml
+++ b/src/rustc/compiler_builtins_shim/Cargo.toml
@@ -34,7 +34,7 @@
 
 [features]
 c = []
-default = ["c", "rustbuild", "compiler-builtins"]
+default = ["rustbuild", "compiler-builtins"]
 mem = []
 rustbuild = []
 compiler-builtins = []
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 06de0d6..aa420bf 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -284,7 +284,7 @@
   report_fatal_error("Bad RelocModel.");
 }
 
-#if LLVM_RUSTLLVM
+#ifdef LLVM_RUSTLLVM
 /// getLongestEntryLength - Return the length of the longest entry in the table.
 ///
 static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index b6e0794..b9a0b43 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -533,6 +533,14 @@
 
 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
 
+extern "C" bool LLVMRustIsRustLLVM() {
+#ifdef LLVM_RUSTLLVM
+  return 1;
+#else
+  return 0;
+#endif
+}
+
 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
                                       uint32_t Value) {
   unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
@@ -824,11 +832,13 @@
 }
 
 extern "C" void
-LLVMRustDICompositeTypeSetTypeArray(LLVMRustDIBuilderRef Builder,
-                                    LLVMMetadataRef CompositeTy,
-                                    LLVMMetadataRef TyArray) {
+LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
+                                     LLVMMetadataRef CompositeTy,
+                                     LLVMMetadataRef Elements,
+                                     LLVMMetadataRef Params) {
   DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
-  Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(TyArray)));
+  Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
+                         DINodeArray(unwrap<MDTuple>(Params)));
 }
 
 extern "C" LLVMValueRef
diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger
index f8ff3d3..9cf17c4 100644
--- a/src/rustllvm/llvm-rebuild-trigger
+++ b/src/rustllvm/llvm-rebuild-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2018-09-16
+2018-11-28
diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md
index 81a46ea..c4ca478 100644
--- a/src/test/COMPILER_TESTS.md
+++ b/src/test/COMPILER_TESTS.md
@@ -1,4 +1,4 @@
 # Compiler Test Documentation
 
 Documentation the compiler testing framework has moved to
-[the rustc guide](https://rust-lang-nursery.github.io/rustc-guide/tests/intro.html).
+[the rustc guide](https://rust-lang.github.io/rustc-guide/tests/intro.html).
diff --git a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
index cec88f1..1793a31 100644
--- a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
+++ b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
@@ -14,7 +14,7 @@
 
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<drop_in_place_intrinsic::StructWithDtor[0]> @@ drop_in_place_intrinsic-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<drop_in_place_intrinsic::StructWithDtor[0]> @@ drop_in_place_intrinsic-cgu.0[Internal]
 struct StructWithDtor(u32);
 
 impl Drop for StructWithDtor {
@@ -26,7 +26,7 @@
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal]
     let x = [StructWithDtor(0), StructWithDtor(1)];
 
     drop_slice_in_place(&x);
@@ -41,6 +41,7 @@
         // not have drop-glue for the unsized [StructWithDtor]. This has to be
         // generated though when the drop_in_place() intrinsic is used.
         //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal]
+        //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal]
         ::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]);
     }
 }
diff --git a/src/test/codegen-units/item-collection/generic-drop-glue.rs b/src/test/codegen-units/item-collection/generic-drop-glue.rs
index 5afa519..4ae5832 100644
--- a/src/test/codegen-units/item-collection/generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/generic-drop-glue.rs
@@ -47,7 +47,7 @@
 struct NonGenericNoDrop(i32);
 
 struct NonGenericWithDrop(i32);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::NonGenericWithDrop[0]> @@ generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::NonGenericWithDrop[0]> @@ generic_drop_glue-cgu.0[Internal]
 
 impl Drop for NonGenericWithDrop {
     //~ MONO_ITEM fn generic_drop_glue::{{impl}}[2]::drop[0]
@@ -57,11 +57,11 @@
 //~ MONO_ITEM fn generic_drop_glue::start[0]
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<i8, char>> @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<i8, char>> @@ generic_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<i8, char>
     let _ = StructWithDrop { x: 0i8, y: 'a' }.x;
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>> @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>> @@ generic_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>
     let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y;
 
@@ -70,17 +70,17 @@
 
     // This is supposed to generate drop-glue because it contains a field that
     // needs to be dropped.
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructNoDrop[0]<generic_drop_glue::NonGenericWithDrop[0], f64>> @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::StructNoDrop[0]<generic_drop_glue::NonGenericWithDrop[0], f64>> @@ generic_drop_glue-cgu.0[Internal]
     let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y;
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<i32, i64>> @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<i32, i64>> @@ generic_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<i32, i64>
     let _ = match EnumWithDrop::A::<i32, i64>(0) {
         EnumWithDrop::A(x) => x,
         EnumWithDrop::B(x) => x as i32
     };
 
-    //~MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<f64, f32>> @@ generic_drop_glue-cgu.0[Internal]
+    //~MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<f64, f32>> @@ generic_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<f64, f32>
     let _ = match EnumWithDrop::B::<f64, f32>(1.0) {
         EnumWithDrop::A(x) => x,
diff --git a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
index d09d343..bfa67b1 100644
--- a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
+++ b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
@@ -34,13 +34,13 @@
 fn start(_: isize, _: *const *const u8) -> isize {
     let s1 = Struct { _a: 0u32 };
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u32>> @@ instantiation_through_vtable-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<instantiation_through_vtable::Struct[0]<u32>> @@ instantiation_through_vtable-cgu.0[Internal]
     //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u32>
     //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u32>
     let _ = &s1 as &Trait;
 
     let s1 = Struct { _a: 0u64 };
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u64>> @@ instantiation_through_vtable-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<instantiation_through_vtable::Struct[0]<u64>> @@ instantiation_through_vtable-cgu.0[Internal]
     //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u64>
     //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u64>
     let _ = &s1 as &Trait;
diff --git a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
index a939dd5..2d72383 100644
--- a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
@@ -15,7 +15,7 @@
 #![deny(dead_code)]
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::StructWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<non_generic_drop_glue::StructWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
 struct StructWithDrop {
     x: i32
 }
@@ -29,7 +29,7 @@
     x: i32
 }
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::EnumWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<non_generic_drop_glue::EnumWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
 enum EnumWithDrop {
     A(i32)
 }
diff --git a/src/test/codegen-units/item-collection/transitive-drop-glue.rs b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
index 7bbc9b6..d901717 100644
--- a/src/test/codegen-units/item-collection/transitive-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
@@ -15,11 +15,11 @@
 #![deny(dead_code)]
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Root[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::Root[0]> @@ transitive_drop_glue-cgu.0[Internal]
 struct Root(Intermediate);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Intermediate[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::Intermediate[0]> @@ transitive_drop_glue-cgu.0[Internal]
 struct Intermediate(Leaf);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Leaf[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::Leaf[0]> @@ transitive_drop_glue-cgu.0[Internal]
 struct Leaf;
 
 impl Drop for Leaf {
@@ -40,15 +40,15 @@
 fn start(_: isize, _: *const *const u8) -> isize {
     let _ = Root(Intermediate(Leaf));
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::RootGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::LeafGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<u32>
     let _ = RootGen(IntermediateGen(LeafGen(0u32)));
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::RootGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::LeafGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<i16>
     let _ = RootGen(IntermediateGen(LeafGen(0i16)));
 
diff --git a/src/test/codegen-units/item-collection/tuple-drop-glue.rs b/src/test/codegen-units/item-collection/tuple-drop-glue.rs
index 865570c..e94af0c 100644
--- a/src/test/codegen-units/item-collection/tuple-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/tuple-drop-glue.rs
@@ -15,7 +15,7 @@
 #![deny(dead_code)]
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<tuple_drop_glue::Dropped[0]> @@ tuple_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<tuple_drop_glue::Dropped[0]> @@ tuple_drop_glue-cgu.0[Internal]
 struct Dropped;
 
 impl Drop for Dropped {
@@ -26,11 +26,11 @@
 //~ MONO_ITEM fn tuple_drop_glue::start[0]
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal]
     let x = (0u32, Dropped);
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal]
     let x = (0i16, (Dropped, true));
 
     0
diff --git a/src/test/codegen-units/item-collection/unsizing.rs b/src/test/codegen-units/item-collection/unsizing.rs
index 5e9a325..c85f7fc 100644
--- a/src/test/codegen-units/item-collection/unsizing.rs
+++ b/src/test/codegen-units/item-collection/unsizing.rs
@@ -59,13 +59,13 @@
 fn start(_: isize, _: *const *const u8) -> isize {
     // simple case
     let bool_sized = &true;
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<bool> @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<bool> @@ unsizing-cgu.0[Internal]
     //~ MONO_ITEM fn unsizing::{{impl}}[0]::foo[0]
     let _bool_unsized = bool_sized as &Trait;
 
     let char_sized = &'a';
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<char> @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<char> @@ unsizing-cgu.0[Internal]
     //~ MONO_ITEM fn unsizing::{{impl}}[1]::foo[0]
     let _char_unsized = char_sized as &Trait;
 
@@ -75,13 +75,13 @@
         _b: 2,
         _c: 3.0f64
     };
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<f64> @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<f64> @@ unsizing-cgu.0[Internal]
     //~ MONO_ITEM fn unsizing::{{impl}}[2]::foo[0]
     let _struct_unsized = struct_sized as &Struct<Trait>;
 
     // custom coercion
     let wrapper_sized = Wrapper(&0u32);
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<u32> @@ unsizing-cgu.0[Internal]
     //~ MONO_ITEM fn unsizing::{{impl}}[3]::foo[0]
     let _wrapper_sized = wrapper_sized as Wrapper<Trait>;
 
diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs
index cbad3a6..87b4430 100644
--- a/src/test/codegen-units/partitioning/extern-drop-glue.rs
+++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs
@@ -21,14 +21,14 @@
 // aux-build:cgu_extern_drop_glue.rs
 extern crate cgu_extern_drop_glue;
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal]
 
 struct LocalStruct(cgu_extern_drop_glue::Struct);
 
 //~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
 pub fn user()
 {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
     let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
 }
 
@@ -40,7 +40,7 @@
     //~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
     pub fn user()
     {
-        //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
+        //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
         let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
     }
 }
diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs
index 98729d9..e09eb31 100644
--- a/src/test/codegen-units/partitioning/local-drop-glue.rs
+++ b/src/test/codegen-units/partitioning/local-drop-glue.rs
@@ -17,7 +17,7 @@
 #![allow(dead_code)]
 #![crate_type="rlib"]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
 struct Struct {
     _a: u32
 }
@@ -27,7 +27,7 @@
     fn drop(&mut self) {}
 }
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue[Internal]
 struct Outer {
     _a: Struct
 }
@@ -46,10 +46,10 @@
 {
     use super::Struct;
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-mod1[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-mod1[Internal]
     struct Struct2 {
         _a: Struct,
-        //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal]
+        //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal]
         _b: (u32, Struct),
     }
 
diff --git a/src/test/codegen-units/partitioning/vtable-through-const.rs b/src/test/codegen-units/partitioning/vtable-through-const.rs
index ebda08a..459c6b6 100644
--- a/src/test/codegen-units/partitioning/vtable-through-const.rs
+++ b/src/test/codegen-units/partitioning/vtable-through-const.rs
@@ -76,7 +76,7 @@
 //~ MONO_ITEM fn vtable_through_const::start[0]
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ vtable_through_const[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<u32> @@ vtable_through_const[Internal]
 
     // Since Trait1::do_something() is instantiated via its default implementation,
     // it is considered a generic and is instantiated here only because it is
diff --git a/src/test/codegen/export-no-mangle.rs b/src/test/codegen/export-no-mangle.rs
index 3546284..95587d9 100644
--- a/src/test/codegen/export-no-mangle.rs
+++ b/src/test/codegen/export-no-mangle.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-flags: -C no-prepopulate-passes
+
 #![crate_type = "lib"]
 
 mod private {
diff --git a/src/test/codegen/external-no-mangle-fns.rs b/src/test/codegen/external-no-mangle-fns.rs
index 3f092b8..5823285 100644
--- a/src/test/codegen/external-no-mangle-fns.rs
+++ b/src/test/codegen/external-no-mangle-fns.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -O
+// compile-flags: -C no-prepopulate-passes
 // `#[no_mangle]`d functions always have external linkage, i.e. no `internal` in their `define`s
 
 #![crate_type = "lib"]
@@ -43,7 +43,7 @@
 };
 
 // The surrounding item should not accidentally become external
-// CHECK: define internal {{.*}} void @_ZN22external_no_mangle_fns1x
+// CHECK: define internal{{.*}} void @_ZN22external_no_mangle_fns1x
 #[inline(never)]
 fn x() {
     // CHECK: define void @g()
diff --git a/src/test/codegen/generic-debug.rs b/src/test/codegen/generic-debug.rs
new file mode 100644
index 0000000..9d5dbf1
--- /dev/null
+++ b/src/test/codegen/generic-debug.rs
@@ -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.
+
+// ignore-tidy-linelength
+// ignore-windows
+
+// compile-flags: -g -C no-prepopulate-passes
+
+// CHECK-LABEL: @main
+// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_structure_type,{{.*}}name: "Generic<i32>",{{.*}}
+// CHECK: {{.*}}DITemplateTypeParameter{{.*}}name: "Type",{{.*}}
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+
+pub struct Generic<Type>(Type);
+
+fn main () {
+    let generic = Generic(10);
+}
diff --git a/src/test/codegen/issue-45222.rs b/src/test/codegen/issue-45222.rs
index 30a0324..3544786 100644
--- a/src/test/codegen/issue-45222.rs
+++ b/src/test/codegen/issue-45222.rs
@@ -69,6 +69,6 @@
 // CHECK-LABEL: @check_foo3r
 #[no_mangle]
 pub fn check_foo3r() -> u64 {
-    // CHECK: ret i64 500005000000000
-    foo3r(100000)
+    // CHECK: ret i64 500050000000
+    foo3r(10000)
 }
diff --git a/src/test/codegen/issue-56267-2.rs b/src/test/codegen/issue-56267-2.rs
new file mode 100644
index 0000000..53b83f4
--- /dev/null
+++ b/src/test/codegen/issue-56267-2.rs
@@ -0,0 +1,18 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type="rlib"]
+
+#[allow(dead_code)]
+pub struct Foo<T> {
+    foo: u64,
+    bar: T,
+}
+
+// The load from bar.1 should have alignment 4. Not checking
+// other loads here, as the alignment will be platform-dependent.
+
+// CHECK: %{{.+}} = load i32, i32* %{{.+}}, align 4
+#[no_mangle]
+pub fn test(x: Foo<(i32, i32)>) -> (i32, i32) {
+    x.bar
+}
diff --git a/src/test/codegen/issue-56267.rs b/src/test/codegen/issue-56267.rs
new file mode 100644
index 0000000..2c33f55
--- /dev/null
+++ b/src/test/codegen/issue-56267.rs
@@ -0,0 +1,18 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type="rlib"]
+
+#[allow(dead_code)]
+pub struct Foo<T> {
+    foo: u64,
+    bar: T,
+}
+
+// The store writing to bar.1 should have alignment 4. Not checking
+// other stores here, as the alignment will be platform-dependent.
+
+// CHECK: store i32 [[TMP1:%.+]], i32* [[TMP2:%.+]], align 4
+#[no_mangle]
+pub fn test(x: (i32, i32)) -> Foo<(i32, i32)> {
+    Foo { foo: 0, bar: x }
+}
diff --git a/src/test/codegen/match-optimizes-away.rs b/src/test/codegen/match-optimizes-away.rs
index d7b7793..2136b17 100644
--- a/src/test/codegen/match-optimizes-away.rs
+++ b/src/test/codegen/match-optimizes-away.rs
@@ -14,6 +14,7 @@
 
 pub enum Three { A, B, C }
 
+#[repr(u16)]
 pub enum Four { A, B, C, D }
 
 #[no_mangle]
@@ -32,7 +33,7 @@
 pub fn four_valued(x: Four) -> Four {
     // CHECK-LABEL: @four_valued
     // CHECK-NEXT: {{^.*:$}}
-    // CHECK-NEXT: ret i8 %0
+    // CHECK-NEXT: ret i16 %0
     match x {
         Four::A => Four::A,
         Four::B => Four::B,
diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs
index 460e28f..fc53031 100644
--- a/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs
+++ b/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar, rustc_private)]
 #![feature(box_syntax)]
-#![feature(macro_at_most_once_rep)]
 
 #[macro_use] extern crate rustc;
 extern crate rustc_plugin;
diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
index 1057649..f697642 100644
--- a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
+++ b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 // Load rustc as a plugin to get macros
 #[macro_use]
diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs
index b0183a3..8647797 100644
--- a/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs
+++ b/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 extern crate syntax;
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/attr-invalid-exprs.rs b/src/test/compile-fail/proc-macro/attr-invalid-exprs.rs
similarity index 98%
rename from src/test/compile-fail-fulldeps/proc-macro/attr-invalid-exprs.rs
rename to src/test/compile-fail/proc-macro/attr-invalid-exprs.rs
index f52c251..798cd14 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/attr-invalid-exprs.rs
+++ b/src/test/compile-fail/proc-macro/attr-invalid-exprs.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:attr-stmt-expr.rs
-// ignore-stage1
 
 //! Attributes producing expressions in invalid locations
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/attr-stmt-expr.rs b/src/test/compile-fail/proc-macro/attr-stmt-expr.rs
similarity index 98%
rename from src/test/compile-fail-fulldeps/proc-macro/attr-stmt-expr.rs
rename to src/test/compile-fail/proc-macro/attr-stmt-expr.rs
index 1344156..6d1d5df 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/attr-stmt-expr.rs
+++ b/src/test/compile-fail/proc-macro/attr-stmt-expr.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:attr-stmt-expr.rs
-// ignore-stage1
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs b/src/test/compile-fail/proc-macro/attribute-with-error.rs
similarity index 98%
rename from src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs
rename to src/test/compile-fail/proc-macro/attribute-with-error.rs
index cf2522b..ed2e8ec 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs
+++ b/src/test/compile-fail/proc-macro/attribute-with-error.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:attribute-with-error.rs
-// ignore-stage1
 
 #![feature(custom_inner_attributes)]
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/attribute.rs b/src/test/compile-fail/proc-macro/attribute.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/attribute.rs
rename to src/test/compile-fail/proc-macro/attribute.rs
index 5d5e612..f89d74d 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/attribute.rs
+++ b/src/test/compile-fail/proc-macro/attribute.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
+// no-prefer-dynamic
+
 #![crate_type = "proc-macro"]
 
 extern crate proc_macro;
diff --git a/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs b/src/test/compile-fail/proc-macro/attributes-included.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs
rename to src/test/compile-fail/proc-macro/attributes-included.rs
index e941367..e129711 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs
+++ b/src/test/compile-fail/proc-macro/attributes-included.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:attributes-included.rs
-// ignore-stage1
 // compile-pass
 
 #![warn(unused)]
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/attr-stmt-expr.rs b/src/test/compile-fail/proc-macro/auxiliary/attr-stmt-expr.rs
similarity index 98%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/attr-stmt-expr.rs
rename to src/test/compile-fail/proc-macro/auxiliary/attr-stmt-expr.rs
index 22ddc91..4cfeec2 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/attr-stmt-expr.rs
+++ b/src/test/compile-fail/proc-macro/auxiliary/attr-stmt-expr.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/attribute-with-error.rs b/src/test/compile-fail/proc-macro/auxiliary/attribute-with-error.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/attribute-with-error.rs
rename to src/test/compile-fail/proc-macro/auxiliary/attribute-with-error.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/attributes-included.rs b/src/test/compile-fail/proc-macro/auxiliary/attributes-included.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/attributes-included.rs
rename to src/test/compile-fail/proc-macro/auxiliary/attributes-included.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/bang_proc_macro2.rs b/src/test/compile-fail/proc-macro/auxiliary/bang_proc_macro2.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/bang_proc_macro2.rs
rename to src/test/compile-fail/proc-macro/auxiliary/bang_proc_macro2.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-a-b.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs
rename to src/test/compile-fail/proc-macro/auxiliary/derive-a-b.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-a.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs
rename to src/test/compile-fail/proc-macro/auxiliary/derive-a.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-b.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs
rename to src/test/compile-fail/proc-macro/auxiliary/derive-b.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-bad.rs
similarity index 99%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs
rename to src/test/compile-fail/proc-macro/auxiliary/derive-bad.rs
index 841b39e..b2ded05 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs
+++ b/src/test/compile-fail/proc-macro/auxiliary/derive-bad.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// no-prefer-dynamic
 // force-host
+// no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-clona.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-clona.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-clona.rs
rename to src/test/compile-fail/proc-macro/auxiliary/derive-clona.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-foo.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-foo.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-foo.rs
rename to src/test/compile-fail/proc-macro/auxiliary/derive-foo.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-unstable-2.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs
rename to src/test/compile-fail/proc-macro/auxiliary/derive-unstable-2.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-unstable.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs
rename to src/test/compile-fail/proc-macro/auxiliary/derive-unstable.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue-41211.rs b/src/test/compile-fail/proc-macro/auxiliary/issue-41211.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue-41211.rs
rename to src/test/compile-fail/proc-macro/auxiliary/issue-41211.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_38586.rs b/src/test/compile-fail/proc-macro/auxiliary/issue_38586.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_38586.rs
rename to src/test/compile-fail/proc-macro/auxiliary/issue_38586.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_50493.rs b/src/test/compile-fail/proc-macro/auxiliary/issue_50493.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_50493.rs
rename to src/test/compile-fail/proc-macro/auxiliary/issue_50493.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/more-gates.rs b/src/test/compile-fail/proc-macro/auxiliary/more-gates.rs
similarity index 98%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/more-gates.rs
rename to src/test/compile-fail/proc-macro/auxiliary/more-gates.rs
index 67fe930..cc9420e 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/more-gates.rs
+++ b/src/test/compile-fail/proc-macro/auxiliary/more-gates.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/proc-macro-gates.rs b/src/test/compile-fail/proc-macro/auxiliary/proc-macro-gates.rs
similarity index 99%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/proc-macro-gates.rs
rename to src/test/compile-fail/proc-macro/auxiliary/proc-macro-gates.rs
index 0f8fd5b..7e4b7fe 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/proc-macro-gates.rs
+++ b/src/test/compile-fail/proc-macro/auxiliary/proc-macro-gates.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// no-prefer-dynamic
 // force-host
+// no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/test-macros.rs b/src/test/compile-fail/proc-macro/auxiliary/test-macros.rs
similarity index 98%
rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/test-macros.rs
rename to src/test/compile-fail/proc-macro/auxiliary/test-macros.rs
index 581c7cb..0e4343a 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/test-macros.rs
+++ b/src/test/compile-fail/proc-macro/auxiliary/test-macros.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/compile-fail-fulldeps/proc-macro/define-two.rs b/src/test/compile-fail/proc-macro/define-two.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/define-two.rs
rename to src/test/compile-fail/proc-macro/define-two.rs
index 8321c47..f8c287b 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/define-two.rs
+++ b/src/test/compile-fail/proc-macro/define-two.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs b/src/test/compile-fail/proc-macro/derive-bad.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs
rename to src/test/compile-fail/proc-macro/derive-bad.rs
index 93790f5..ac27e87 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs
+++ b/src/test/compile-fail/proc-macro/derive-bad.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:derive-bad.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate derive_bad;
diff --git a/src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs b/src/test/compile-fail/proc-macro/derive-still-gated.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs
rename to src/test/compile-fail/proc-macro/derive-still-gated.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs b/src/test/compile-fail/proc-macro/expand-to-unstable-2.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs
rename to src/test/compile-fail/proc-macro/expand-to-unstable-2.rs
index 6f254dc..e4fcbb1 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs
+++ b/src/test/compile-fail/proc-macro/expand-to-unstable-2.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:derive-unstable-2.rs
-// ignore-stage1
 
 #![allow(warnings)]
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs b/src/test/compile-fail/proc-macro/expand-to-unstable.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs
rename to src/test/compile-fail/proc-macro/expand-to-unstable.rs
index ca0f0e3..836e336 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs
+++ b/src/test/compile-fail/proc-macro/expand-to-unstable.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:derive-unstable.rs
-// ignore-stage1
 
 #![allow(warnings)]
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/export-macro.rs b/src/test/compile-fail/proc-macro/export-macro.rs
similarity index 94%
rename from src/test/compile-fail-fulldeps/proc-macro/export-macro.rs
rename to src/test/compile-fail/proc-macro/export-macro.rs
index 477039b..d8bb357 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/export-macro.rs
+++ b/src/test/compile-fail/proc-macro/export-macro.rs
@@ -10,6 +10,9 @@
 
 // error-pattern: cannot export macro_rules! macros from a `proc-macro` crate
 
+// force-host
+// no-prefer-dynamic
+
 #![crate_type = "proc-macro"]
 
 #[macro_export]
diff --git a/src/test/compile-fail-fulldeps/proc-macro/exports.rs b/src/test/compile-fail/proc-macro/exports.rs
similarity index 95%
rename from src/test/compile-fail-fulldeps/proc-macro/exports.rs
rename to src/test/compile-fail/proc-macro/exports.rs
index 41b94d0..07e5723 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/exports.rs
+++ b/src/test/compile-fail/proc-macro/exports.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
+// no-prefer-dynamic
+
 #![crate_type = "proc-macro"]
 #![allow(warnings)]
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/illegal-proc-macro-derive-use.rs b/src/test/compile-fail/proc-macro/illegal-proc-macro-derive-use.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/illegal-proc-macro-derive-use.rs
rename to src/test/compile-fail/proc-macro/illegal-proc-macro-derive-use.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/import.rs b/src/test/compile-fail/proc-macro/import.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/import.rs
rename to src/test/compile-fail/proc-macro/import.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs b/src/test/compile-fail/proc-macro/issue-37788.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs
rename to src/test/compile-fail/proc-macro/issue-37788.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs b/src/test/compile-fail/proc-macro/issue-38586.rs
similarity index 96%
rename from src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs
rename to src/test/compile-fail/proc-macro/issue-38586.rs
index 2d843d0..649220a 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs
+++ b/src/test/compile-fail/proc-macro/issue-38586.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:issue_38586.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate issue_38586;
diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs b/src/test/compile-fail/proc-macro/issue-41211.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs
rename to src/test/compile-fail/proc-macro/issue-41211.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs b/src/test/compile-fail/proc-macro/issue-50493.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs
rename to src/test/compile-fail/proc-macro/issue-50493.rs
index eaa64c6..635da57 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs
+++ b/src/test/compile-fail/proc-macro/issue-50493.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:issue_50493.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate issue_50493;
diff --git a/src/test/compile-fail-fulldeps/proc-macro/item-error.rs b/src/test/compile-fail/proc-macro/item-error.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/item-error.rs
rename to src/test/compile-fail/proc-macro/item-error.rs
index c0d4d71..4133e75 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/item-error.rs
+++ b/src/test/compile-fail/proc-macro/item-error.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:derive-b.rs
-// ignore-stage1
 
 #![allow(warnings)]
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs b/src/test/compile-fail/proc-macro/lints_in_proc_macros.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs
rename to src/test/compile-fail/proc-macro/lints_in_proc_macros.rs
index 60e533d..d49c612 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs
+++ b/src/test/compile-fail/proc-macro/lints_in_proc_macros.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:bang_proc_macro2.rs
-// ignore-stage1
 
 #![feature(proc_macro_hygiene)]
 #![allow(unused_macros)]
diff --git a/src/test/compile-fail-fulldeps/proc-macro/macros-in-extern.rs b/src/test/compile-fail/proc-macro/macros-in-extern.rs
similarity index 98%
rename from src/test/compile-fail-fulldeps/proc-macro/macros-in-extern.rs
rename to src/test/compile-fail/proc-macro/macros-in-extern.rs
index f280e74..43d7077 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/macros-in-extern.rs
+++ b/src/test/compile-fail/proc-macro/macros-in-extern.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:test-macros.rs
-// ignore-stage1
 // ignore-wasm32
 
 extern crate test_macros;
diff --git a/src/test/compile-fail-fulldeps/proc-macro/more-gates.rs b/src/test/compile-fail/proc-macro/more-gates.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/more-gates.rs
rename to src/test/compile-fail/proc-macro/more-gates.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/no-macro-use-attr.rs b/src/test/compile-fail/proc-macro/no-macro-use-attr.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/no-macro-use-attr.rs
rename to src/test/compile-fail/proc-macro/no-macro-use-attr.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs b/src/test/compile-fail/proc-macro/proc-macro-attributes.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs
rename to src/test/compile-fail/proc-macro/proc-macro-attributes.rs
index d0aed8b..6e52411 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs
+++ b/src/test/compile-fail/proc-macro/proc-macro-attributes.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:derive-b.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate derive_b;
diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs b/src/test/compile-fail/proc-macro/proc-macro-gates.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs
rename to src/test/compile-fail/proc-macro/proc-macro-gates.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates2.rs b/src/test/compile-fail/proc-macro/proc-macro-gates2.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates2.rs
rename to src/test/compile-fail/proc-macro/proc-macro-gates2.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/pub-at-crate-root.rs b/src/test/compile-fail/proc-macro/pub-at-crate-root.rs
similarity index 96%
rename from src/test/compile-fail-fulldeps/proc-macro/pub-at-crate-root.rs
rename to src/test/compile-fail/proc-macro/pub-at-crate-root.rs
index 238dde5..e995eb5 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/pub-at-crate-root.rs
+++ b/src/test/compile-fail/proc-macro/pub-at-crate-root.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
+// no-prefer-dynamic
+
 #![crate_type = "proc-macro"]
 
 extern crate proc_macro;
diff --git a/src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs b/src/test/compile-fail/proc-macro/shadow-builtin.rs
similarity index 94%
rename from src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs
rename to src/test/compile-fail/proc-macro/shadow-builtin.rs
index 8c5affb..a5fcfde 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs
+++ b/src/test/compile-fail/proc-macro/shadow-builtin.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
+// no-prefer-dynamic
+
 #![crate_type = "proc-macro"]
 
 extern crate proc_macro;
diff --git a/src/test/compile-fail-fulldeps/proc-macro/shadow.rs b/src/test/compile-fail/proc-macro/shadow.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/proc-macro/shadow.rs
rename to src/test/compile-fail/proc-macro/shadow.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-1.rs b/src/test/compile-fail/proc-macro/two-crate-types-1.rs
similarity index 93%
rename from src/test/compile-fail-fulldeps/proc-macro/two-crate-types-1.rs
rename to src/test/compile-fail/proc-macro/two-crate-types-1.rs
index db646fb..06bd3f9 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-1.rs
+++ b/src/test/compile-fail/proc-macro/two-crate-types-1.rs
@@ -10,5 +10,8 @@
 
 // error-pattern: cannot mix `proc-macro` crate type with others
 
+// force-host
+// no-prefer-dynamic
+
 #![crate_type = "proc-macro"]
 #![crate_type = "rlib"]
diff --git a/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-2.rs b/src/test/compile-fail/proc-macro/two-crate-types-2.rs
similarity index 97%
rename from src/test/compile-fail-fulldeps/proc-macro/two-crate-types-2.rs
rename to src/test/compile-fail/proc-macro/two-crate-types-2.rs
index 97b0f84..dd5e5ac 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-2.rs
+++ b/src/test/compile-fail/proc-macro/two-crate-types-2.rs
@@ -10,3 +10,4 @@
 
 // error-pattern: cannot mix `proc-macro` crate type with others
 // compile-flags: --crate-type rlib --crate-type proc-macro
+// force-host
diff --git a/src/test/debuginfo/associated-types.rs b/src/test/debuginfo/associated-types.rs
index 229f946..c9c2395 100644
--- a/src/test/debuginfo/associated-types.rs
+++ b/src/test/debuginfo/associated-types.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// min-lldb-version: 310
+// Some versions of the non-rust-enabled LLDB print the wrong generic
+// parameter type names in this test.
+// rust-lldb
 
 // compile-flags:-g
 
diff --git a/src/test/debuginfo/generic-method-on-generic-struct.rs b/src/test/debuginfo/generic-method-on-generic-struct.rs
index 97bb9aa..df1f1e3 100644
--- a/src/test/debuginfo/generic-method-on-generic-struct.rs
+++ b/src/test/debuginfo/generic-method-on-generic-struct.rs
@@ -11,7 +11,10 @@
 // ignore-tidy-linelength
 
 // compile-flags:-g
-// min-lldb-version: 310
+
+// Some versions of the non-rust-enabled LLDB print the wrong generic
+// parameter type names in this test.
+// rust-lldb
 
 // === GDB TESTS ===================================================================================
 
diff --git a/src/test/debuginfo/generic-struct.rs b/src/test/debuginfo/generic-struct.rs
index 4e06a15..ebaac96 100644
--- a/src/test/debuginfo/generic-struct.rs
+++ b/src/test/debuginfo/generic-struct.rs
@@ -9,7 +9,10 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// min-lldb-version: 310
+
+// Some versions of the non-rust-enabled LLDB print the wrong generic
+// parameter type names in this test.
+// rust-lldb
 
 // compile-flags:-g
 
diff --git a/src/test/debuginfo/generic-tuple-style-enum.rs b/src/test/debuginfo/generic-tuple-style-enum.rs
index ebd43da..8bda0e4 100644
--- a/src/test/debuginfo/generic-tuple-style-enum.rs
+++ b/src/test/debuginfo/generic-tuple-style-enum.rs
@@ -41,7 +41,7 @@
 // lldb-command:run
 
 // lldb-command:print case1
-// lldbr-check:(generic_tuple_style_enum::Regular<u16, u32, u64>::Case1) case1 = { = 0 = 31868 = 31868 = 31868 = 31868 }
+// lldbr-check:(generic_tuple_style_enum::Regular<u16, u32, u64>::Case1) case1 = { __0 = 0 __1 = 31868 __2 = 31868 __3 = 31868 __4 = 31868 }
 
 // lldb-command:print case2
 // lldbr-check:(generic_tuple_style_enum::Regular<i16, i32, i64>::Case2) case2 = Regular<i16, i32, i64>::Case2 { Case1: 0, Case2: 286331153, Case3: 286331153 }
@@ -50,7 +50,7 @@
 // lldbr-check:(generic_tuple_style_enum::Regular<i16, i32, i64>::Case3) case3 = Regular<i16, i32, i64>::Case3 { Case1: 0, Case2: 6438275382588823897 }
 
 // lldb-command:print univariant
-// lldbr-check:(generic_tuple_style_enum::Univariant<i64>) univariant = { TheOnlyCase = { = -1 } }
+// lldbr-check:(generic_tuple_style_enum::Univariant<i64>) univariant = Univariant<i64> { TheOnlyCase: Univariant<i64>::TheOnlyCase(-1) }
 
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
diff --git a/src/test/debuginfo/method-on-generic-struct.rs b/src/test/debuginfo/method-on-generic-struct.rs
index 5723896..f4f7bdc 100644
--- a/src/test/debuginfo/method-on-generic-struct.rs
+++ b/src/test/debuginfo/method-on-generic-struct.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// min-lldb-version: 310
+// Some versions of the non-rust-enabled LLDB print the wrong generic
+// parameter type names in this test.
+// rust-lldb
 
 // compile-flags:-g
 
diff --git a/src/test/incremental-fulldeps/auxiliary/incremental_proc_macro_aux.rs b/src/test/incremental/auxiliary/incremental_proc_macro_aux.rs
similarity index 98%
rename from src/test/incremental-fulldeps/auxiliary/incremental_proc_macro_aux.rs
rename to src/test/incremental/auxiliary/incremental_proc_macro_aux.rs
index e9f9ba8..34d2009 100644
--- a/src/test/incremental-fulldeps/auxiliary/incremental_proc_macro_aux.rs
+++ b/src/test/incremental/auxiliary/incremental_proc_macro_aux.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/incremental-fulldeps/auxiliary/issue_49482_macro_def.rs b/src/test/incremental/auxiliary/issue_49482_macro_def.rs
similarity index 98%
rename from src/test/incremental-fulldeps/auxiliary/issue_49482_macro_def.rs
rename to src/test/incremental/auxiliary/issue_49482_macro_def.rs
index 763c9eb..fa6bff4 100644
--- a/src/test/incremental-fulldeps/auxiliary/issue_49482_macro_def.rs
+++ b/src/test/incremental/auxiliary/issue_49482_macro_def.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type="proc-macro"]
diff --git a/src/test/incremental-fulldeps/auxiliary/issue_49482_reexport.rs b/src/test/incremental/auxiliary/issue_49482_reexport.rs
similarity index 100%
rename from src/test/incremental-fulldeps/auxiliary/issue_49482_reexport.rs
rename to src/test/incremental/auxiliary/issue_49482_reexport.rs
diff --git a/src/test/incremental-fulldeps/auxiliary/issue_54059.rs b/src/test/incremental/auxiliary/issue_54059.rs
similarity index 98%
rename from src/test/incremental-fulldeps/auxiliary/issue_54059.rs
rename to src/test/incremental/auxiliary/issue_54059.rs
index ec0d044..635501f 100644
--- a/src/test/incremental-fulldeps/auxiliary/issue_54059.rs
+++ b/src/test/incremental/auxiliary/issue_54059.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 // check that having extern "C" functions in a proc macro doesn't crash.
diff --git a/src/test/incremental-fulldeps/incremental_proc_macro.rs b/src/test/incremental/incremental_proc_macro.rs
similarity index 97%
rename from src/test/incremental-fulldeps/incremental_proc_macro.rs
rename to src/test/incremental/incremental_proc_macro.rs
index 103ee30..495f4ff 100644
--- a/src/test/incremental-fulldeps/incremental_proc_macro.rs
+++ b/src/test/incremental/incremental_proc_macro.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:incremental_proc_macro_aux.rs
-// ignore-stage1
 // revisions: cfail1 cfail2
 // compile-pass
 
diff --git a/src/test/incremental-fulldeps/issue-49482.rs b/src/test/incremental/issue-49482.rs
similarity index 97%
rename from src/test/incremental-fulldeps/issue-49482.rs
rename to src/test/incremental/issue-49482.rs
index 3261b5a..65e86e8 100644
--- a/src/test/incremental-fulldeps/issue-49482.rs
+++ b/src/test/incremental/issue-49482.rs
@@ -10,7 +10,6 @@
 
 // aux-build:issue_49482_macro_def.rs
 // aux-build:issue_49482_reexport.rs
-// ignore-stage1
 // revisions: rpass1
 
 extern crate issue_49482_reexport;
diff --git a/src/test/incremental-fulldeps/issue-54059.rs b/src/test/incremental/issue-54059.rs
similarity index 97%
rename from src/test/incremental-fulldeps/issue-54059.rs
rename to src/test/incremental/issue-54059.rs
index dee1e0a..2f4ea72 100644
--- a/src/test/incremental-fulldeps/issue-54059.rs
+++ b/src/test/incremental/issue-54059.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:issue_54059.rs
-// ignore-stage1
 // ignore-wasm32-bare no libc for ffi testing
 // ignore-windows - dealing with weird symbols issues on dylibs isn't worth it
 // revisions: rpass1
diff --git a/src/test/pretty/attr-derive.rs b/src/test/pretty/attr-derive.rs
index a1c581a..f38bf6e 100644
--- a/src/test/pretty/attr-derive.rs
+++ b/src/test/pretty/attr-derive.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:derive-foo.rs
-// ignore-stage1
 // pp-exact
 // Testing that both the inner item and next outer item are
 // preserved, and that the first outer item parsed in main is not
diff --git a/src/test/pretty/auxiliary/derive-foo.rs b/src/test/pretty/auxiliary/derive-foo.rs
index bd81d3e..3552b20 100644
--- a/src/test/pretty/auxiliary/derive-foo.rs
+++ b/src/test/pretty/auxiliary/derive-foo.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile
new file mode 100644
index 0000000..f124ca2
--- /dev/null
+++ b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile
@@ -0,0 +1,6 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) checkrust.rs
+	$(CC) test.c $(call STATICLIB,checkrust) $(call OUT_EXE,test) $(EXTRACFLAGS)
+	$(call RUN,test)
diff --git a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs
new file mode 100644
index 0000000..90ad601
--- /dev/null
+++ b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs
@@ -0,0 +1,80 @@
+// 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 = "staticlib"]
+#![feature(c_variadic)]
+#![feature(libc)]
+
+extern crate libc;
+
+use libc::{c_char, c_double, c_int, c_long, c_longlong};
+use std::ffi::VaList;
+use std::ffi::{CString, CStr};
+
+macro_rules! continue_if {
+    ($cond:expr) => {
+        if !($cond) {
+            return 0xff;
+        }
+    }
+}
+
+unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool {
+    let cstr0 = CStr::from_ptr(ptr);
+    let cstr1 = CString::new(val).unwrap();
+    &*cstr1 == cstr0
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn check_list_0(mut ap: VaList) -> usize {
+    continue_if!(ap.arg::<c_longlong>() == 1);
+    continue_if!(ap.arg::<c_int>() == 2);
+    continue_if!(ap.arg::<c_longlong>() == 3);
+    0
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize {
+    continue_if!(ap.arg::<c_int>() == -1);
+    continue_if!(ap.arg::<c_char>() == 'A' as c_char);
+    continue_if!(ap.arg::<c_char>() == '4' as c_char);
+    continue_if!(ap.arg::<c_char>() == ';' as c_char);
+    continue_if!(ap.arg::<c_int>() == 0x32);
+    continue_if!(ap.arg::<c_int>() == 0x10000001);
+    continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Valid!"));
+    0
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize {
+    continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor());
+    continue_if!(ap.arg::<c_long>() == 12);
+    continue_if!(ap.arg::<c_char>() == 'a' as c_char);
+    continue_if!(ap.arg::<c_double>().floor() == 6.18f64.floor());
+    continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello"));
+    continue_if!(ap.arg::<c_int>() == 42);
+    continue_if!(compare_c_str(ap.arg::<*const c_char>(), "World"));
+    0
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize {
+    continue_if!(ap.arg::<c_double>().floor() == 6.28f64.floor());
+    continue_if!(ap.arg::<c_int>() == 16);
+    continue_if!(ap.arg::<c_char>() == 'A' as c_char);
+    continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!"));
+    ap.copy(|mut ap| {
+        if compare_c_str(ap.arg::<*const c_char>(), "Correct") {
+            0
+        } else {
+            0xff
+        }
+    })
+}
diff --git a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c
new file mode 100644
index 0000000..e9edf59
--- /dev/null
+++ b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c
@@ -0,0 +1,40 @@
+// 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.
+
+#include <stdarg.h>
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+extern size_t check_list_0(va_list ap);
+extern size_t check_list_1(va_list ap);
+extern size_t check_list_2(va_list ap);
+extern size_t check_list_copy_0(va_list ap);
+
+int test_rust(size_t (*fn)(va_list), ...) {
+    size_t ret = 0;
+    va_list ap;
+    va_start(ap, fn);
+    ret = fn(ap);
+    va_end(ap);
+    return ret;
+}
+
+int main(int argc, char* argv[]) {
+    assert(test_rust(check_list_0, 0x01LL, 0x02, 0x03LL) == 0);
+
+    assert(test_rust(check_list_1, -1, 'A', '4', ';', 0x32, 0x10000001, "Valid!") == 0);
+
+    assert(test_rust(check_list_2, 3.14, 12l, 'a', 6.28, "Hello", 42, "World") == 0);
+
+    assert(test_rust(check_list_copy_0, 6.28, 16, 'A', "Skip Me!", "Correct") == 0);
+    return 0;
+}
diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs
index 4dfecb3..c342e1c 100644
--- a/src/test/run-make-fulldeps/issue-19371/foo.rs
+++ b/src/test/run-make-fulldeps/issue-19371/foo.rs
@@ -72,7 +72,8 @@
         driver::spawn_thread_pool(opts, |opts| {
             let (sess, cstore, codegen_backend) = basic_sess(opts);
             let control = CompileController::basic();
-            let input = Input::Str { name: FileName::Anon, input: code };
+            let name = FileName::anon_source_code(&code);
+            let input = Input::Str { name, input: code };
             let _ = compile_input(
                 codegen_backend,
                 &sess,
diff --git a/src/test/run-make-fulldeps/issue-38237/Makefile b/src/test/run-make-fulldeps/issue-38237/Makefile
index 855d958..0a68140 100644
--- a/src/test/run-make-fulldeps/issue-38237/Makefile
+++ b/src/test/run-make-fulldeps/issue-38237/Makefile
@@ -1,11 +1,5 @@
 -include ../tools.mk
 
-ifeq ($(findstring stage1,$(RUST_BUILD_STAGE)),stage1)
-# ignore stage1
-all:
-
-else
 all:
 	$(RUSTC) foo.rs; $(RUSTC) bar.rs
 	$(RUSTDOC) baz.rs -L $(TMPDIR) -o $(TMPDIR)
-endif
diff --git a/src/test/run-make-fulldeps/rustc-macro-dep-files/Makefile b/src/test/run-make-fulldeps/rustc-macro-dep-files/Makefile
deleted file mode 100644
index d2c8e7f..0000000
--- a/src/test/run-make-fulldeps/rustc-macro-dep-files/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
--include ../tools.mk
-
-ifeq ($(findstring stage1,$(RUST_BUILD_STAGE)),stage1)
-# ignore stage1
-all:
-
-else
-all:
-	$(RUSTC) foo.rs
-	$(RUSTC) bar.rs --emit dep-info
-	$(CGREP) -v "proc-macro source" < $(TMPDIR)/bar.d
-endif
diff --git a/src/test/run-make-fulldeps/rustdoc-io-error/Makefile b/src/test/run-make-fulldeps/rustdoc-io-error/Makefile
new file mode 100644
index 0000000..2055c9c
--- /dev/null
+++ b/src/test/run-make-fulldeps/rustdoc-io-error/Makefile
@@ -0,0 +1,25 @@
+-include ../tools.mk
+
+# This test verifies that rustdoc doesn't ICE when it encounters an IO error
+# while generating files. Ideally this would be a rustdoc-ui test, so we could
+# verify the error message as well.
+
+OUTPUT_DIR := "$(TMPDIR)/rustdoc-io-error"
+
+# Ignore Windows: the test uses `chmod`.
+ifndef IS_WINDOWS
+
+# This test operates by creating a temporary directory and modifying its
+# permissions so that it is not writable. We have to take special care to set
+# the permissions back to normal so that it's able to be deleted later.
+all:
+	mkdir -p $(OUTPUT_DIR)
+	chmod u-w $(OUTPUT_DIR)
+	-$(shell $(RUSTDOC) -o $(OUTPUT_DIR) foo.rs)
+	chmod u+w $(OUTPUT_DIR)
+	exit $($(.SHELLSTATUS) -eq 1)
+
+else
+all:
+
+endif
diff --git a/src/test/run-make-fulldeps/rustdoc-io-error/foo.rs b/src/test/run-make-fulldeps/rustdoc-io-error/foo.rs
new file mode 100644
index 0000000..4a83567
--- /dev/null
+++ b/src/test/run-make-fulldeps/rustdoc-io-error/foo.rs
@@ -0,0 +1 @@
+pub struct Foo;
diff --git a/src/test/run-make/llvm-outputs/Makefile b/src/test/run-make/llvm-outputs/Makefile
new file mode 100644
index 0000000..d7f6757
--- /dev/null
+++ b/src/test/run-make/llvm-outputs/Makefile
@@ -0,0 +1,5 @@
+-include ../../run-make-fulldeps/tools.mk
+
+all:
+	echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_ir/ --emit=llvm-ir
+	echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_bc/ --emit=llvm-bc
diff --git a/src/test/run-make/rustc-macro-dep-files/Makefile b/src/test/run-make/rustc-macro-dep-files/Makefile
new file mode 100644
index 0000000..0420a38
--- /dev/null
+++ b/src/test/run-make/rustc-macro-dep-files/Makefile
@@ -0,0 +1,8 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC`
+# instead of hardcoding them everywhere they're needed.
+all:
+	$(BARE_RUSTC) foo.rs --out-dir $(TMPDIR)
+	$(RUSTC) bar.rs --target $(TARGET) --emit dep-info
+	$(CGREP) -v "proc-macro source" < $(TMPDIR)/bar.d
diff --git a/src/test/run-make-fulldeps/rustc-macro-dep-files/bar.rs b/src/test/run-make/rustc-macro-dep-files/bar.rs
similarity index 93%
rename from src/test/run-make-fulldeps/rustc-macro-dep-files/bar.rs
rename to src/test/run-make/rustc-macro-dep-files/bar.rs
index 03330c3..b2d7f3f 100644
--- a/src/test/run-make-fulldeps/rustc-macro-dep-files/bar.rs
+++ b/src/test/run-make/rustc-macro-dep-files/bar.rs
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![no_std]
+#![crate_type = "lib"]
+
 #[macro_use]
 extern crate foo;
 
 #[derive(A)]
 struct A;
-
-fn main() {
-    let _b = B;
-}
diff --git a/src/test/run-make-fulldeps/rustc-macro-dep-files/foo.rs b/src/test/run-make/rustc-macro-dep-files/foo.rs
similarity index 100%
rename from src/test/run-make-fulldeps/rustc-macro-dep-files/foo.rs
rename to src/test/run-make/rustc-macro-dep-files/foo.rs
diff --git a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs
index 8f54f2e..c9d0329 100644
--- a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs
+++ b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs
@@ -25,7 +25,6 @@
 use syntax::parse::parser::Parser;
 use syntax::parse::token;
 use syntax::ptr::P;
-use syntax::str::char_at;
 use syntax::parse::attr::*;
 use syntax::print::pprust;
 use std::fmt;
@@ -33,7 +32,7 @@
 // Copied out of syntax::util::parser_testing
 
 pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> {
-    new_parser_from_source_str(ps, FileName::Custom("bogofile".to_owned()), source_str)
+    new_parser_from_source_str(ps, FileName::Custom(source_str.clone()), source_str)
 }
 
 fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> PResult<'a, T> where
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs
rename to src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs
index e0acf34..f4d3f2c 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![feature(box_syntax, plugin, plugin_registrar, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 #![crate_type = "dylib"]
 
 #[macro_use]
diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs
index 00c419a..9f6927d 100644
--- a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar, rustc_private)]
 #![feature(box_syntax)]
-#![feature(macro_at_most_once_rep)]
 
 #[macro_use] extern crate rustc;
 extern crate rustc_plugin;
diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs
index 6283d05..e8cbf5a 100644
--- a/src/test/run-pass-fulldeps/compiler-calls.rs
+++ b/src/test/run-pass-fulldeps/compiler-calls.rs
@@ -11,6 +11,7 @@
 // Test that the CompilerCalls interface to the compiler works.
 
 // ignore-cross-compile
+// ignore-stage1
 
 #![feature(rustc_private)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-40001.rs b/src/test/run-pass-fulldeps/issue-40001.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/issue-40001.rs
rename to src/test/run-pass-fulldeps/issue-40001.rs
diff --git a/src/test/run-pass-fulldeps/newtype_index.rs b/src/test/run-pass-fulldeps/newtype_index.rs
index 3cd622a..0fd7ccd 100644
--- a/src/test/run-pass-fulldeps/newtype_index.rs
+++ b/src/test/run-pass-fulldeps/newtype_index.rs
@@ -1,4 +1,4 @@
-#![feature(rustc_attrs, rustc_private, step_trait)]
+#![feature(rustc_attrs, rustc_private, step_trait, min_const_unsafe_fn)]
 
 #[macro_use] extern crate rustc_data_structures;
 extern crate rustc_serialize;
diff --git a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs
index e944ef2..854063a 100644
--- a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs
@@ -44,9 +44,11 @@
 
 
 fn parse_expr(ps: &ParseSess, src: &str) -> P<Expr> {
+    let src_as_string = src.to_string();
+
     let mut p = parse::new_parser_from_source_str(ps,
-                                                  FileName::Custom("expr".to_owned()),
-                                                  src.to_owned());
+                                                  FileName::Custom(src_as_string.clone()),
+                                                  src_as_string);
     p.parse_expr().unwrap()
 }
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/test-macros.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/test-macros.rs
deleted file mode 100644
index 581c7cb..0000000
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/test-macros.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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.
-
-// no-prefer-dynamic
-
-#![crate_type = "proc-macro"]
-
-extern crate proc_macro;
-
-use proc_macro::TokenStream;
-
-#[proc_macro_attribute]
-pub fn nop_attr(_attr: TokenStream, input: TokenStream) -> TokenStream {
-    assert!(_attr.to_string().is_empty());
-    input
-}
-
-#[proc_macro_attribute]
-pub fn no_output(_attr: TokenStream, _input: TokenStream) -> TokenStream {
-    assert!(_attr.to_string().is_empty());
-    assert!(!_input.to_string().is_empty());
-    "".parse().unwrap()
-}
-
-#[proc_macro]
-pub fn emit_input(input: TokenStream) -> TokenStream {
-    input
-}
diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs b/src/test/run-pass/auxiliary/cond_plugin.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs
rename to src/test/run-pass/auxiliary/cond_plugin.rs
index e7545f9..940b1ea 100644
--- a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs
+++ b/src/test/run-pass/auxiliary/cond_plugin.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs b/src/test/run-pass/auxiliary/hello_macro.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/auxiliary/hello_macro.rs
rename to src/test/run-pass/auxiliary/hello_macro.rs
index caf56da..f3a0f2c 100644
--- a/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs
+++ b/src/test/run-pass/auxiliary/hello_macro.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs b/src/test/run-pass/auxiliary/proc_macro_def.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs
rename to src/test/run-pass/auxiliary/proc_macro_def.rs
index 847db00..d111db8 100644
--- a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs
+++ b/src/test/run-pass/auxiliary/proc_macro_def.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass/binding/empty-types-in-patterns.rs b/src/test/run-pass/binding/empty-types-in-patterns.rs
index c230442..7fb7eec 100644
--- a/src/test/run-pass/binding/empty-types-in-patterns.rs
+++ b/src/test/run-pass/binding/empty-types-in-patterns.rs
@@ -60,6 +60,7 @@
     let x: Result<u32, &!> = Ok(123);
     match x {
         Ok(y) => y,
+        Err(_) => unimplemented!(),
     };
 
     bar(&[]);
diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs
index e6dd421..7373828 100644
--- a/src/test/run-pass/impl-trait/example-calendar.rs
+++ b/src/test/run-pass/impl-trait/example-calendar.rs
@@ -753,10 +753,7 @@
     type Item = Vec<It::Item>;
 
     fn next(&mut self) -> Option<Vec<It::Item>> {
-        let first = match self.it.next() {
-            Some(e) => e,
-            None => return None
-        };
+        let first = self.it.next()?;
 
         let mut result = Vec::with_capacity(self.n);
         result.push(first);
diff --git a/src/test/run-pass/issue-55380.rs b/src/test/run-pass/issue-55380.rs
new file mode 100644
index 0000000..29392fb
--- /dev/null
+++ b/src/test/run-pass/issue-55380.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.
+
+// run-pass
+
+#![feature(specialization)]
+
+pub trait Foo {
+    fn abc() -> u32;
+    fn def() -> u32;
+}
+
+pub trait Marker {}
+
+impl Marker for () {}
+
+impl<T> Foo for T {
+    default fn abc() -> u32 { 16 }
+    default fn def() -> u32 { 42 }
+}
+
+impl<T: Marker> Foo for T {
+    fn def() -> u32 {
+        Self::abc()
+    }
+}
+
+fn main() {
+   assert_eq!(<()>::def(), 16);
+   assert_eq!(<i32>::def(), 42);
+}
diff --git a/src/test/run-pass/issue-56237.rs b/src/test/run-pass/issue-56237.rs
new file mode 100644
index 0000000..87e10e8
--- /dev/null
+++ b/src/test/run-pass/issue-56237.rs
@@ -0,0 +1,11 @@
+use std::ops::Deref;
+
+fn foo<P>(_value: <P as Deref>::Target)
+where
+    P: Deref,
+    <P as Deref>::Target: Sized,
+{}
+
+fn main() {
+    foo::<Box<u32>>(2);
+}
diff --git a/src/test/run-pass-fulldeps/macro-quote-cond.rs b/src/test/run-pass/macro-quote-cond.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/macro-quote-cond.rs
rename to src/test/run-pass/macro-quote-cond.rs
index d438add..d8e3633 100644
--- a/src/test/run-pass-fulldeps/macro-quote-cond.rs
+++ b/src/test/run-pass/macro-quote-cond.rs
@@ -10,7 +10,6 @@
 
 #![allow(unused_parens)]
 // aux-build:cond_plugin.rs
-// ignore-stage1
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/run-pass-fulldeps/macro-quote-test.rs b/src/test/run-pass/macro-quote-test.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/macro-quote-test.rs
rename to src/test/run-pass/macro-quote-test.rs
index f967ef5..473f92f 100644
--- a/src/test/run-pass-fulldeps/macro-quote-test.rs
+++ b/src/test/run-pass/macro-quote-test.rs
@@ -11,7 +11,6 @@
 // Test that a macro can emit delimiters with nothing inside - `()`, `{}`
 
 // aux-build:hello_macro.rs
-// ignore-stage1
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/run-pass/macros/macro-at-most-once-rep.rs b/src/test/run-pass/macros/macro-at-most-once-rep.rs
index c712942..563fd01 100644
--- a/src/test/run-pass/macros/macro-at-most-once-rep.rs
+++ b/src/test/run-pass/macros/macro-at-most-once-rep.rs
@@ -22,8 +22,6 @@
 
 // edition:2018
 
-#![feature(macro_at_most_once_rep)]
-
 macro_rules! foo {
     ($($a:ident)? ; $num:expr) => { {
         let mut x = 0;
diff --git a/src/test/run-pass-fulldeps/proc-macro/add-impl.rs b/src/test/run-pass/proc-macro/add-impl.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/add-impl.rs
rename to src/test/run-pass/proc-macro/add-impl.rs
index 5175fe1..7ea7cea 100644
--- a/src/test/run-pass-fulldeps/proc-macro/add-impl.rs
+++ b/src/test/run-pass/proc-macro/add-impl.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:add-impl.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate add_impl;
diff --git a/src/test/run-pass-fulldeps/proc-macro/append-impl.rs b/src/test/run-pass/proc-macro/append-impl.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/append-impl.rs
rename to src/test/run-pass/proc-macro/append-impl.rs
index 37aef7e..591f333 100644
--- a/src/test/run-pass-fulldeps/proc-macro/append-impl.rs
+++ b/src/test/run-pass/proc-macro/append-impl.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:append-impl.rs
-// ignore-stage1
 
 #![allow(warnings)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-args.rs b/src/test/run-pass/proc-macro/attr-args.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/attr-args.rs
rename to src/test/run-pass/proc-macro/attr-args.rs
index effb3ad..b2ee5c2 100644
--- a/src/test/run-pass-fulldeps/proc-macro/attr-args.rs
+++ b/src/test/run-pass/proc-macro/attr-args.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:attr-args.rs
-// ignore-stage1
 
 #![allow(warnings)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs b/src/test/run-pass/proc-macro/attr-cfg.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs
rename to src/test/run-pass/proc-macro/attr-cfg.rs
index 1a9d9b9..58ffd0c 100644
--- a/src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs
+++ b/src/test/run-pass/proc-macro/attr-cfg.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:attr-cfg.rs
-// ignore-stage1
 // revisions: foo bar
 
 extern crate attr_cfg;
diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-on-trait.rs b/src/test/run-pass/proc-macro/attr-on-trait.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/attr-on-trait.rs
rename to src/test/run-pass/proc-macro/attr-on-trait.rs
index 698a0ec..383c193 100644
--- a/src/test/run-pass-fulldeps/proc-macro/attr-on-trait.rs
+++ b/src/test/run-pass/proc-macro/attr-on-trait.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:attr-on-trait.rs
-// ignore-stage1
 
 extern crate attr_on_trait;
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs b/src/test/run-pass/proc-macro/attr-stmt-expr.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs
rename to src/test/run-pass/proc-macro/attr-stmt-expr.rs
index 8a3452f..43a5695 100644
--- a/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs
+++ b/src/test/run-pass/proc-macro/attr-stmt-expr.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:attr-stmt-expr.rs
-// ignore-stage1
 
 #![feature(stmt_expr_attributes, proc_macro_hygiene)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs b/src/test/run-pass/proc-macro/auxiliary/add-impl.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs
rename to src/test/run-pass/proc-macro/auxiliary/add-impl.rs
index 3959ecc..806d70e 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/add-impl.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs b/src/test/run-pass/proc-macro/auxiliary/append-impl.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs
rename to src/test/run-pass/proc-macro/auxiliary/append-impl.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-args.rs b/src/test/run-pass/proc-macro/auxiliary/attr-args.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-args.rs
rename to src/test/run-pass/proc-macro/auxiliary/attr-args.rs
index 655bfa3..1f45a79 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-args.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/attr-args.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-cfg.rs b/src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-cfg.rs
rename to src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs
index f9037aa..553d2ca 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-cfg.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-on-trait.rs b/src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-on-trait.rs
rename to src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs
index 5e5c775b..f5431dd 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-on-trait.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-stmt-expr.rs b/src/test/run-pass/proc-macro/auxiliary/attr-stmt-expr.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-stmt-expr.rs
rename to src/test/run-pass/proc-macro/auxiliary/attr-stmt-expr.rs
index 4d5e22b..4704bd1 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-stmt-expr.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/attr-stmt-expr.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/bang-macro.rs b/src/test/run-pass/proc-macro/auxiliary/bang-macro.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/bang-macro.rs
rename to src/test/run-pass/proc-macro/auxiliary/bang-macro.rs
index 8b7c6cd..4530187 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/bang-macro.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/bang-macro.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/call-site.rs b/src/test/run-pass/proc-macro/auxiliary/call-site.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/call-site.rs
rename to src/test/run-pass/proc-macro/auxiliary/call-site.rs
index 65eb8f4..ed878a2 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/call-site.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/call-site.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/count_compound_ops.rs b/src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/count_compound_ops.rs
rename to src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs
index 77d0d93..b0d71f2 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/count_compound_ops.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![feature(proc_macro_hygiene, proc_macro_quote)]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/custom-attr-only-one-derive.rs b/src/test/run-pass/proc-macro/auxiliary/custom-attr-only-one-derive.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/custom-attr-only-one-derive.rs
rename to src/test/run-pass/proc-macro/auxiliary/custom-attr-only-one-derive.rs
index 4609f57..250d950 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/custom-attr-only-one-derive.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/custom-attr-only-one-derive.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs b/src/test/run-pass/proc-macro/auxiliary/derive-a.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs
rename to src/test/run-pass/proc-macro/auxiliary/derive-a.rs
index b7374a0..55c2b3c 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/derive-a.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs b/src/test/run-pass/proc-macro/auxiliary/derive-atob.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs
rename to src/test/run-pass/proc-macro/auxiliary/derive-atob.rs
index 67d828d..406f169 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/derive-atob.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-attr-cfg.rs b/src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-attr-cfg.rs
rename to src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs
index 2b41357..20ba0de 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-attr-cfg.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs b/src/test/run-pass/proc-macro/auxiliary/derive-b.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs
rename to src/test/run-pass/proc-macro/auxiliary/derive-b.rs
index e1aabad..d69e69d 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/derive-b.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs b/src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs
rename to src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs
index 550ffe9..91a82ba 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-nothing.rs b/src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-nothing.rs
rename to src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs
index cfe428b..635d336 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-nothing.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs b/src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs
similarity index 95%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs
rename to src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs
index cf96f52..f62e0cd 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
-// compile-flags:--crate-type proc-macro
+
+#![crate_type = "proc-macro"]
 
 extern crate proc_macro;
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-two-attrs.rs b/src/test/run-pass/proc-macro/auxiliary/derive-two-attrs.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-two-attrs.rs
rename to src/test/run-pass/proc-macro/auxiliary/derive-two-attrs.rs
index d02edb5..eafd457 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-two-attrs.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/derive-two-attrs.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-union.rs b/src/test/run-pass/proc-macro/auxiliary/derive-union.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-union.rs
rename to src/test/run-pass/proc-macro/auxiliary/derive-union.rs
index 41bb88a..e6d3d91 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-union.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/derive-union.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs b/src/test/run-pass/proc-macro/auxiliary/double.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs
rename to src/test/run-pass/proc-macro/auxiliary/double.rs
index a6c9817..f376795 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/double.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs b/src/test/run-pass/proc-macro/auxiliary/empty-crate.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs
rename to src/test/run-pass/proc-macro/auxiliary/empty-crate.rs
index b45d4bf..943acd9 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/empty-crate.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs b/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs
rename to src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs
index e6831b6..d7f8ec4 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/external-crate-var.rs b/src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/external-crate-var.rs
rename to src/test/run-pass/proc-macro/auxiliary/external-crate-var.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs b/src/test/run-pass/proc-macro/auxiliary/gen-lifetime-token.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs
rename to src/test/run-pass/proc-macro/auxiliary/gen-lifetime-token.rs
index 978de27..9f30083 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/gen-lifetime-token.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example.rs b/src/test/run-pass/proc-macro/auxiliary/hygiene_example.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example.rs
rename to src/test/run-pass/proc-macro/auxiliary/hygiene_example.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example_codegen.rs b/src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example_codegen.rs
rename to src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs
index 551ac38..af3b601 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example_codegen.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![feature(proc_macro_quote, proc_macro_hygiene)]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-39889.rs b/src/test/run-pass/proc-macro/auxiliary/issue-39889.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-39889.rs
rename to src/test/run-pass/proc-macro/auxiliary/issue-39889.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-42708.rs b/src/test/run-pass/proc-macro/auxiliary/issue-42708.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-42708.rs
rename to src/test/run-pass/proc-macro/auxiliary/issue-42708.rs
index 906cace..e74b9dc 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-42708.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/issue-42708.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-50061.rs b/src/test/run-pass/proc-macro/auxiliary/issue-50061.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-50061.rs
rename to src/test/run-pass/proc-macro/auxiliary/issue-50061.rs
index 6de1752..a8a03ca 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-50061.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/issue-50061.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/lifetimes.rs b/src/test/run-pass/proc-macro/auxiliary/lifetimes.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/lifetimes.rs
rename to src/test/run-pass/proc-macro/auxiliary/lifetimes.rs
index 0ee26b6..c52496d 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/lifetimes.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/lifetimes.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/modify-ast.rs b/src/test/run-pass/proc-macro/auxiliary/modify-ast.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/modify-ast.rs
rename to src/test/run-pass/proc-macro/auxiliary/modify-ast.rs
index 498c681..ff28c1d 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/modify-ast.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/modify-ast.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/negative-token.rs b/src/test/run-pass/proc-macro/auxiliary/negative-token.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/negative-token.rs
rename to src/test/run-pass/proc-macro/auxiliary/negative-token.rs
index fd63969..ef4fd8d 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/negative-token.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/negative-token.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/not-joint.rs b/src/test/run-pass/proc-macro/auxiliary/not-joint.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/not-joint.rs
rename to src/test/run-pass/proc-macro/auxiliary/not-joint.rs
index e00a4d8..90209e0 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/not-joint.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/not-joint.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/span-api-tests.rs b/src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/span-api-tests.rs
rename to src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/span-test-macros.rs b/src/test/run-pass/proc-macro/auxiliary/span-test-macros.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/span-test-macros.rs
rename to src/test/run-pass/proc-macro/auxiliary/span-test-macros.rs
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/test-macros.rs b/src/test/run-pass/proc-macro/auxiliary/test-macros.rs
similarity index 98%
copy from src/test/compile-fail-fulldeps/proc-macro/auxiliary/test-macros.rs
copy to src/test/run-pass/proc-macro/auxiliary/test-macros.rs
index 581c7cb..0e4343a 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/test-macros.rs
+++ b/src/test/run-pass/proc-macro/auxiliary/test-macros.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs b/src/test/run-pass/proc-macro/bang-macro.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/bang-macro.rs
rename to src/test/run-pass/proc-macro/bang-macro.rs
index 10fe015..f433bc6 100644
--- a/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs
+++ b/src/test/run-pass/proc-macro/bang-macro.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:bang-macro.rs
-// ignore-stage1
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/call-site.rs b/src/test/run-pass/proc-macro/call-site.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/call-site.rs
rename to src/test/run-pass/proc-macro/call-site.rs
index b27c806..ccbf33c 100644
--- a/src/test/run-pass-fulldeps/proc-macro/call-site.rs
+++ b/src/test/run-pass/proc-macro/call-site.rs
@@ -11,7 +11,6 @@
 #![allow(unused_variables)]
 #![allow(unused_imports)]
 // aux-build:call-site.rs
-// ignore-stage1
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs b/src/test/run-pass/proc-macro/count_compound_ops.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs
rename to src/test/run-pass/proc-macro/count_compound_ops.rs
index 07ad4f2..46a5906 100644
--- a/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs
+++ b/src/test/run-pass/proc-macro/count_compound_ops.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:count_compound_ops.rs
-// ignore-stage1
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs b/src/test/run-pass/proc-macro/crate-var.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/crate-var.rs
rename to src/test/run-pass/proc-macro/crate-var.rs
index 41c1519..00b467a 100644
--- a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs
+++ b/src/test/run-pass/proc-macro/crate-var.rs
@@ -10,7 +10,6 @@
 
 // aux-build:double.rs
 // aux-build:external-crate-var.rs
-// ignore-stage1
 
 #![allow(unused)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/custom-attr-only-one-derive.rs b/src/test/run-pass/proc-macro/custom-attr-only-one-derive.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/custom-attr-only-one-derive.rs
rename to src/test/run-pass/proc-macro/custom-attr-only-one-derive.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs b/src/test/run-pass/proc-macro/derive-attr-cfg.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs
rename to src/test/run-pass/proc-macro/derive-attr-cfg.rs
index e7e8b3d..f804042 100644
--- a/src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs
+++ b/src/test/run-pass/proc-macro/derive-attr-cfg.rs
@@ -10,7 +10,6 @@
 
 #![allow(dead_code)]
 // aux-build:derive-attr-cfg.rs
-// ignore-stage1
 
 extern crate derive_attr_cfg;
 use derive_attr_cfg::Foo;
diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs b/src/test/run-pass/proc-macro/derive-b.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/derive-b.rs
rename to src/test/run-pass/proc-macro/derive-b.rs
index ac9eca3..60a6cf7 100644
--- a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs
+++ b/src/test/run-pass/proc-macro/derive-b.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:derive-b.rs
-// ignore-stage1
 
 #![feature(unrestricted_attribute_tokens)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs b/src/test/run-pass/proc-macro/derive-same-struct.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs
rename to src/test/run-pass/proc-macro/derive-same-struct.rs
index 64ad571..7aff32e 100644
--- a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs
+++ b/src/test/run-pass/proc-macro/derive-same-struct.rs
@@ -11,7 +11,6 @@
 #![allow(path_statements)]
 #![allow(dead_code)]
 // aux-build:derive-same-struct.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate derive_same_struct;
diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.stdout b/src/test/run-pass/proc-macro/derive-same-struct.stdout
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/derive-same-struct.stdout
rename to src/test/run-pass/proc-macro/derive-same-struct.stdout
diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-test.rs b/src/test/run-pass/proc-macro/derive-test.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/derive-test.rs
rename to src/test/run-pass/proc-macro/derive-test.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-two-attrs.rs b/src/test/run-pass/proc-macro/derive-two-attrs.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/derive-two-attrs.rs
rename to src/test/run-pass/proc-macro/derive-two-attrs.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-union.rs b/src/test/run-pass/proc-macro/derive-union.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/derive-union.rs
rename to src/test/run-pass/proc-macro/derive-union.rs
index 298a652..2aae1d8 100644
--- a/src/test/run-pass-fulldeps/proc-macro/derive-union.rs
+++ b/src/test/run-pass/proc-macro/derive-union.rs
@@ -10,7 +10,6 @@
 
 #![allow(unused_variables)]
 // aux-build:derive-union.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate derive_union;
diff --git a/src/test/run-pass-fulldeps/proc-macro/empty-crate.rs b/src/test/run-pass/proc-macro/empty-crate.rs
similarity index 96%
rename from src/test/run-pass-fulldeps/proc-macro/empty-crate.rs
rename to src/test/run-pass/proc-macro/empty-crate.rs
index 2b0a57d..1a0c050 100644
--- a/src/test/run-pass-fulldeps/proc-macro/empty-crate.rs
+++ b/src/test/run-pass/proc-macro/empty-crate.rs
@@ -10,7 +10,6 @@
 
 #![allow(unused_imports)]
 // aux-build:empty-crate.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate empty_crate;
diff --git a/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs b/src/test/run-pass/proc-macro/expand-with-a-macro.rs
similarity index 91%
rename from src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs
rename to src/test/run-pass/proc-macro/expand-with-a-macro.rs
index 4ccd461..944973e 100644
--- a/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs
+++ b/src/test/run-pass/proc-macro/expand-with-a-macro.rs
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 // aux-build:expand-with-a-macro.rs
-// ignore-stage1
+
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![deny(warnings)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/gen-lifetime-token.rs b/src/test/run-pass/proc-macro/gen-lifetime-token.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/gen-lifetime-token.rs
rename to src/test/run-pass/proc-macro/gen-lifetime-token.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs b/src/test/run-pass/proc-macro/hygiene_example.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs
rename to src/test/run-pass/proc-macro/hygiene_example.rs
index cf18bb2..41857fd 100644
--- a/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs
+++ b/src/test/run-pass/proc-macro/hygiene_example.rs
@@ -11,7 +11,6 @@
 #![allow(unused_macros)]
 // aux-build:hygiene_example_codegen.rs
 // aux-build:hygiene_example.rs
-// ignore-stage1
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs b/src/test/run-pass/proc-macro/issue-39889.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/issue-39889.rs
rename to src/test/run-pass/proc-macro/issue-39889.rs
index f722109..99500a7 100644
--- a/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs
+++ b/src/test/run-pass/proc-macro/issue-39889.rs
@@ -10,7 +10,6 @@
 
 #![allow(dead_code)]
 // aux-build:issue-39889.rs
-// ignore-stage1
 
 extern crate issue_39889;
 use issue_39889::Issue39889;
diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs b/src/test/run-pass/proc-macro/issue-42708.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/issue-42708.rs
rename to src/test/run-pass/proc-macro/issue-42708.rs
index 7bbdbc6..8f9c872 100644
--- a/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs
+++ b/src/test/run-pass/proc-macro/issue-42708.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:issue-42708.rs
-// ignore-stage1
 
 #![feature(decl_macro)]
 #![allow(unused)]
diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-50061.rs b/src/test/run-pass/proc-macro/issue-50061.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/issue-50061.rs
rename to src/test/run-pass/proc-macro/issue-50061.rs
index 0465916..1a75116 100644
--- a/src/test/run-pass-fulldeps/proc-macro/issue-50061.rs
+++ b/src/test/run-pass/proc-macro/issue-50061.rs
@@ -10,7 +10,6 @@
 
 #![allow(path_statements)]
 // aux-build:issue-50061.rs
-// ignore-stage1
 
 #![feature(decl_macro)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/lifetimes.rs b/src/test/run-pass/proc-macro/lifetimes.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/lifetimes.rs
rename to src/test/run-pass/proc-macro/lifetimes.rs
index 79d6d27..7cd234d 100644
--- a/src/test/run-pass-fulldeps/proc-macro/lifetimes.rs
+++ b/src/test/run-pass/proc-macro/lifetimes.rs
@@ -10,7 +10,6 @@
 
 #![allow(unused_variables)]
 // aux-build:lifetimes.rs
-// ignore-stage1
 
 extern crate lifetimes;
 use lifetimes::*;
diff --git a/src/test/run-pass-fulldeps/proc-macro/load-two.rs b/src/test/run-pass/proc-macro/load-two.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/load-two.rs
rename to src/test/run-pass/proc-macro/load-two.rs
index cf1e076..319e99d 100644
--- a/src/test/run-pass-fulldeps/proc-macro/load-two.rs
+++ b/src/test/run-pass/proc-macro/load-two.rs
@@ -12,7 +12,6 @@
 #![allow(dead_code)]
 // aux-build:derive-atob.rs
 // aux-build:derive-ctod.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate derive_atob;
diff --git a/src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs b/src/test/run-pass/proc-macro/macros-in-extern.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs
rename to src/test/run-pass/proc-macro/macros-in-extern.rs
index bd76cc3..ce62cab 100644
--- a/src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs
+++ b/src/test/run-pass/proc-macro/macros-in-extern.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:test-macros.rs
-// ignore-stage1
 // ignore-wasm32
 
 #![feature(macros_in_extern)]
diff --git a/src/test/run-pass-fulldeps/proc-macro/modify-ast.rs b/src/test/run-pass/proc-macro/modify-ast.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/modify-ast.rs
rename to src/test/run-pass/proc-macro/modify-ast.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/negative-token.rs b/src/test/run-pass/proc-macro/negative-token.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/negative-token.rs
rename to src/test/run-pass/proc-macro/negative-token.rs
index ccd729b..f953ba8 100644
--- a/src/test/run-pass-fulldeps/proc-macro/negative-token.rs
+++ b/src/test/run-pass/proc-macro/negative-token.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:negative-token.rs
-// ignore-stage1
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/not-joint.rs b/src/test/run-pass/proc-macro/not-joint.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/not-joint.rs
rename to src/test/run-pass/proc-macro/not-joint.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/smoke.rs b/src/test/run-pass/proc-macro/smoke.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/smoke.rs
rename to src/test/run-pass/proc-macro/smoke.rs
index 49011e1..ba0cd3b 100644
--- a/src/test/run-pass-fulldeps/proc-macro/smoke.rs
+++ b/src/test/run-pass/proc-macro/smoke.rs
@@ -11,7 +11,6 @@
 #![allow(unused_must_use)]
 #![allow(path_statements)]
 // aux-build:derive-a.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate derive_a;
diff --git a/src/test/run-pass-fulldeps/proc-macro/span-api-tests.rs b/src/test/run-pass/proc-macro/span-api-tests.rs
similarity index 100%
rename from src/test/run-pass-fulldeps/proc-macro/span-api-tests.rs
rename to src/test/run-pass/proc-macro/span-api-tests.rs
diff --git a/src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs b/src/test/run-pass/proc-macro/struct-field-macro.rs
similarity index 97%
rename from src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs
rename to src/test/run-pass/proc-macro/struct-field-macro.rs
index db52aa5..b1ac803 100644
--- a/src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs
+++ b/src/test/run-pass/proc-macro/struct-field-macro.rs
@@ -10,7 +10,6 @@
 
 #![allow(dead_code)]
 // aux-build:derive-nothing.rs
-// ignore-stage1
 
 #[macro_use]
 extern crate derive_nothing;
diff --git a/src/test/run-pass-fulldeps/proc_macro.rs b/src/test/run-pass/proc_macro.rs
similarity index 98%
rename from src/test/run-pass-fulldeps/proc_macro.rs
rename to src/test/run-pass/proc_macro.rs
index 27e0c23..e14ceca 100644
--- a/src/test/run-pass-fulldeps/proc_macro.rs
+++ b/src/test/run-pass/proc_macro.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:proc_macro_def.rs
-// ignore-stage1
 // ignore-cross-compile
 
 #![feature(proc_macro_hygiene)]
diff --git a/src/test/run-pass/rfcs/rfc-2302-self-struct-ctor.rs b/src/test/run-pass/rfcs/rfc-2302-self-struct-ctor.rs
index 156e240..1ec20c5 100644
--- a/src/test/run-pass/rfcs/rfc-2302-self-struct-ctor.rs
+++ b/src/test/run-pass/rfcs/rfc-2302-self-struct-ctor.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(self_struct_ctor)]
-
 #![allow(dead_code)]
 
 use std::fmt::Display;
diff --git a/src/test/run-pass/self/self-in-typedefs.rs b/src/test/run-pass/self/self-in-typedefs.rs
index 92eccb4..84a7e18f 100644
--- a/src/test/run-pass/self/self-in-typedefs.rs
+++ b/src/test/run-pass/self/self-in-typedefs.rs
@@ -9,12 +9,11 @@
 // except according to those terms.
 
 // run-pass
-#![allow(unions_with_drop_fields)]
 
-#![feature(self_in_typedefs)]
 #![feature(untagged_unions)]
 
 #![allow(dead_code)]
+#![allow(unions_with_drop_fields)]
 
 enum A<'a, T: 'a>
 where
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs b/src/test/rustdoc-js/filter-crate.js
similarity index 79%
copy from src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs
copy to src/test/rustdoc-js/filter-crate.js
index b45d4bf..97ecc60 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs
+++ b/src/test/rustdoc-js/filter-crate.js
@@ -8,7 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// no-prefer-dynamic
+// exact-check
 
-#![crate_type = "proc-macro"]
-#![deny(unused_variables)]
+const QUERY = 'hashmap';
+const FILTER_CRATE = 'core';
+
+const EXPECTED = {
+    'others': [
+    ],
+};
diff --git a/src/test/rustdoc-ui/doc-without-codeblock.rs b/src/test/rustdoc-ui/doc-without-codeblock.rs
index e047b27..645deff 100644
--- a/src/test/rustdoc-ui/doc-without-codeblock.rs
+++ b/src/test/rustdoc-ui/doc-without-codeblock.rs
@@ -1,3 +1,4 @@
+//~ ERROR Missing code example in this documentation
 // 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.
@@ -11,10 +12,13 @@
 #![deny(missing_doc_code_examples)]
 
 /// Some docs.
+//~^ ERROR Missing code example in this documentation
 pub struct Foo;
 
 /// And then, the princess died.
+//~^ ERROR Missing code example in this documentation
 pub mod foo {
     /// Or maybe not because she saved herself!
+    //~^ ERROR Missing code example in this documentation
     pub fn bar() {}
 }
diff --git a/src/test/rustdoc-ui/doc-without-codeblock.stderr b/src/test/rustdoc-ui/doc-without-codeblock.stderr
index ba5bb7f..f3efc65 100644
--- a/src/test/rustdoc-ui/doc-without-codeblock.stderr
+++ b/src/test/rustdoc-ui/doc-without-codeblock.stderr
@@ -1,25 +1,25 @@
 error: Missing code example in this documentation
    |
 note: lint level defined here
-  --> $DIR/doc-without-codeblock.rs:11:9
+  --> $DIR/doc-without-codeblock.rs:12:9
    |
 LL | #![deny(missing_doc_code_examples)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Missing code example in this documentation
-  --> $DIR/doc-without-codeblock.rs:13:1
+  --> $DIR/doc-without-codeblock.rs:14:1
    |
 LL | /// Some docs.
    | ^^^^^^^^^^^^^^
 
 error: Missing code example in this documentation
-  --> $DIR/doc-without-codeblock.rs:16:1
+  --> $DIR/doc-without-codeblock.rs:18:1
    |
 LL | /// And then, the princess died.
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Missing code example in this documentation
-  --> $DIR/doc-without-codeblock.rs:18:5
+  --> $DIR/doc-without-codeblock.rs:21:5
    |
 LL |     /// Or maybe not because she saved herself!
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout
index cab7bda..52e0cdc 100644
--- a/src/test/rustdoc-ui/failed-doctest-output.stdout
+++ b/src/test/rustdoc-ui/failed-doctest-output.stdout
@@ -12,7 +12,7 @@
 3 | no
   | ^^ not found in this scope
 
-thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:323:13
+thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:327:13
 note: Run with `RUST_BACKTRACE=1` for a backtrace.
 
 ---- $DIR/failed-doctest-output.rs - SomeStruct (line 21) stdout ----
@@ -21,7 +21,7 @@
 thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1
 note: Run with `RUST_BACKTRACE=1` for a backtrace.
 
-', src/librustdoc/test.rs:358:17
+', src/librustdoc/test.rs:362:17
 
 
 failures:
diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.rs b/src/test/rustdoc-ui/intra-link-span-ice-55723.rs
index 12e59a4..c701548 100644
--- a/src/test/rustdoc-ui/intra-link-span-ice-55723.rs
+++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.rs
@@ -17,8 +17,9 @@
 // https://github.com/rust-lang/rust/issues/55723
 
 /// ## For example:
-///  
+///
 /// (arr[i])
+//~^ ERROR `[i]` cannot be resolved, ignoring it...
 pub fn test_ice() {
     unimplemented!();
 }
diff --git a/src/test/rustdoc-ui/private-item-doc-test.rs b/src/test/rustdoc-ui/private-item-doc-test.rs
index 5a13fe3..771dc3b 100644
--- a/src/test/rustdoc-ui/private-item-doc-test.rs
+++ b/src/test/rustdoc-ui/private-item-doc-test.rs
@@ -16,5 +16,6 @@
     /// ```
     /// assert!(false);
     /// ```
+    //~^^^^^ ERROR Documentation test in private item
     fn bar() {}
 }
diff --git a/src/test/rustdoc/doc-proc-macro.rs b/src/test/rustdoc/doc-proc-macro.rs
index 01a4a41..b3b403a 100644
--- a/src/test/rustdoc/doc-proc-macro.rs
+++ b/src/test/rustdoc/doc-proc-macro.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-stage1
-
 // Issue #52129: ICE when trying to document the `quote` proc-macro from proc_macro
 
 // As of this writing, we don't currently attempt to document proc-macros. However, we shouldn't
diff --git a/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs b/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs
index 6aac070..bde1fd8 100644
--- a/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs
+++ b/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type="proc-macro"]
diff --git a/src/test/rustdoc/inline_cross/proc_macro.rs b/src/test/rustdoc/inline_cross/proc_macro.rs
index a879258..c259e9c 100644
--- a/src/test/rustdoc/inline_cross/proc_macro.rs
+++ b/src/test/rustdoc/inline_cross/proc_macro.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-stage1
 // aux-build:proc_macro.rs
 // build-aux-docs
 
diff --git a/src/test/rustdoc/inline_local/macro_by_example.rs b/src/test/rustdoc/inline_local/macro_by_example.rs
new file mode 100644
index 0000000..93d55ec
--- /dev/null
+++ b/src/test/rustdoc/inline_local/macro_by_example.rs
@@ -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.
+
+
+/// docs for foo
+#[deprecated(since = "1.2.3", note = "text")]
+#[macro_export]
+macro_rules! foo {
+    ($($tt:tt)*) => {}
+}
+
+// @has macro_by_example/macros/index.html
+pub mod macros {
+    // @!has - 'pub use foo as bar;'
+    // @has macro_by_example/macros/macro.bar.html
+    // @has - '//*[@class="docblock"]' 'docs for foo'
+    // @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.2.3: text'
+    // @has - '//a/@href' 'macro_by_example.rs.html#15-17'
+    #[doc(inline)]
+    pub use foo as bar;
+}
diff --git a/src/test/rustdoc/proc-macro.rs b/src/test/rustdoc/proc-macro.rs
index bfd1947..23d0d00 100644
--- a/src/test/rustdoc/proc-macro.rs
+++ b/src/test/rustdoc/proc-macro.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-stage1
+// force-host
+// no-prefer-dynamic
 
 #![crate_type="proc-macro"]
 #![crate_name="some_macros"]
diff --git a/src/test/rustdoc/rustc-macro-crate.rs b/src/test/rustdoc/rustc-macro-crate.rs
index d46f968..6ad5556 100644
--- a/src/test/rustdoc/rustc-macro-crate.rs
+++ b/src/test/rustdoc/rustc-macro-crate.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
-// ignore-stage1
 
 #![crate_type = "proc-macro"]
 
diff --git a/src/test/rustdoc/sidebar-link-generation.rs b/src/test/rustdoc/sidebar-link-generation.rs
new file mode 100644
index 0000000..2482a7e
--- /dev/null
+++ b/src/test/rustdoc/sidebar-link-generation.rs
@@ -0,0 +1,23 @@
+// 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.
+
+#![crate_name = "foo"]
+
+// @has foo/struct.SomeStruct.html '//*[@class="sidebar-links"]/a[@href="#method.some_fn-1"]' \
+//          "some_fn"
+pub struct SomeStruct<T> { _inner: T }
+
+impl SomeStruct<()> {
+    pub fn some_fn(&self) {}
+}
+
+impl SomeStruct<usize> {
+    pub fn some_fn(&self) {}
+}
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs b/src/test/rustdoc/source-file.rs
similarity index 84%
copy from src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs
copy to src/test/rustdoc/source-file.rs
index b45d4bf..077817b 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs
+++ b/src/test/rustdoc/source-file.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// no-prefer-dynamic
+#![crate_name = "foo"]
 
-#![crate_type = "proc-macro"]
-#![deny(unused_variables)]
+// @has source-files.js source-file.rs
+
+pub struct Foo;
diff --git a/src/test/ui-fulldeps/auxiliary/attr_proc_macro.rs b/src/test/ui-fulldeps/auxiliary/attr_proc_macro.rs
deleted file mode 100644
index 679cb77..0000000
--- a/src/test/ui-fulldeps/auxiliary/attr_proc_macro.rs
+++ /dev/null
@@ -1,23 +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.
-
-// force-host
-// no-prefer-dynamic
-
-#![crate_type = "proc-macro"]
-
-extern crate proc_macro;
-
-use proc_macro::TokenStream;
-
-#[proc_macro_attribute]
-pub fn attr_proc_macro(_: TokenStream, input: TokenStream) -> TokenStream {
-    input
-}
diff --git a/src/test/ui-fulldeps/auxiliary/bang_proc_macro.rs b/src/test/ui-fulldeps/auxiliary/bang_proc_macro.rs
deleted file mode 100644
index 6484725..0000000
--- a/src/test/ui-fulldeps/auxiliary/bang_proc_macro.rs
+++ /dev/null
@@ -1,23 +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.
-
-// force-host
-// no-prefer-dynamic
-
-#![crate_type = "proc-macro"]
-
-extern crate proc_macro;
-
-use proc_macro::TokenStream;
-
-#[proc_macro]
-pub fn bang_proc_macro(input: TokenStream) -> TokenStream {
-    input
-}
diff --git a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs
index 1057649..f697642 100644
--- a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 // Load rustc as a plugin to get macros
 #[macro_use]
diff --git a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs
index b0183a3..8647797 100644
--- a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 extern crate syntax;
 
diff --git a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs
index 7d2acd7..0a449e3 100644
--- a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs
@@ -10,7 +10,6 @@
 
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 extern crate syntax;
 
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed.rs b/src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed.rs
deleted file mode 100644
index 4e70171..0000000
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// no-prefer-dynamic
-
-#![crate_type = "proc-macro"]
-
-extern crate proc_macro;
-use proc_macro::*;
-
-#[proc_macro_derive(MyTrait, attributes(my_attr))]
-pub fn foo(_: TokenStream) -> TokenStream {
-    TokenStream::new()
-}
diff --git a/src/test/ui-fulldeps/unnecessary-extern-crate.stderr b/src/test/ui-fulldeps/unnecessary-extern-crate.stderr
deleted file mode 100644
index 58ec590..0000000
--- a/src/test/ui-fulldeps/unnecessary-extern-crate.stderr
+++ /dev/null
@@ -1,44 +0,0 @@
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:16:1
-   |
-LL | extern crate alloc;
-   | ^^^^^^^^^^^^^^^^^^^ help: remove it
-   |
-note: lint level defined here
-  --> $DIR/unnecessary-extern-crate.rs:13:9
-   |
-LL | #![deny(unused_extern_crates)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:19:1
-   |
-LL | extern crate alloc as x;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:41:5
-   |
-LL |     extern crate alloc;
-   |     ^^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:45:5
-   |
-LL |     extern crate alloc as x;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:54:9
-   |
-LL |         extern crate alloc;
-   |         ^^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: unused extern crate
-  --> $DIR/unnecessary-extern-crate.rs:58:9
-   |
-LL |         extern crate alloc as x;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: aborting due to 6 previous errors
-
diff --git a/src/test/ui/E0501.ast.nll.stderr b/src/test/ui/E0501.ast.nll.stderr
index 72fda90..8a3fce3 100644
--- a/src/test/ui/E0501.ast.nll.stderr
+++ b/src/test/ui/E0501.ast.nll.stderr
@@ -7,7 +7,7 @@
    |                        - first borrow occurs due to use of `a` in closure
 LL |     };
 LL |     outside_closure_1(a); //[ast]~ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
-   |                       ^ borrow occurs here
+   |                       ^ second borrow occurs here
 ...
 LL |     drop(bar);
    |          --- first borrow later used here
@@ -21,7 +21,7 @@
    |                        - first borrow occurs due to use of `a` in closure
 ...
 LL |     outside_closure_2(a); //[ast]~ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
-   |                       ^ borrow occurs here
+   |                       ^ second borrow occurs here
 ...
 LL |     drop(bar);
    |          --- first borrow later used here
diff --git a/src/test/ui/E0501.mir.stderr b/src/test/ui/E0501.mir.stderr
index 72fda90..8a3fce3 100644
--- a/src/test/ui/E0501.mir.stderr
+++ b/src/test/ui/E0501.mir.stderr
@@ -7,7 +7,7 @@
    |                        - first borrow occurs due to use of `a` in closure
 LL |     };
 LL |     outside_closure_1(a); //[ast]~ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
-   |                       ^ borrow occurs here
+   |                       ^ second borrow occurs here
 ...
 LL |     drop(bar);
    |          --- first borrow later used here
@@ -21,7 +21,7 @@
    |                        - first borrow occurs due to use of `a` in closure
 ...
 LL |     outside_closure_2(a); //[ast]~ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
-   |                       ^ borrow occurs here
+   |                       ^ second borrow occurs here
 ...
 LL |     drop(bar);
    |          --- first borrow later used here
diff --git a/src/test/ui/always-inhabited-union-ref.rs b/src/test/ui/always-inhabited-union-ref.rs
new file mode 100644
index 0000000..11eae2a
--- /dev/null
+++ b/src/test/ui/always-inhabited-union-ref.rs
@@ -0,0 +1,32 @@
+// The precise semantics of inhabitedness with respect to unions and references is currently
+// undecided. This test file currently checks a conservative choice.
+
+#![feature(exhaustive_patterns)]
+#![feature(never_type)]
+
+#![allow(dead_code)]
+#![allow(unreachable_code)]
+
+pub union Foo {
+    foo: !,
+}
+
+fn uninhab_ref() -> &'static ! {
+    unimplemented!()
+}
+
+fn uninhab_union() -> Foo {
+    unimplemented!()
+}
+
+fn match_on_uninhab() {
+    match uninhab_ref() {
+        //~^ ERROR non-exhaustive patterns: type `&'static !` is non-empty
+    }
+
+    match uninhab_union() {
+        //~^ ERROR non-exhaustive patterns: type `Foo` is non-empty
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/always-inhabited-union-ref.stderr b/src/test/ui/always-inhabited-union-ref.stderr
new file mode 100644
index 0000000..212f5d7
--- /dev/null
+++ b/src/test/ui/always-inhabited-union-ref.stderr
@@ -0,0 +1,27 @@
+error[E0004]: non-exhaustive patterns: type `&'static !` is non-empty
+  --> $DIR/always-inhabited-union-ref.rs:23:11
+   |
+LL |     match uninhab_ref() {
+   |           ^^^^^^^^^^^^^
+   |
+help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+  --> $DIR/always-inhabited-union-ref.rs:23:11
+   |
+LL |     match uninhab_ref() {
+   |           ^^^^^^^^^^^^^
+
+error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
+  --> $DIR/always-inhabited-union-ref.rs:27:11
+   |
+LL |     match uninhab_union() {
+   |           ^^^^^^^^^^^^^^^
+   |
+help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+  --> $DIR/always-inhabited-union-ref.rs:27:11
+   |
+LL |     match uninhab_union() {
+   |           ^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.rs b/src/test/ui/associated-types/associated-types-overridden-binding-2.rs
index 8d91561..3153ba4 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding-2.rs
+++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.rs
@@ -14,4 +14,5 @@
 
 fn main() {
     let _: &I32Iterator<Item = u32> = &vec![42].into_iter();
+    //~^ ERROR type mismatch
 }
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.rs b/src/test/ui/associated-types/associated-types-overridden-binding.rs
index ed2211e..1e0514e 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding.rs
+++ b/src/test/ui/associated-types/associated-types-overridden-binding.rs
@@ -11,7 +11,7 @@
 #![feature(trait_alias)]
 
 trait Foo: Iterator<Item = i32> {}
-trait Bar: Foo<Item = u32> {}
+trait Bar: Foo<Item = u32> {} //~ ERROR type annotations required
 
 trait I32Iterator = Iterator<Item = i32>;
 trait U32Iterator = I32Iterator<Item = u32>;
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
index 216aa09..c3e6eb8 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding.stderr
+++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
@@ -1,7 +1,7 @@
 error[E0284]: type annotations required: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
   --> $DIR/associated-types-overridden-binding.rs:14:1
    |
-LL | trait Bar: Foo<Item = u32> {}
+LL | trait Bar: Foo<Item = u32> {} //~ ERROR type annotations required
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: required by `Foo`
diff --git a/src/test/ui/await-keyword/2015-edition-warning.fixed b/src/test/ui/await-keyword/2015-edition-warning.fixed
index c2c40cd..c58496c 100644
--- a/src/test/ui/await-keyword/2015-edition-warning.fixed
+++ b/src/test/ui/await-keyword/2015-edition-warning.fixed
@@ -5,11 +5,23 @@
 
 mod outer_mod {
     pub mod r#await {
+//~^ ERROR `await` is a keyword
+//~| WARN was previously accepted
         pub struct r#await;
+//~^ ERROR `await` is a keyword
+//~| WARN was previously accepted
     }
 }
 use outer_mod::r#await::r#await;
+//~^ ERROR `await` is a keyword
+//~| ERROR `await` is a keyword
+//~| WARN was previously accepted
+//~| WARN was previously accepted
 
 fn main() {
     match r#await { r#await => {} }
+//~^ ERROR `await` is a keyword
+//~| ERROR `await` is a keyword
+//~| WARN was previously accepted
+//~| WARN was previously accepted
 }
diff --git a/src/test/ui/await-keyword/2015-edition-warning.rs b/src/test/ui/await-keyword/2015-edition-warning.rs
index 95539ab..a7543a1 100644
--- a/src/test/ui/await-keyword/2015-edition-warning.rs
+++ b/src/test/ui/await-keyword/2015-edition-warning.rs
@@ -5,11 +5,23 @@
 
 mod outer_mod {
     pub mod await {
+//~^ ERROR `await` is a keyword
+//~| WARN was previously accepted
         pub struct await;
+//~^ ERROR `await` is a keyword
+//~| WARN was previously accepted
     }
 }
 use outer_mod::await::await;
+//~^ ERROR `await` is a keyword
+//~| ERROR `await` is a keyword
+//~| WARN was previously accepted
+//~| WARN was previously accepted
 
 fn main() {
     match await { await => {} }
+//~^ ERROR `await` is a keyword
+//~| ERROR `await` is a keyword
+//~| WARN was previously accepted
+//~| WARN was previously accepted
 }
diff --git a/src/test/ui/await-keyword/2015-edition-warning.stderr b/src/test/ui/await-keyword/2015-edition-warning.stderr
index 073e9d7..d9ae1b9 100644
--- a/src/test/ui/await-keyword/2015-edition-warning.stderr
+++ b/src/test/ui/await-keyword/2015-edition-warning.stderr
@@ -13,7 +13,7 @@
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:8:20
+  --> $DIR/2015-edition-warning.rs:10:20
    |
 LL |         pub struct await;
    |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -22,7 +22,7 @@
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:11:16
+  --> $DIR/2015-edition-warning.rs:15:16
    |
 LL | use outer_mod::await::await;
    |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -31,7 +31,7 @@
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:11:23
+  --> $DIR/2015-edition-warning.rs:15:23
    |
 LL | use outer_mod::await::await;
    |                       ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -40,7 +40,7 @@
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:14:11
+  --> $DIR/2015-edition-warning.rs:22:11
    |
 LL |     match await { await => {} }
    |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -49,7 +49,7 @@
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:14:19
+  --> $DIR/2015-edition-warning.rs:22:19
    |
 LL |     match await { await => {} }
    |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
diff --git a/src/test/ui/await-keyword/2018-edition-error.rs b/src/test/ui/await-keyword/2018-edition-error.rs
index a9e2e3f..7ba3382 100644
--- a/src/test/ui/await-keyword/2018-edition-error.rs
+++ b/src/test/ui/await-keyword/2018-edition-error.rs
@@ -2,12 +2,14 @@
 #![allow(non_camel_case_types)]
 
 mod outer_mod {
-    pub mod await {
-        pub struct await;
+    pub mod await { //~ ERROR `await` is a keyword
+        pub struct await; //~ ERROR `await` is a keyword
     }
 }
-use self::outer_mod::await::await;
+use self::outer_mod::await::await; //~ ERROR `await` is a keyword
+    //~^ ERROR `await` is a keyword
 
 fn main() {
-    match await { await => () }
+    match await { await => () } //~ ERROR `await` is a keyword
+    //~^ ERROR `await` is a keyword
 }
diff --git a/src/test/ui/await-keyword/2018-edition-error.stderr b/src/test/ui/await-keyword/2018-edition-error.stderr
index d5727b8..9ddb279 100644
--- a/src/test/ui/await-keyword/2018-edition-error.stderr
+++ b/src/test/ui/await-keyword/2018-edition-error.stderr
@@ -1,37 +1,37 @@
 error[E0721]: `await` is a keyword in the 2018 edition
   --> $DIR/2018-edition-error.rs:5:13
    |
-LL |     pub mod await {
+LL |     pub mod await { //~ ERROR `await` is a keyword
    |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
 
 error[E0721]: `await` is a keyword in the 2018 edition
   --> $DIR/2018-edition-error.rs:6:20
    |
-LL |         pub struct await;
+LL |         pub struct await; //~ ERROR `await` is a keyword
    |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
 
 error[E0721]: `await` is a keyword in the 2018 edition
   --> $DIR/2018-edition-error.rs:9:22
    |
-LL | use self::outer_mod::await::await;
+LL | use self::outer_mod::await::await; //~ ERROR `await` is a keyword
    |                      ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
 
 error[E0721]: `await` is a keyword in the 2018 edition
   --> $DIR/2018-edition-error.rs:9:29
    |
-LL | use self::outer_mod::await::await;
+LL | use self::outer_mod::await::await; //~ ERROR `await` is a keyword
    |                             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
 
 error[E0721]: `await` is a keyword in the 2018 edition
-  --> $DIR/2018-edition-error.rs:12:11
+  --> $DIR/2018-edition-error.rs:13:11
    |
-LL |     match await { await => () }
+LL |     match await { await => () } //~ ERROR `await` is a keyword
    |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
 
 error[E0721]: `await` is a keyword in the 2018 edition
-  --> $DIR/2018-edition-error.rs:12:19
+  --> $DIR/2018-edition-error.rs:13:19
    |
-LL |     match await { await => () }
+LL |     match await { await => () } //~ ERROR `await` is a keyword
    |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
 
 error: aborting due to 6 previous errors
diff --git a/src/test/ui/await-keyword/post_expansion_error.rs b/src/test/ui/await-keyword/post_expansion_error.rs
index 580ca3b..96dd480 100644
--- a/src/test/ui/await-keyword/post_expansion_error.rs
+++ b/src/test/ui/await-keyword/post_expansion_error.rs
@@ -6,4 +6,5 @@
 
 fn main() {
     await!()
+    //~^ ERROR `await` is a keyword
 }
diff --git a/src/test/ui/borrowck/borrowck-insert-during-each.nll.stderr b/src/test/ui/borrowck/borrowck-insert-during-each.nll.stderr
index 123d475..84fc694 100644
--- a/src/test/ui/borrowck/borrowck-insert-during-each.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-insert-during-each.nll.stderr
@@ -10,7 +10,7 @@
 LL | |             f.n.insert(*a);
    | |             - first borrow occurs due to use of `f` in closure
 LL | |         })
-   | |__________^ borrow occurs here
+   | |__________^ second borrow occurs here
 
 error[E0500]: closure requires unique access to `f` but it is already borrowed
   --> $DIR/borrowck-insert-during-each.rs:27:9
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.ast.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.ast.stderr
index e3b5341..4f845d8 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.ast.stderr
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.ast.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `t.0`
-  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:25:31
+  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:26:31
    |
 LL |         drop(t);
    |              - value moved here
@@ -10,7 +10,7 @@
    = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `t.1`
-  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:25:36
+  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:26:36
    |
 LL |         drop(t);
    |              - value moved here
@@ -21,7 +21,7 @@
    = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `u.0`
-  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:33:31
+  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:37:31
    |
 LL |         drop(u);
    |              - value moved here
@@ -32,7 +32,7 @@
    = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `u.1`
-  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:33:36
+  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:37:36
    |
 LL |         drop(u);
    |              - value moved here
@@ -43,7 +43,7 @@
    = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `v.x`
-  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:41:31
+  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:48:31
    |
 LL |         drop(v);
    |              - value moved here
@@ -54,7 +54,7 @@
    = note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `v.y`
-  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:41:36
+  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:48:36
    |
 LL |         drop(v);
    |              - value moved here
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr
index 001ed59..7861087 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr
@@ -9,7 +9,7 @@
    = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait
 
 error[E0382]: assign to part of moved value: `u`
-  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:31:9
+  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:34:9
    |
 LL |         drop(u);
    |              - value moved here
@@ -19,7 +19,7 @@
    = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait
 
 error[E0382]: assign to part of moved value: `v`
-  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:39:9
+  --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:45:9
    |
 LL |         drop(v);
    |              - value moved here
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs
index b6339c4..358a5dd 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs
@@ -21,23 +21,32 @@
         let mut t: Tuple = (S(0), 0);
         drop(t);
         t.0 = S(1);
+        //[nll]~^ ERROR assign to part of moved value
         t.1 = 2;
         println!("{:?} {:?}", t.0, t.1);
+        //[ast]~^ ERROR use of moved value
+        //[ast]~^^ ERROR use of moved value
     }
 
     {
         let mut u: Tpair = Tpair(S(0), 0);
         drop(u);
         u.0 = S(1);
+        //[nll]~^ ERROR assign to part of moved value
         u.1 = 2;
         println!("{:?} {:?}", u.0, u.1);
+        //[ast]~^ ERROR use of moved value
+        //[ast]~^^ ERROR use of moved value
     }
 
     {
         let mut v: Spair = Spair { x: S(0), y: 0 };
         drop(v);
         v.x = S(1);
+        //[nll]~^ ERROR assign to part of moved value
         v.y = 2;
         println!("{:?} {:?}", v.x, v.y);
+        //[ast]~^ ERROR use of moved value
+        //[ast]~^^ ERROR use of moved value
     }
 }
diff --git a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs
index 0749900..ad4accb 100644
--- a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs
+++ b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs
@@ -13,7 +13,7 @@
 fn foo(val: Value) {
     let _reviewers_original: Vec<Value> = match val.as_array() {
         Some(array) => {
-            *array
+            *array //~ ERROR cannot move out of borrowed content
         }
         None => vec![]
     };
diff --git a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr
index 6a12016..d1d7d13 100644
--- a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr
+++ b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr
@@ -1,7 +1,7 @@
 error[E0507]: cannot move out of borrowed content
   --> $DIR/issue-54597-reject-move-out-of-borrow-via-pat.rs:16:13
    |
-LL |             *array
+LL |             *array //~ ERROR cannot move out of borrowed content
    |             ^^^^^^
    |             |
    |             cannot move out of borrowed content
diff --git a/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.ast.stderr b/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.ast.stderr
index 3180823..f3e9ce3 100644
--- a/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.ast.stderr
+++ b/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.ast.stderr
@@ -9,7 +9,7 @@
    |
 
 error[E0595]: closure cannot assign to immutable argument `x`
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:29:22
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:32:22
    |
 LL |         let mut c1 = |z: &'static mut isize| {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow mutably
@@ -19,7 +19,7 @@
    |
 
 error[E0595]: closure cannot assign to immutable argument `x`
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:40:9
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:46:9
    |
 LL |     pub fn capture_assign_whole(x: (i32,)) {
    |                                 - help: make this binding mutable: `mut x`
@@ -27,7 +27,7 @@
    |         ^^ cannot borrow mutably
 
 error[E0595]: closure cannot assign to immutable argument `x`
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:43:9
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:52:9
    |
 LL |     pub fn capture_assign_part(x: (i32,)) {
    |                                - help: make this binding mutable: `mut x`
@@ -35,7 +35,7 @@
    |         ^^ cannot borrow mutably
 
 error[E0595]: closure cannot assign to immutable argument `x`
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:46:9
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:58:9
    |
 LL |     pub fn capture_reborrow_whole(x: (i32,)) {
    |                                   - help: make this binding mutable: `mut x`
@@ -43,7 +43,7 @@
    |         ^^ cannot borrow mutably
 
 error[E0595]: closure cannot assign to immutable argument `x`
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:49:9
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:64:9
    |
 LL |     pub fn capture_reborrow_part(x: (i32,)) {
    |                                  - help: make this binding mutable: `mut x`
diff --git a/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.migrate.stderr b/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.migrate.stderr
index 0ccddf0..434f318 100644
--- a/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.migrate.stderr
+++ b/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.migrate.stderr
@@ -8,7 +8,7 @@
    |                                              ^^^^^ cannot assign
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:30:50
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:34:50
    |
 LL |     pub fn ee(x: &'static mut isize) {
    |               - help: consider changing this to be mutable: `mut x`
@@ -17,7 +17,7 @@
    |                                                  ^^^^^ cannot assign
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:40:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:46:14
    |
 LL |     pub fn capture_assign_whole(x: (i32,)) {
    |                                 - help: consider changing this to be mutable: `mut x`
@@ -25,7 +25,7 @@
    |              ^^^^^^^^ cannot assign
 
 error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:43:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:52:14
    |
 LL |     pub fn capture_assign_part(x: (i32,)) {
    |                                - help: consider changing this to be mutable: `mut x`
@@ -33,7 +33,7 @@
    |              ^^^^^^^ cannot assign
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:46:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:58:14
    |
 LL |     pub fn capture_reborrow_whole(x: (i32,)) {
    |                                   - help: consider changing this to be mutable: `mut x`
@@ -41,7 +41,7 @@
    |              ^^^^^^ cannot borrow as mutable
 
 error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:49:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:64:14
    |
 LL |     pub fn capture_reborrow_part(x: (i32,)) {
    |                                  - help: consider changing this to be mutable: `mut x`
diff --git a/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.nll.stderr b/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.nll.stderr
index 0ccddf0..434f318 100644
--- a/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.nll.stderr
+++ b/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.nll.stderr
@@ -8,7 +8,7 @@
    |                                              ^^^^^ cannot assign
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:30:50
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:34:50
    |
 LL |     pub fn ee(x: &'static mut isize) {
    |               - help: consider changing this to be mutable: `mut x`
@@ -17,7 +17,7 @@
    |                                                  ^^^^^ cannot assign
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:40:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:46:14
    |
 LL |     pub fn capture_assign_whole(x: (i32,)) {
    |                                 - help: consider changing this to be mutable: `mut x`
@@ -25,7 +25,7 @@
    |              ^^^^^^^^ cannot assign
 
 error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:43:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:52:14
    |
 LL |     pub fn capture_assign_part(x: (i32,)) {
    |                                - help: consider changing this to be mutable: `mut x`
@@ -33,7 +33,7 @@
    |              ^^^^^^^ cannot assign
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:46:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:58:14
    |
 LL |     pub fn capture_reborrow_whole(x: (i32,)) {
    |                                   - help: consider changing this to be mutable: `mut x`
@@ -41,7 +41,7 @@
    |              ^^^^^^ cannot borrow as mutable
 
 error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:49:14
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:64:14
    |
 LL |     pub fn capture_reborrow_part(x: (i32,)) {
    |                                  - help: consider changing this to be mutable: `mut x`
diff --git a/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs b/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs
index 25ad66a..2bd71ec 100644
--- a/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs
+++ b/src/test/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs
@@ -19,6 +19,9 @@
     pub fn e(x: &'static mut isize) {
         static mut Y: isize = 3;
         let mut c1 = |y: &'static mut isize| x = y;
+        //[migrate]~^ ERROR is not declared as mutable
+        //[nll]~^^ ERROR is not declared as mutable
+        //[ast]~^^^ closure cannot assign to immutable
         unsafe { c1(&mut Y); }
     }
 }
@@ -27,7 +30,10 @@
     pub fn ee(x: &'static mut isize) {
         static mut Z: isize = 3;
         let mut c1 = |z: &'static mut isize| {
+        //[ast]~^ closure cannot assign to immutable
             let mut c2 = |y: &'static mut isize| x = y;
+        //[migrate]~^ ERROR is not declared as mutable
+        //[nll]~^^ ERROR is not declared as mutable
             c2(z);
         };
         unsafe { c1(&mut Z); }
@@ -38,15 +44,27 @@
 mod mutability_errors {
     pub fn capture_assign_whole(x: (i32,)) {
         || { x = (1,); };
+        //[ast]~^ ERROR immutable argument
+        //[migrate]~^^ ERROR is not declared as mutable
+        //[nll]~^^^ ERROR is not declared as mutable
     }
     pub fn capture_assign_part(x: (i32,)) {
         || { x.0 = 1; };
+        //[ast]~^ ERROR immutable argument
+        //[migrate]~^^ ERROR is not declared as mutable
+        //[nll]~^^^ ERROR is not declared as mutable
     }
     pub fn capture_reborrow_whole(x: (i32,)) {
         || { &mut x; };
+        //[ast]~^ ERROR immutable argument
+        //[migrate]~^^ ERROR is not declared as mutable
+        //[nll]~^^^ ERROR is not declared as mutable
     }
     pub fn capture_reborrow_part(x: (i32,)) {
         || { &mut x.0; };
+        //[ast]~^ ERROR immutable argument
+        //[migrate]~^^ ERROR is not declared as mutable
+        //[nll]~^^^ ERROR is not declared as mutable
     }
 }
 
diff --git a/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs b/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs
index dca8f3c..7e2a72f 100644
--- a/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs
+++ b/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs
@@ -29,6 +29,7 @@
     // This will compile, but then hard-abort at runtime.
     // FIXME(oli-obk): this should instead panic (not hard-abort) at runtime.
     let x: &'static u8 = &(bar() + 1);
+    //~^ ERROR does not live long enough
     let y = *x;
     unreachable!();
 }
diff --git a/src/test/ui/consts/const-int-unchecked.rs b/src/test/ui/consts/const-int-unchecked.rs
index cbf8556..6d4b50c 100644
--- a/src/test/ui/consts/const-int-unchecked.rs
+++ b/src/test/ui/consts/const-int-unchecked.rs
@@ -13,9 +13,9 @@
 use std::intrinsics;
 
 const SHR: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) };
-//^~ ERROR: Overflowing shift by 8 in unchecked_shr
+//~^ ERROR any use of this value will cause an error
 const SHL: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) };
-//^~ ERROR: Overflowing shift by 8 in unchecked_shl
+//~^ ERROR any use of this value will cause an error
 
 fn main() {
 }
diff --git a/src/test/ui/consts/const-match-check.eval1.stderr b/src/test/ui/consts/const-match-check.eval1.stderr
index 3caf149..703453e 100644
--- a/src/test/ui/consts/const-match-check.eval1.stderr
+++ b/src/test/ui/consts/const-match-check.eval1.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:35:15
    |
 LL |     A = { let 0 = 0; 0 },
-   |               ^ pattern `_` not covered
+   |               ^ pattern `-2147483648i32..=-1i32` not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-match-check.eval2.stderr b/src/test/ui/consts/const-match-check.eval2.stderr
index de85d4d..6caff93 100644
--- a/src/test/ui/consts/const-match-check.eval2.stderr
+++ b/src/test/ui/consts/const-match-check.eval2.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:41:24
    |
 LL |     let x: [i32; { let 0 = 0; 0 }] = [];
-   |                        ^ pattern `_` not covered
+   |                        ^ pattern `-2147483648i32..=-1i32` not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-match-check.matchck.stderr b/src/test/ui/consts/const-match-check.matchck.stderr
index bbf1169..9e45045 100644
--- a/src/test/ui/consts/const-match-check.matchck.stderr
+++ b/src/test/ui/consts/const-match-check.matchck.stderr
@@ -1,26 +1,26 @@
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:14:22
    |
 LL | const X: i32 = { let 0 = 0; 0 };
-   |                      ^ pattern `_` not covered
+   |                      ^ pattern `-2147483648i32..=-1i32` not covered
 
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:18:23
    |
 LL | static Y: i32 = { let 0 = 0; 0 };
-   |                       ^ pattern `_` not covered
+   |                       ^ pattern `-2147483648i32..=-1i32` not covered
 
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:23:26
    |
 LL |     const X: i32 = { let 0 = 0; 0 };
-   |                          ^ pattern `_` not covered
+   |                          ^ pattern `-2147483648i32..=-1i32` not covered
 
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:29:26
    |
 LL |     const X: i32 = { let 0 = 0; 0 };
-   |                          ^ pattern `_` not covered
+   |                          ^ pattern `-2147483648i32..=-1i32` not covered
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/consts/const-pattern-irrefutable.rs b/src/test/ui/consts/const-pattern-irrefutable.rs
index af0b95e..278864d 100644
--- a/src/test/ui/consts/const-pattern-irrefutable.rs
+++ b/src/test/ui/consts/const-pattern-irrefutable.rs
@@ -19,8 +19,8 @@
 const a: u8 = 2;
 
 fn main() {
-    let a = 4; //~ ERROR refutable pattern in local binding: `_` not covered
-    let c = 4; //~ ERROR refutable pattern in local binding: `_` not covered
-    let d = 4; //~ ERROR refutable pattern in local binding: `_` not covered
+    let a = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
+    let c = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
+    let d = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
     fn f() {} // Check that the `NOTE`s still work with an item here (c.f. issue #35115).
 }
diff --git a/src/test/ui/consts/const-pattern-irrefutable.stderr b/src/test/ui/consts/const-pattern-irrefutable.stderr
index 6d5738f..d9ad16c 100644
--- a/src/test/ui/consts/const-pattern-irrefutable.stderr
+++ b/src/test/ui/consts/const-pattern-irrefutable.stderr
@@ -1,19 +1,19 @@
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `0u8..=1u8` not covered
   --> $DIR/const-pattern-irrefutable.rs:22:9
    |
-LL |     let a = 4; //~ ERROR refutable pattern in local binding: `_` not covered
+LL |     let a = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
    |         ^ interpreted as a constant pattern, not new variable
 
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `0u8..=1u8` not covered
   --> $DIR/const-pattern-irrefutable.rs:23:9
    |
-LL |     let c = 4; //~ ERROR refutable pattern in local binding: `_` not covered
+LL |     let c = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
    |         ^ interpreted as a constant pattern, not new variable
 
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `0u8..=1u8` not covered
   --> $DIR/const-pattern-irrefutable.rs:24:9
    |
-LL |     let d = 4; //~ ERROR refutable pattern in local binding: `_` not covered
+LL |     let d = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
    |         ^ interpreted as a constant pattern, not new variable
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/consts/issue-56164.rs b/src/test/ui/consts/issue-56164.rs
new file mode 100644
index 0000000..9d1a8b5
--- /dev/null
+++ b/src/test/ui/consts/issue-56164.rs
@@ -0,0 +1,13 @@
+#![feature(const_fn)]
+
+const fn foo() { (||{})() }
+//~^ ERROR calls in constant functions are limited to constant functions, tuple structs and tuple
+// variants
+
+const fn bad(input: fn()) {
+    input()
+    //~^ ERROR function pointers are not allowed in const fn
+}
+
+fn main() {
+}
diff --git a/src/test/ui/consts/issue-56164.stderr b/src/test/ui/consts/issue-56164.stderr
new file mode 100644
index 0000000..d3e9ce3
--- /dev/null
+++ b/src/test/ui/consts/issue-56164.stderr
@@ -0,0 +1,15 @@
+error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/issue-56164.rs:3:18
+   |
+LL | const fn foo() { (||{})() }
+   |                  ^^^^^^^^
+
+error: function pointers are not allowed in const fn
+  --> $DIR/issue-56164.rs:8:5
+   |
+LL |     input()
+   |     ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs
index 0dba3a7..43ca9e7 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs
@@ -78,9 +78,9 @@
 const fn i32_ops3(c: i32, d: i32) -> bool { c != d }
 const fn i32_ops4(c: i32, d: i32) -> i32 { c + d }
 const fn char_cast(u: u8) -> char { u as char }
-const unsafe fn foo4() -> i32 { 42 }
-const unsafe fn foo5<T>() -> *const T { 0 as *const T }
-const unsafe fn foo6<T>() -> *mut T { 0 as *mut T }
+const unsafe fn ret_i32_no_unsafe() -> i32 { 42 }
+const unsafe fn ret_null_ptr_no_unsafe<T>() -> *const T { 0 as *const T }
+const unsafe fn ret_null_mut_ptr_no_unsafe<T>() -> *mut T { 0 as *mut T }
 
 // not ok
 const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs
index 67332c6..f11b43d 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs
@@ -8,23 +8,27 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// gate-test-min_const_unsafe_fn
+
 // ok
-const unsafe fn foo4() -> i32 { 42 }
-const unsafe fn foo5<T>() -> *const T { 0 as *const T }
-const unsafe fn foo6<T>() -> *mut T { 0 as *mut T }
+const unsafe fn ret_i32_no_unsafe() -> i32 { 42 }
+const unsafe fn ret_null_ptr_no_unsafe<T>() -> *const T { 0 as *const T }
+const unsafe fn ret_null_mut_ptr_no_unsafe<T>() -> *mut T { 0 as *mut T }
 const fn no_unsafe() { unsafe {} }
 
 // not ok
-const fn foo8() -> i32 {
-    unsafe { foo4() } //~ ERROR unsafe operations are not allowed in const fn
+const fn call_unsafe_const_fn() -> i32 {
+    unsafe { ret_i32_no_unsafe() } //~ ERROR calls to `const unsafe fn` in const fns are unstable
 }
-const fn foo9() -> *const String {
-    unsafe { foo5::<String>() } //~ ERROR unsafe operations are not allowed in const fn
+const fn call_unsafe_generic_const_fn() -> *const String {
+    unsafe { ret_null_ptr_no_unsafe::<String>() }
+    //~^ ERROR calls to `const unsafe fn` in const fns are unstable
 }
-const fn foo10() -> *const Vec<std::cell::Cell<u32>> {
-    unsafe { foo6::<Vec<std::cell::Cell<u32>>>() } //~ ERROR not allowed in const fn
+const fn call_unsafe_generic_cell_const_fn() -> *const Vec<std::cell::Cell<u32>> {
+    unsafe { ret_null_mut_ptr_no_unsafe::<Vec<std::cell::Cell<u32>>>() }
+    //~^ ERROR calls to `const unsafe fn` in const fns
 }
-const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
+const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
 //~^ dereferencing raw pointers in constant functions
 
 fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr
index 8cff0d4..922a788 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr
@@ -1,58 +1,60 @@
 error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
-  --> $DIR/min_const_fn_unsafe.rs:27:51
+  --> $DIR/min_const_fn_unsafe.rs:31:59
    |
-LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
-   |                                                   ^^
+LL | const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
+   |                                                           ^^
    |
    = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
 
 error[E0658]: unions in const fn are unstable (see issue #51909)
-  --> $DIR/min_const_fn_unsafe.rs:34:5
+  --> $DIR/min_const_fn_unsafe.rs:38:5
    |
 LL |     Foo { x: () }.y //~ ERROR not allowed in const fn
    |     ^^^^^^^^^^^^^^^
    |
    = help: add #![feature(const_fn_union)] to the crate attributes to enable
 
-error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
-  --> $DIR/min_const_fn_unsafe.rs:19:14
+error[E0658]: calls to `const unsafe fn` in const fns are unstable (see issue #55607)
+  --> $DIR/min_const_fn_unsafe.rs:21:14
    |
-LL |     unsafe { foo4() } //~ ERROR unsafe operations are not allowed in const fn
-   |              ^^^^^^ call to unsafe function
+LL |     unsafe { ret_i32_no_unsafe() } //~ ERROR calls to `const unsafe fn` in const fns are unstable
+   |              ^^^^^^^^^^^^^^^^^^^
    |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
+   = help: add #![feature(min_const_unsafe_fn)] to the crate attributes to enable
 
-error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
-  --> $DIR/min_const_fn_unsafe.rs:22:14
+error[E0658]: calls to `const unsafe fn` in const fns are unstable (see issue #55607)
+  --> $DIR/min_const_fn_unsafe.rs:24:14
    |
-LL |     unsafe { foo5::<String>() } //~ ERROR unsafe operations are not allowed in const fn
-   |              ^^^^^^^^^^^^^^^^ call to unsafe function
+LL |     unsafe { ret_null_ptr_no_unsafe::<String>() }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
+   = help: add #![feature(min_const_unsafe_fn)] to the crate attributes to enable
 
-error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
-  --> $DIR/min_const_fn_unsafe.rs:25:14
+error[E0658]: calls to `const unsafe fn` in const fns are unstable (see issue #55607)
+  --> $DIR/min_const_fn_unsafe.rs:28:14
    |
-LL |     unsafe { foo6::<Vec<std::cell::Cell<u32>>>() } //~ ERROR not allowed in const fn
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+LL |     unsafe { ret_null_mut_ptr_no_unsafe::<Vec<std::cell::Cell<u32>>>() }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
+   = help: add #![feature(min_const_unsafe_fn)] to the crate attributes to enable
 
 error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
-  --> $DIR/min_const_fn_unsafe.rs:27:51
+  --> $DIR/min_const_fn_unsafe.rs:31:59
    |
-LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
-   |                                                   ^^ dereference of raw pointer
+LL | const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
+   |                                                           ^^ dereference of raw pointer
    |
    = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+   = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
 
 error: access to union field is unsafe and unsafe operations are not allowed in const fn
-  --> $DIR/min_const_fn_unsafe.rs:34:5
+  --> $DIR/min_const_fn_unsafe.rs:38:5
    |
 LL |     Foo { x: () }.y //~ ERROR not allowed in const fn
    |     ^^^^^^^^^^^^^^^ access to union field
    |
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+   = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.rs
new file mode 100644
index 0000000..8a6884b
--- /dev/null
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.rs
@@ -0,0 +1,62 @@
+// 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(min_const_unsafe_fn)]
+
+// ok
+const unsafe fn foo4() -> i32 { 42 }
+const unsafe fn foo5<T>() -> *const T { 0 as *const T }
+const unsafe fn foo6<T>() -> *mut T { 0 as *mut T }
+const fn no_unsafe() { unsafe {} }
+
+const fn foo8() -> i32 {
+    unsafe { foo4() }
+}
+const fn foo9() -> *const String {
+    unsafe { foo5::<String>() }
+}
+const fn foo10() -> *const Vec<std::cell::Cell<u32>> {
+    unsafe { foo6::<Vec<std::cell::Cell<u32>>>() }
+}
+const unsafe fn foo8_3() -> i32 {
+    unsafe { foo4() }
+}
+const unsafe fn foo9_3() -> *const String {
+    unsafe { foo5::<String>() }
+}
+const unsafe fn foo10_3() -> *const Vec<std::cell::Cell<u32>> {
+    unsafe { foo6::<Vec<std::cell::Cell<u32>>>() }
+}
+// not ok
+const unsafe fn foo8_2() -> i32 {
+    foo4() //~ ERROR not allowed in const fn
+}
+const unsafe fn foo9_2() -> *const String {
+    foo5::<String>() //~ ERROR not allowed in const fn
+}
+const unsafe fn foo10_2() -> *const Vec<std::cell::Cell<u32>> {
+    foo6::<Vec<std::cell::Cell<u32>>>() //~ ERROR not allowed in const fn
+}
+const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
+//~^ dereferencing raw pointers in constant functions
+
+const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x } //~ ERROR not allowed in const fn
+//~^ dereferencing raw pointers in constant functions
+
+const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ ERROR not allowed
+//~^ dereferencing raw pointers in constant functions
+
+fn main() {}
+
+const unsafe fn no_union() {
+    union Foo { x: (), y: () }
+    Foo { x: () }.y //~ ERROR not allowed in const fn
+    //~^ unions in const fn
+}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.stderr
new file mode 100644
index 0000000..20c75af
--- /dev/null
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.stderr
@@ -0,0 +1,97 @@
+error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:47:51
+   |
+LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
+   |                                                   ^^
+   |
+   = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
+
+error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:50:60
+   |
+LL | const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x } //~ ERROR not allowed in const fn
+   |                                                            ^^^
+   |
+   = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
+
+error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:53:62
+   |
+LL | const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ ERROR not allowed
+   |                                                              ^^^
+   |
+   = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
+
+error[E0658]: unions in const fn are unstable (see issue #51909)
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:60:5
+   |
+LL |     Foo { x: () }.y //~ ERROR not allowed in const fn
+   |     ^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn_union)] to the crate attributes to enable
+
+error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:39:5
+   |
+LL |     foo4() //~ ERROR not allowed in const fn
+   |     ^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+   = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
+
+error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:42:5
+   |
+LL |     foo5::<String>() //~ ERROR not allowed in const fn
+   |     ^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+   = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
+
+error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:45:5
+   |
+LL |     foo6::<Vec<std::cell::Cell<u32>>>() //~ ERROR not allowed in const fn
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+   = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
+
+error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:47:51
+   |
+LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x } //~ ERROR not allowed in const fn
+   |                                                   ^^ dereference of raw pointer
+   |
+   = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+   = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
+
+error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:50:60
+   |
+LL | const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x } //~ ERROR not allowed in const fn
+   |                                                            ^^^ dereference of raw pointer
+   |
+   = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+   = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
+
+error: dereference of raw pointer is unsafe and unsafe operations are not allowed in const fn
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:53:62
+   |
+LL | const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ ERROR not allowed
+   |                                                              ^^^ dereference of raw pointer
+   |
+   = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+
+error: access to union field is unsafe and unsafe operations are not allowed in const fn
+  --> $DIR/min_const_fn_unsafe_feature_gate.rs:60:5
+   |
+LL |     Foo { x: () }.y //~ ERROR not allowed in const fn
+   |     ^^^^^^^^^^^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+   = note: unsafe action within a `const unsafe fn` still require an `unsafe` block in contrast to regular `unsafe fn`.
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
new file mode 100644
index 0000000..f559c23
--- /dev/null
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.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.
+
+#![unstable(feature = "humans",
+            reason = "who ever let humans program computers,
+            we're apparently really bad at it",
+            issue = "0")]
+
+#![feature(rustc_const_unstable, const_fn, foo, foo2)]
+#![feature(min_const_unsafe_fn)]
+#![feature(staged_api)]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature="foo")]
+const unsafe fn foo() -> u32 { 42 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+// can't call non-min_const_fn
+const unsafe fn bar() -> u32 { unsafe { foo() } } //~ ERROR can only call other `min_const_fn`
+
+#[unstable(feature = "rust1", issue="0")]
+const unsafe fn foo2() -> u32 { 42 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+// can't call non-min_const_fn
+const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR can only call other `min_const_fn`
+
+#[stable(feature = "rust1", since = "1.0.0")]
+// conformity is required, even with `const_fn` feature gate
+const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` op
+
+// check whether this function cannot be called even with the feature gate active
+#[unstable(feature = "foo2", issue="0")]
+const unsafe fn foo2_gated() -> u32 { 42 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+// can't call non-min_const_fn
+const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } } //~ ERROR can only call other
+
+fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
new file mode 100644
index 0000000..37be288
--- /dev/null
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
@@ -0,0 +1,26 @@
+error: can only call other `min_const_fn` within a `min_const_fn`
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:26:41
+   |
+LL | const unsafe fn bar() -> u32 { unsafe { foo() } } //~ ERROR can only call other `min_const_fn`
+   |                                         ^^^^^
+
+error: can only call other `min_const_fn` within a `min_const_fn`
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:33:42
+   |
+LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR can only call other `min_const_fn`
+   |                                          ^^^^^^
+
+error: only int, `bool` and `char` operations are stable in const fn
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:37:33
+   |
+LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` op
+   |                                 ^^^^^^^^^^^^^
+
+error: can only call other `min_const_fn` within a `min_const_fn`
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:45:48
+   |
+LL | const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } } //~ ERROR can only call other
+   |                                                ^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs
new file mode 100644
index 0000000..131bc97
--- /dev/null
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.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.
+
+#![unstable(feature = "humans",
+            reason = "who ever let humans program computers,
+            we're apparently really bad at it",
+            issue = "0")]
+
+#![feature(rustc_const_unstable, const_fn, foo, foo2)]
+#![feature(min_const_unsafe_fn)]
+#![feature(staged_api)]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature="foo")]
+const fn foo() -> u32 { 42 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+// can't call non-min_const_fn
+const unsafe fn bar() -> u32 { foo() } //~ ERROR can only call other `min_const_fn`
+
+#[unstable(feature = "rust1", issue="0")]
+const fn foo2() -> u32 { 42 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+// can't call non-min_const_fn
+const unsafe fn bar2() -> u32 { foo2() } //~ ERROR can only call other `min_const_fn`
+
+// check whether this function cannot be called even with the feature gate active
+#[unstable(feature = "foo2", issue="0")]
+const fn foo2_gated() -> u32 { 42 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+// can't call non-min_const_fn
+const unsafe fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR can only call other `min_const_fn`
+
+fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr
new file mode 100644
index 0000000..0b58dc1
--- /dev/null
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr
@@ -0,0 +1,20 @@
+error: can only call other `min_const_fn` within a `min_const_fn`
+  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:26:32
+   |
+LL | const unsafe fn bar() -> u32 { foo() } //~ ERROR can only call other `min_const_fn`
+   |                                ^^^^^
+
+error: can only call other `min_const_fn` within a `min_const_fn`
+  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:33:33
+   |
+LL | const unsafe fn bar2() -> u32 { foo2() } //~ ERROR can only call other `min_const_fn`
+   |                                 ^^^^^^
+
+error: can only call other `min_const_fn` within a `min_const_fn`
+  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:41:39
+   |
+LL | const unsafe fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR can only call other `min_const_fn`
+   |                                       ^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs b/src/test/ui/custom-derive/auxiliary/plugin.rs
similarity index 98%
rename from src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs
rename to src/test/ui/custom-derive/auxiliary/plugin.rs
index 124bc05..921e2ce 100644
--- a/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs
+++ b/src/test/ui/custom-derive/auxiliary/plugin.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/custom-derive/derive-in-mod.rs b/src/test/ui/custom-derive/derive-in-mod.rs
similarity index 100%
rename from src/test/ui-fulldeps/custom-derive/derive-in-mod.rs
rename to src/test/ui/custom-derive/derive-in-mod.rs
diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs b/src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.rs
similarity index 91%
rename from src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs
rename to src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.rs
index b750a8b..ba072ba 100644
--- a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.rs
+++ b/src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.rs
@@ -1,5 +1,4 @@
 // aux-build:plugin.rs
-// ignore-stage1
 
 #[macro_use(WithHelper)]
 extern crate plugin;
diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr b/src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.stderr
similarity index 78%
rename from src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr
rename to src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.stderr
index d288d72..2c9d226 100644
--- a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr
+++ b/src/test/ui/custom-derive/helper-attr-blocked-by-import-ambig.stderr
@@ -1,16 +1,16 @@
 error[E0659]: `helper` is ambiguous (derive helper attribute vs any other name)
-  --> $DIR/helper-attr-blocked-by-import-ambig.rs:10:3
+  --> $DIR/helper-attr-blocked-by-import-ambig.rs:9:3
    |
 LL | #[helper] //~ ERROR `helper` is ambiguous
    |   ^^^^^^ ambiguous name
    |
 note: `helper` could refer to the derive helper attribute defined here
-  --> $DIR/helper-attr-blocked-by-import-ambig.rs:9:10
+  --> $DIR/helper-attr-blocked-by-import-ambig.rs:8:10
    |
 LL | #[derive(WithHelper)]
    |          ^^^^^^^^^^
 note: `helper` could also refer to the attribute macro imported here
-  --> $DIR/helper-attr-blocked-by-import-ambig.rs:7:5
+  --> $DIR/helper-attr-blocked-by-import-ambig.rs:6:5
    |
 LL | use plugin::helper;
    |     ^^^^^^^^^^^^^^
diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs b/src/test/ui/custom-derive/helper-attr-blocked-by-import.rs
similarity index 94%
rename from src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs
rename to src/test/ui/custom-derive/helper-attr-blocked-by-import.rs
index 03b774f..abbf014 100644
--- a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import.rs
+++ b/src/test/ui/custom-derive/helper-attr-blocked-by-import.rs
@@ -1,6 +1,5 @@
 // compile-pass
 // aux-build:plugin.rs
-// ignore-stage1
 
 #[macro_use(WithHelper)]
 extern crate plugin;
diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.rs b/src/test/ui/custom-derive/issue-36935.rs
similarity index 97%
rename from src/test/ui-fulldeps/custom-derive/issue-36935.rs
rename to src/test/ui/custom-derive/issue-36935.rs
index 5ec79a5..92c47eb 100644
--- a/src/test/ui-fulldeps/custom-derive/issue-36935.rs
+++ b/src/test/ui/custom-derive/issue-36935.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:plugin.rs
-// ignore-stage1
+
 
 #[macro_use] extern crate plugin;
 
diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr b/src/test/ui/custom-derive/issue-36935.stderr
similarity index 100%
rename from src/test/ui-fulldeps/custom-derive/issue-36935.stderr
rename to src/test/ui/custom-derive/issue-36935.stderr
diff --git a/src/test/ui/custom_test_frameworks/mismatch.rs b/src/test/ui/custom_test_frameworks/mismatch.rs
index 28753f1..ca5a6f7 100644
--- a/src/test/ui/custom_test_frameworks/mismatch.rs
+++ b/src/test/ui/custom_test_frameworks/mismatch.rs
@@ -17,3 +17,4 @@
 
 #[test]
 fn wrong_kind(){}
+//~^ ERROR trait bound `test::TestDescAndFn: example_runner::Testable` is not satisfied
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 20a94f7..7e7f21d 100644
--- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
@@ -1,4 +1,4 @@
-error[E0055]: reached the recursion limit while auto-dereferencing I
+error[E0055]: reached the recursion limit while auto-dereferencing `I`
   --> $DIR/recursion_limit_deref.rs:60:22
    |
 LL |     let x: &Bottom = &t; //~ ERROR mismatched types
diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr
index 9008127..2d46196 100644
--- a/src/test/ui/error-codes/E0004-2.stderr
+++ b/src/test/ui/error-codes/E0004-2.stderr
@@ -1,4 +1,4 @@
-error[E0004]: non-exhaustive patterns: type std::option::Option<i32> is non-empty
+error[E0004]: non-exhaustive patterns: type `std::option::Option<i32>` is non-empty
   --> $DIR/E0004-2.rs:14:11
    |
 LL |     match x { } //~ ERROR E0004
diff --git a/src/test/ui/error-codes/E0055.stderr b/src/test/ui/error-codes/E0055.stderr
index 9653f4e..dddbd92 100644
--- a/src/test/ui/error-codes/E0055.stderr
+++ b/src/test/ui/error-codes/E0055.stderr
@@ -1,4 +1,4 @@
-error[E0055]: reached the recursion limit while auto-dereferencing Foo
+error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/E0055.rs:21:13
    |
 LL |     ref_foo.foo();
diff --git a/src/test/ui/error-codes/E0161.ast.stderr b/src/test/ui/error-codes/E0161.ast.stderr
index 62e8676..9030195 100644
--- a/src/test/ui/error-codes/E0161.ast.stderr
+++ b/src/test/ui/error-codes/E0161.ast.stderr
@@ -1,7 +1,7 @@
 error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
   --> $DIR/E0161.rs:32:9
    |
-LL |     box *x; //~ ERROR E0161
+LL |     box *x;
    |         ^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0161.astul.stderr b/src/test/ui/error-codes/E0161.astul.stderr
index 79080fb..bfeab0c 100644
--- a/src/test/ui/error-codes/E0161.astul.stderr
+++ b/src/test/ui/error-codes/E0161.astul.stderr
@@ -1,7 +1,7 @@
 error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
   --> $DIR/E0161.rs:32:5
    |
-LL |     box *x; //~ ERROR E0161
+LL |     box *x;
    |     ^^^^^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0161.edition.stderr b/src/test/ui/error-codes/E0161.edition.stderr
index 62e8676..9030195 100644
--- a/src/test/ui/error-codes/E0161.edition.stderr
+++ b/src/test/ui/error-codes/E0161.edition.stderr
@@ -1,7 +1,7 @@
 error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
   --> $DIR/E0161.rs:32:9
    |
-LL |     box *x; //~ ERROR E0161
+LL |     box *x;
    |         ^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0161.editionul.stderr b/src/test/ui/error-codes/E0161.editionul.stderr
index 79080fb..bfeab0c 100644
--- a/src/test/ui/error-codes/E0161.editionul.stderr
+++ b/src/test/ui/error-codes/E0161.editionul.stderr
@@ -1,7 +1,7 @@
 error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
   --> $DIR/E0161.rs:32:5
    |
-LL |     box *x; //~ ERROR E0161
+LL |     box *x;
    |     ^^^^^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0161.nll.stderr b/src/test/ui/error-codes/E0161.nll.stderr
index 62e8676..9030195 100644
--- a/src/test/ui/error-codes/E0161.nll.stderr
+++ b/src/test/ui/error-codes/E0161.nll.stderr
@@ -1,7 +1,7 @@
 error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
   --> $DIR/E0161.rs:32:9
    |
-LL |     box *x; //~ ERROR E0161
+LL |     box *x;
    |         ^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0161.nllul.stderr b/src/test/ui/error-codes/E0161.nllul.stderr
index 79080fb..bfeab0c 100644
--- a/src/test/ui/error-codes/E0161.nllul.stderr
+++ b/src/test/ui/error-codes/E0161.nllul.stderr
@@ -1,7 +1,7 @@
 error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
   --> $DIR/E0161.rs:32:5
    |
-LL |     box *x; //~ ERROR E0161
+LL |     box *x;
    |     ^^^^^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0161.rs b/src/test/ui/error-codes/E0161.rs
index edc5a84..26742ff 100644
--- a/src/test/ui/error-codes/E0161.rs
+++ b/src/test/ui/error-codes/E0161.rs
@@ -29,7 +29,15 @@
 #![feature(box_syntax)]
 
 fn foo(x: Box<[i32]>) {
-    box *x; //~ ERROR E0161
+    box *x;
+    //[ast]~^ ERROR E0161
+    //[nll]~^^ ERROR E0161
+    //[zflags]~^^^ ERROR E0161
+    //[edition]~^^^^ ERROR E0161
+    //[astul]~^^^^^ ERROR E0161
+    //[nllul]~^^^^^^ ERROR E0161
+    //[zflagsul]~^^^^^^^ ERROR E0161
+    //[editionul]~^^^^^^^^ ERROR E0161
 }
 
 fn main() {}
diff --git a/src/test/ui/error-codes/E0161.zflags.stderr b/src/test/ui/error-codes/E0161.zflags.stderr
index 62e8676..9030195 100644
--- a/src/test/ui/error-codes/E0161.zflags.stderr
+++ b/src/test/ui/error-codes/E0161.zflags.stderr
@@ -1,7 +1,7 @@
 error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
   --> $DIR/E0161.rs:32:9
    |
-LL |     box *x; //~ ERROR E0161
+LL |     box *x;
    |         ^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0161.zflagsul.stderr b/src/test/ui/error-codes/E0161.zflagsul.stderr
index 79080fb..bfeab0c 100644
--- a/src/test/ui/error-codes/E0161.zflagsul.stderr
+++ b/src/test/ui/error-codes/E0161.zflagsul.stderr
@@ -1,7 +1,7 @@
 error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
   --> $DIR/E0161.rs:32:5
    |
-LL |     box *x; //~ ERROR E0161
+LL |     box *x;
    |     ^^^^^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0411.stderr b/src/test/ui/error-codes/E0411.stderr
index a5f2e3a..4e85f65 100644
--- a/src/test/ui/error-codes/E0411.stderr
+++ b/src/test/ui/error-codes/E0411.stderr
@@ -2,7 +2,7 @@
   --> $DIR/E0411.rs:12:6
    |
 LL |     <Self>::foo; //~ ERROR E0411
-   |      ^^^^ `Self` is only available in traits and impls
+   |      ^^^^ `Self` is only available in impls, traits, and type definitions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0718.rs b/src/test/ui/error-codes/E0718.rs
index ce74e35..7367819 100644
--- a/src/test/ui/error-codes/E0718.rs
+++ b/src/test/ui/error-codes/E0718.rs
@@ -11,7 +11,7 @@
 #![feature(lang_items)]
 
 // Arc is expected to be a struct, so this will error.
-#[lang = "arc"]
+#[lang = "arc"] //~ ERROR language item must be applied to a struct
 static X: u32 = 42;
 
 fn main() {}
diff --git a/src/test/ui/error-codes/E0718.stderr b/src/test/ui/error-codes/E0718.stderr
index 8ce721d..8544b07 100644
--- a/src/test/ui/error-codes/E0718.stderr
+++ b/src/test/ui/error-codes/E0718.stderr
@@ -1,7 +1,7 @@
 error[E0718]: `arc` language item must be applied to a struct
   --> $DIR/E0718.rs:14:1
    |
-LL | #[lang = "arc"]
+LL | #[lang = "arc"] //~ ERROR language item must be applied to a struct
    | ^^^^^^^^^^^^^^^ attribute should be applied to a struct, not a static item
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0719.rs b/src/test/ui/error-codes/E0719.rs
index c7bfa85..895f9e0 100644
--- a/src/test/ui/error-codes/E0719.rs
+++ b/src/test/ui/error-codes/E0719.rs
@@ -9,10 +9,12 @@
 // except according to those terms.
 
 trait Foo: Iterator<Item = i32, Item = i32> {}
+//~^ ERROR is already specified
 
 type Unit = ();
 
 fn test() -> Box<Iterator<Item = (), Item = Unit>> {
+//~^ ERROR is already specified
     Box::new(None.into_iter())
 }
 
diff --git a/src/test/ui/error-codes/E0719.stderr b/src/test/ui/error-codes/E0719.stderr
index 3a908fc..0666e1e 100644
--- a/src/test/ui/error-codes/E0719.stderr
+++ b/src/test/ui/error-codes/E0719.stderr
@@ -7,7 +7,7 @@
    |                     `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
-  --> $DIR/E0719.rs:15:38
+  --> $DIR/E0719.rs:16:38
    |
 LL | fn test() -> Box<Iterator<Item = (), Item = Unit>> {
    |                           ---------  ^^^^^^^^^^^ re-bound here
diff --git a/src/test/ui/exhaustive_integer_patterns.rs b/src/test/ui/exhaustive_integer_patterns.rs
index 7825aaa..020382d 100644
--- a/src/test/ui/exhaustive_integer_patterns.rs
+++ b/src/test/ui/exhaustive_integer_patterns.rs
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(exhaustive_integer_patterns)]
+#![feature(precise_pointer_size_matching)]
 #![feature(exclusive_range_pattern)]
+
 #![deny(unreachable_patterns)]
 
-use std::{char, usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128};
+use std::{char, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128};
 
 fn main() {
     let x: u8 = 0;
@@ -68,10 +69,6 @@
         '\u{E000}' ..= '\u{10_FFFF}' => {}
     }
 
-    match 0usize {
-        0 ..= usize::MAX => {} // ok
-    }
-
     match 0u16 {
         0 ..= u16::MAX => {} // ok
     }
@@ -88,10 +85,6 @@
         0 ..= u128::MAX => {} // ok
     }
 
-    match 0isize {
-        isize::MIN ..= isize::MAX => {} // ok
-    }
-
     match 0i8 {
         -128 ..= 127 => {} // ok
     }
diff --git a/src/test/ui/exhaustive_integer_patterns.stderr b/src/test/ui/exhaustive_integer_patterns.stderr
index 44b05a1..011e936 100644
--- a/src/test/ui/exhaustive_integer_patterns.stderr
+++ b/src/test/ui/exhaustive_integer_patterns.stderr
@@ -1,83 +1,83 @@
 error: unreachable pattern
-  --> $DIR/exhaustive_integer_patterns.rs:32:9
+  --> $DIR/exhaustive_integer_patterns.rs:33:9
    |
 LL |         200 => {} //~ ERROR unreachable pattern
    |         ^^^
    |
 note: lint level defined here
-  --> $DIR/exhaustive_integer_patterns.rs:13:9
+  --> $DIR/exhaustive_integer_patterns.rs:14:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:37:11
+  --> $DIR/exhaustive_integer_patterns.rs:38:11
    |
 LL |     match x { //~ ERROR non-exhaustive patterns
    |           ^ pattern `128u8..=255u8` not covered
 
 error[E0004]: non-exhaustive patterns: `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered
-  --> $DIR/exhaustive_integer_patterns.rs:42:11
+  --> $DIR/exhaustive_integer_patterns.rs:43:11
    |
 LL |     match x { //~ ERROR non-exhaustive patterns
    |           ^ patterns `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered
 
 error: unreachable pattern
-  --> $DIR/exhaustive_integer_patterns.rs:53:9
+  --> $DIR/exhaustive_integer_patterns.rs:54:9
    |
 LL |         -2..=20 => {} //~ ERROR unreachable pattern
    |         ^^^^^^^
 
 error[E0004]: non-exhaustive patterns: `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered
-  --> $DIR/exhaustive_integer_patterns.rs:50:11
+  --> $DIR/exhaustive_integer_patterns.rs:51:11
    |
 LL |     match x { //~ ERROR non-exhaustive patterns
    |           ^ patterns `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered
 
 error[E0004]: non-exhaustive patterns: `-128i8` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:99:11
+  --> $DIR/exhaustive_integer_patterns.rs:92:11
    |
 LL |     match 0i8 { //~ ERROR non-exhaustive patterns
    |           ^^^ pattern `-128i8` not covered
 
 error[E0004]: non-exhaustive patterns: `0i16` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:107:11
+  --> $DIR/exhaustive_integer_patterns.rs:100:11
    |
 LL |     match 0i16 { //~ ERROR non-exhaustive patterns
    |           ^^^^ pattern `0i16` not covered
 
 error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:125:11
+  --> $DIR/exhaustive_integer_patterns.rs:118:11
    |
 LL |     match 0u8 { //~ ERROR non-exhaustive patterns
    |           ^^^ pattern `128u8..=255u8` not covered
 
 error[E0004]: non-exhaustive patterns: `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:137:11
+  --> $DIR/exhaustive_integer_patterns.rs:130:11
    |
 LL |     match (0u8, Some(())) { //~ ERROR non-exhaustive patterns
    |           ^^^^^^^^^^^^^^^ patterns `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered
 
 error[E0004]: non-exhaustive patterns: `(126u8..=127u8, false)` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:142:11
+  --> $DIR/exhaustive_integer_patterns.rs:135:11
    |
 LL |     match (0u8, true) { //~ ERROR non-exhaustive patterns
    |           ^^^^^^^^^^^ pattern `(126u8..=127u8, false)` not covered
 
 error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211455u128` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:162:11
+  --> $DIR/exhaustive_integer_patterns.rs:155:11
    |
 LL |     match 0u128 { //~ ERROR non-exhaustive patterns
    |           ^^^^^ pattern `340282366920938463463374607431768211455u128` not covered
 
 error[E0004]: non-exhaustive patterns: `5u128..=340282366920938463463374607431768211455u128` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:166:11
+  --> $DIR/exhaustive_integer_patterns.rs:159:11
    |
 LL |     match 0u128 { //~ ERROR non-exhaustive patterns
    |           ^^^^^ pattern `5u128..=340282366920938463463374607431768211455u128` not covered
 
 error[E0004]: non-exhaustive patterns: `0u128..=3u128` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:170:11
+  --> $DIR/exhaustive_integer_patterns.rs:163:11
    |
 LL |     match 0u128 { //~ ERROR non-exhaustive patterns
    |           ^^^^^ pattern `0u128..=3u128` not covered
diff --git a/src/test/ui/existential_types/private_unused.rs b/src/test/ui/existential_types/private_unused.rs
new file mode 100644
index 0000000..736d812
--- /dev/null
+++ b/src/test/ui/existential_types/private_unused.rs
@@ -0,0 +1,13 @@
+// compile-pass
+
+#[deny(warnings)]
+
+enum Empty { }
+trait Bar<T> {}
+impl Bar<Empty> for () {}
+
+fn boo() -> impl Bar<Empty> {}
+
+fn main() {
+    boo();
+}
diff --git a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs b/src/test/ui/feature-gate-exhaustive_integer_patterns.rs
deleted file mode 100644
index 3aa1522..0000000
--- a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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 x: u8 = 0;
-    match x { //~ ERROR non-exhaustive patterns: `_` not covered
-        0 ..= 255 => {}
-    }
-}
diff --git a/src/test/ui/feature-gate-exhaustive_integer_patterns.stderr b/src/test/ui/feature-gate-exhaustive_integer_patterns.stderr
deleted file mode 100644
index 63d98f6..0000000
--- a/src/test/ui/feature-gate-exhaustive_integer_patterns.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0004]: non-exhaustive patterns: `_` not covered
-  --> $DIR/feature-gate-exhaustive_integer_patterns.rs:13:11
-   |
-LL |     match x { //~ ERROR non-exhaustive patterns: `_` not covered
-   |           ^ pattern `_` not covered
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/feature-gate-custom_test_frameworks.rs b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs
similarity index 100%
rename from src/test/ui/feature-gate-custom_test_frameworks.rs
rename to src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs
diff --git a/src/test/ui/feature-gate-custom_test_frameworks.stderr b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr
similarity index 100%
rename from src/test/ui/feature-gate-custom_test_frameworks.stderr
rename to src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr
diff --git a/src/test/ui/feature-gate-doc_cfg-cfg-rustdoc.rs b/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.rs
similarity index 100%
rename from src/test/ui/feature-gate-doc_cfg-cfg-rustdoc.rs
rename to src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.rs
diff --git a/src/test/ui/feature-gate-doc_cfg-cfg-rustdoc.stderr b/src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.stderr
similarity index 100%
rename from src/test/ui/feature-gate-doc_cfg-cfg-rustdoc.stderr
rename to src/test/ui/feature-gates/feature-gate-doc_cfg-cfg-rustdoc.stderr
diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_self.rs b/src/test/ui/feature-gates/feature-gate-extern_crate_self.rs
new file mode 100644
index 0000000..2161932
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-extern_crate_self.rs
@@ -0,0 +1,3 @@
+extern crate self as foo; //~ ERROR `extern crate self` is unstable
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_self.stderr b/src/test/ui/feature-gates/feature-gate-extern_crate_self.stderr
new file mode 100644
index 0000000..530015b
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-extern_crate_self.stderr
@@ -0,0 +1,11 @@
+error[E0658]: `extern crate self` is unstable (see issue #56409)
+  --> $DIR/feature-gate-extern_crate_self.rs:1:1
+   |
+LL | extern crate self as foo; //~ ERROR `extern crate self` is unstable
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(extern_crate_self)] 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-gates/feature-gate-impl_trait_in_bindings.rs b/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs
index 9c76719..34f2315 100644
--- a/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs
+++ b/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs
@@ -9,9 +9,13 @@
 // except according to those terms.
 
 const FOO: impl Copy = 42;
+//~^ ERROR `impl Trait` not allowed
 
 static BAR: impl Copy = 42;
+//~^ ERROR `impl Trait` not allowed
 
 fn main() {
     let foo = impl Copy = 42;
+//~^ ERROR expected expression, found keyword `impl`
+    let foo: impl Copy = 42;
 }
diff --git a/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr b/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr
index 82bc619..4582e36 100644
--- a/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr
+++ b/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr
@@ -1,5 +1,5 @@
 error: expected expression, found keyword `impl`
-  --> $DIR/feature-gate-impl_trait_in_bindings.rs:16:15
+  --> $DIR/feature-gate-impl_trait_in_bindings.rs:18:15
    |
 LL |     let foo = impl Copy = 42;
    |               ^^^^ expected expression
@@ -13,7 +13,7 @@
    = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/feature-gate-impl_trait_in_bindings.rs:13:13
+  --> $DIR/feature-gate-impl_trait_in_bindings.rs:14:13
    |
 LL | static BAR: impl Copy = 42;
    |             ^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-linker-flavor.rs b/src/test/ui/feature-gates/feature-gate-linker-flavor.rs
index 7111596..56ede01 100644
--- a/src/test/ui/feature-gates/feature-gate-linker-flavor.rs
+++ b/src/test/ui/feature-gates/feature-gate-linker-flavor.rs
@@ -14,6 +14,7 @@
 // book
 
 #[used]
+//~^ ERROR attribute must be applied to a `static` variable
 fn foo() {}
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs
new file mode 100644
index 0000000..1208552
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs
@@ -0,0 +1,14 @@
+#![feature(exclusive_range_pattern)]
+
+use std::usize::MAX;
+
+fn main() {
+    match 0usize { //~ERROR non-exhaustive patterns: `_` not covered
+        0..=MAX => {}
+    }
+
+    match 0isize { //~ERROR non-exhaustive patterns: `_` not covered
+        1..=20 => {}
+        -5..3 => {}
+    }
+}
diff --git a/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
new file mode 100644
index 0000000..5806f6f
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
@@ -0,0 +1,15 @@
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/feature-gate-precise_pointer_size_matching.rs:6:11
+   |
+LL |     match 0usize { //~ERROR non-exhaustive patterns: `_` not covered
+   |           ^^^^^^ pattern `_` not covered
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/feature-gate-precise_pointer_size_matching.rs:10:11
+   |
+LL |     match 0isize { //~ERROR non-exhaustive patterns: `_` not covered
+   |           ^^^^^^ pattern `_` not covered
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/feature-gates/feature-gate-self-struct-ctor.rs b/src/test/ui/feature-gates/feature-gate-self-struct-ctor.rs
deleted file mode 100644
index 98eab39..0000000
--- a/src/test/ui/feature-gates/feature-gate-self-struct-ctor.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-struct ST1(i32, i32);
-
-impl ST1 {
-    fn ctor() -> Self {
-        Self(1,2)
-        //~^ ERROR: `Self` struct constructors are unstable (see issue #51994) [E0658]
-    }
-}
-
-struct ST2;
-
-impl ST2 {
-    fn ctor() -> Self {
-        Self
-        //~^ ERROR: `Self` struct constructors are unstable (see issue #51994) [E0658]
-    }
-}
-
-fn main() {
-    let _ = ST1::ctor();
-    let _ = ST2::ctor();
-}
diff --git a/src/test/ui/feature-gates/feature-gate-self-struct-ctor.stderr b/src/test/ui/feature-gates/feature-gate-self-struct-ctor.stderr
deleted file mode 100644
index 6061a0d..0000000
--- a/src/test/ui/feature-gates/feature-gate-self-struct-ctor.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0658]: `Self` struct constructors are unstable (see issue #51994)
-  --> $DIR/feature-gate-self-struct-ctor.rs:5:9
-   |
-LL |         Self(1,2)
-   |         ^^^^
-   |
-   = help: add #![feature(self_struct_ctor)] to the crate attributes to enable
-
-error[E0658]: `Self` struct constructors are unstable (see issue #51994)
-  --> $DIR/feature-gate-self-struct-ctor.rs:14:9
-   |
-LL |         Self
-   |         ^^^^
-   |
-   = help: add #![feature(self_struct_ctor)] 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-gates/feature-gate-self_in_typedefs.rs b/src/test/ui/feature-gates/feature-gate-self_in_typedefs.rs
deleted file mode 100644
index 4b476a0..0000000
--- a/src/test/ui/feature-gates/feature-gate-self_in_typedefs.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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.
-
-enum StackList<'a, T: 'a> {
-    Nil,
-    Cons(T, &'a Self)
-    //~^ ERROR cannot find type `Self` in this scope
-    //~| `Self` is only available in traits and impls
-}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-self_in_typedefs.stderr b/src/test/ui/feature-gates/feature-gate-self_in_typedefs.stderr
deleted file mode 100644
index ab04953..0000000
--- a/src/test/ui/feature-gates/feature-gate-self_in_typedefs.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0411]: cannot find type `Self` in this scope
-  --> $DIR/feature-gate-self_in_typedefs.rs:13:17
-   |
-LL |     Cons(T, &'a Self)
-   |                 ^^^^ `Self` is only available in traits and impls
-   |
-   = help: add #![feature(self_in_typedefs)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0411`.
diff --git a/src/test/ui/feature-gates/feature-gate-trait-alias.rs b/src/test/ui/feature-gates/feature-gate-trait-alias.rs
index a2a183f..52e01c2 100644
--- a/src/test/ui/feature-gates/feature-gate-trait-alias.rs
+++ b/src/test/ui/feature-gates/feature-gate-trait-alias.rs
@@ -9,5 +9,6 @@
 // except according to those terms.
 
 trait Foo = Default;
+//~^ ERROR trait aliases are experimental
 
 fn main() {}
diff --git a/src/test/ui/feature-gate-underscore_const_names.rs b/src/test/ui/feature-gates/feature-gate-underscore_const_names.rs
similarity index 96%
rename from src/test/ui/feature-gate-underscore_const_names.rs
rename to src/test/ui/feature-gates/feature-gate-underscore_const_names.rs
index b283e28..fec0868 100644
--- a/src/test/ui/feature-gate-underscore_const_names.rs
+++ b/src/test/ui/feature-gates/feature-gate-underscore_const_names.rs
@@ -15,6 +15,7 @@
 impl Trt for Str {}
 
 const _ : () = {
+//~^ ERROR is unstable
     use std::marker::PhantomData;
     struct ImplementsTrait<T: Trt>(PhantomData<T>);
     let _ = ImplementsTrait::<Str>(PhantomData);
diff --git a/src/test/ui/feature-gate-underscore_const_names.stderr b/src/test/ui/feature-gates/feature-gate-underscore_const_names.stderr
similarity index 94%
rename from src/test/ui/feature-gate-underscore_const_names.stderr
rename to src/test/ui/feature-gates/feature-gate-underscore_const_names.stderr
index ab90ef8..694d2c1 100644
--- a/src/test/ui/feature-gate-underscore_const_names.stderr
+++ b/src/test/ui/feature-gates/feature-gate-underscore_const_names.stderr
@@ -2,6 +2,7 @@
   --> $DIR/feature-gate-underscore_const_names.rs:17:1
    |
 LL | / const _ : () = {
+LL | | //~^ ERROR is unstable
 LL | |     use std::marker::PhantomData;
 LL | |     struct ImplementsTrait<T: Trt>(PhantomData<T>);
 LL | |     let _ = ImplementsTrait::<Str>(PhantomData);
diff --git a/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr b/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr
index ec8937b..0631f2c3 100644
--- a/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr
+++ b/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr
@@ -25,11 +25,7 @@
    |     ^^^^^^ not an extern crate passed with `--extern`
    |
    = help: add #![feature(uniform_paths)] to the crate attributes to enable
-note: this import refers to the built-in attribute imported here
-  --> $DIR/feature-gate-uniform-paths.rs:21:5
-   |
-LL | use inline; //~ ERROR imports can only refer to extern crate names
-   |     ^^^^^^
+   = note: this import refers to a built-in attribute
 
 error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
   --> $DIR/feature-gate-uniform-paths.rs:23:5
@@ -38,11 +34,7 @@
    |     ^^^ not an extern crate passed with `--extern`
    |
    = help: add #![feature(uniform_paths)] to the crate attributes to enable
-note: this import refers to the struct imported here
-  --> $DIR/feature-gate-uniform-paths.rs:23:5
-   |
-LL | use Vec; //~ ERROR imports can only refer to extern crate names
-   |     ^^^
+   = note: this import refers to a struct from prelude
 
 error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
   --> $DIR/feature-gate-uniform-paths.rs:25:5
@@ -51,11 +43,7 @@
    |     ^^^ not an extern crate passed with `--extern`
    |
    = help: add #![feature(uniform_paths)] to the crate attributes to enable
-note: this import refers to the macro imported here
-  --> $DIR/feature-gate-uniform-paths.rs:25:5
-   |
-LL | use vec; //~ ERROR imports can only refer to extern crate names
-   |     ^^^
+   = note: this import refers to a macro from prelude
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/feature-gate-unsized_locals.rs b/src/test/ui/feature-gates/feature-gate-unsized_locals.rs
similarity index 100%
rename from src/test/ui/feature-gate-unsized_locals.rs
rename to src/test/ui/feature-gates/feature-gate-unsized_locals.rs
diff --git a/src/test/ui/feature-gate-unsized_locals.stderr b/src/test/ui/feature-gates/feature-gate-unsized_locals.stderr
similarity index 100%
rename from src/test/ui/feature-gate-unsized_locals.stderr
rename to src/test/ui/feature-gates/feature-gate-unsized_locals.stderr
diff --git a/src/test/ui/underscore_const_names_feature_gate.rs b/src/test/ui/feature-gates/underscore_const_names_feature_gate.rs
similarity index 92%
rename from src/test/ui/underscore_const_names_feature_gate.rs
rename to src/test/ui/feature-gates/underscore_const_names_feature_gate.rs
index b217403..b41e350 100644
--- a/src/test/ui/underscore_const_names_feature_gate.rs
+++ b/src/test/ui/feature-gates/underscore_const_names_feature_gate.rs
@@ -9,6 +9,5 @@
 // except according to those terms.
 
 const _: () = (); //~ ERROR is unstable
-static _: () = (); //~ ERROR is unstable
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/underscore_const_names_feature_gate.stderr b/src/test/ui/feature-gates/underscore_const_names_feature_gate.stderr
new file mode 100644
index 0000000..192cc25
--- /dev/null
+++ b/src/test/ui/feature-gates/underscore_const_names_feature_gate.stderr
@@ -0,0 +1,11 @@
+error[E0658]: naming constants with `_` is unstable (see issue #54912)
+  --> $DIR/underscore_const_names_feature_gate.rs:11:1
+   |
+LL | const _: () = (); //~ ERROR is unstable
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(underscore_const_names)] 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/for/for-loop-refutable-pattern-error-message.stderr b/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr
index b76c2ff..9b19fc8 100644
--- a/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr
+++ b/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in `for` loop binding: `&_` not covered
+error[E0005]: refutable pattern in `for` loop binding: `&-2147483648i32..=0i32` not covered
   --> $DIR/for-loop-refutable-pattern-error-message.rs:12:9
    |
 LL |     for &1 in [1].iter() {} //~ ERROR refutable pattern in `for` loop binding
-   |         ^^ pattern `&_` not covered
+   |         ^^ pattern `&-2147483648i32..=0i32` not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generator/generator-region-requirements.rs b/src/test/ui/generator/generator-region-requirements.rs
index 59e7841..2cda483 100644
--- a/src/test/ui/generator/generator-region-requirements.rs
+++ b/src/test/ui/generator/generator-region-requirements.rs
@@ -13,6 +13,8 @@
     loop {
         match unsafe { g.resume() } {
             GeneratorState::Complete(c) => return c,
+//[nll]~^ ERROR explicit lifetime required
+//[ast]~^^ ERROR explicit lifetime required
             GeneratorState::Yielded(_) => (),
         }
     }
diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr b/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr
index 8dabb3c..60163d7 100644
--- a/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr
+++ b/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr
@@ -7,7 +7,7 @@
    |                       - first borrow occurs due to use of `x` in generator
 ...
 LL |     println!("{}", x); //~ ERROR
-   |                    ^ borrow occurs here
+   |                    ^ second borrow occurs here
 LL |     b.resume();
    |     - first borrow later used here
 
diff --git a/src/test/ui/impl-trait/bindings-opaque.rs b/src/test/ui/impl-trait/bindings-opaque.rs
index 88b7a52..84a0f78 100644
--- a/src/test/ui/impl-trait/bindings-opaque.rs
+++ b/src/test/ui/impl-trait/bindings-opaque.rs
@@ -18,6 +18,9 @@
     let foo: impl Copy = 42;
 
     let _ = FOO.count_ones();
+//~^ ERROR no method
     let _ = BAR.count_ones();
+//~^ ERROR no method
     let _ = foo.count_ones();
+//~^ ERROR no method
 }
diff --git a/src/test/ui/impl-trait/bindings-opaque.stderr b/src/test/ui/impl-trait/bindings-opaque.stderr
index 00358ee..1f79149 100644
--- a/src/test/ui/impl-trait/bindings-opaque.stderr
+++ b/src/test/ui/impl-trait/bindings-opaque.stderr
@@ -5,13 +5,13 @@
    |                 ^^^^^^^^^^
 
 error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope
-  --> $DIR/bindings-opaque.rs:21:17
+  --> $DIR/bindings-opaque.rs:22:17
    |
 LL |     let _ = BAR.count_ones();
    |                 ^^^^^^^^^^
 
 error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope
-  --> $DIR/bindings-opaque.rs:22:17
+  --> $DIR/bindings-opaque.rs:24:17
    |
 LL |     let _ = foo.count_ones();
    |                 ^^^^^^^^^^
diff --git a/src/test/ui/impl-trait/bindings.rs b/src/test/ui/impl-trait/bindings.rs
index 571571a..0cca12f 100644
--- a/src/test/ui/impl-trait/bindings.rs
+++ b/src/test/ui/impl-trait/bindings.rs
@@ -12,23 +12,27 @@
 
 fn a<T: Clone>(x: T) {
     const foo: impl Clone = x;
+//~^ ERROR can't capture dynamic environment in a fn item
 }
 
 fn b<T: Clone>(x: T) {
     let _ = move || {
         const foo: impl Clone = x;
+//~^ ERROR can't capture dynamic environment in a fn item
     };
 }
 
 trait Foo<T: Clone> {
     fn a(x: T) {
         const foo: impl Clone = x;
+//~^ ERROR can't capture dynamic environment in a fn item
     }
 }
 
 impl<T: Clone> Foo<T> for i32 {
     fn a(x: T) {
         const foo: impl Clone = x;
+//~^ ERROR can't capture dynamic environment in a fn item
     }
 }
 
diff --git a/src/test/ui/impl-trait/bindings.stderr b/src/test/ui/impl-trait/bindings.stderr
index 70a736d2..91be86f 100644
--- a/src/test/ui/impl-trait/bindings.stderr
+++ b/src/test/ui/impl-trait/bindings.stderr
@@ -7,7 +7,7 @@
    = help: use the `|| { ... }` closure form instead
 
 error[E0434]: can't capture dynamic environment in a fn item
-  --> $DIR/bindings.rs:19:33
+  --> $DIR/bindings.rs:20:33
    |
 LL |         const foo: impl Clone = x;
    |                                 ^
@@ -15,7 +15,7 @@
    = help: use the `|| { ... }` closure form instead
 
 error[E0434]: can't capture dynamic environment in a fn item
-  --> $DIR/bindings.rs:25:33
+  --> $DIR/bindings.rs:27:33
    |
 LL |         const foo: impl Clone = x;
    |                                 ^
@@ -23,7 +23,7 @@
    = help: use the `|| { ... }` closure form instead
 
 error[E0434]: can't capture dynamic environment in a fn item
-  --> $DIR/bindings.rs:31:33
+  --> $DIR/bindings.rs:34:33
    |
 LL |         const foo: impl Clone = x;
    |                                 ^
diff --git a/src/test/ui/imports/extern-crate-self-fail.rs b/src/test/ui/imports/extern-crate-self-fail.rs
new file mode 100644
index 0000000..eab7b70
--- /dev/null
+++ b/src/test/ui/imports/extern-crate-self-fail.rs
@@ -0,0 +1,8 @@
+#![feature(extern_crate_self)]
+
+extern crate self; //~ ERROR `extern crate self;` requires renaming
+
+#[macro_use] //~ ERROR `macro_use` is not supported on `extern crate self`
+extern crate self as foo;
+
+fn main() {}
diff --git a/src/test/ui/imports/extern-crate-self-fail.stderr b/src/test/ui/imports/extern-crate-self-fail.stderr
new file mode 100644
index 0000000..0ca0d89
--- /dev/null
+++ b/src/test/ui/imports/extern-crate-self-fail.stderr
@@ -0,0 +1,14 @@
+error: `extern crate self;` requires renaming
+  --> $DIR/extern-crate-self-fail.rs:3:1
+   |
+LL | extern crate self; //~ ERROR `extern crate self;` requires renaming
+   | ^^^^^^^^^^^^^^^^^^ help: try: `extern crate self as name;`
+
+error: `macro_use` is not supported on `extern crate self`
+  --> $DIR/extern-crate-self-fail.rs:5:1
+   |
+LL | #[macro_use] //~ ERROR `macro_use` is not supported on `extern crate self`
+   | ^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/imports/extern-crate-self-pass.rs b/src/test/ui/imports/extern-crate-self-pass.rs
new file mode 100644
index 0000000..bf255bb
--- /dev/null
+++ b/src/test/ui/imports/extern-crate-self-pass.rs
@@ -0,0 +1,15 @@
+// compile-pass
+
+#![feature(extern_crate_self)]
+
+extern crate self as foo;
+
+struct S;
+
+mod m {
+    fn check() {
+        foo::S; // OK
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr
index b5e20ea..ef68ade 100644
--- a/src/test/ui/infinite/infinite-autoderef.stderr
+++ b/src/test/ui/infinite/infinite-autoderef.stderr
@@ -7,7 +7,7 @@
    |             cyclic type of infinite size
    |             help: try using a conversion method: `box x.to_string()`
 
-error[E0055]: reached the recursion limit while auto-dereferencing Foo
+error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/infinite-autoderef.rs:35:5
    |
 LL |     Foo.foo;
@@ -15,7 +15,7 @@
    |
    = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
 
-error[E0055]: reached the recursion limit while auto-dereferencing Foo
+error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/infinite-autoderef.rs:35:9
    |
 LL |     Foo.foo;
@@ -29,7 +29,7 @@
 LL |     Foo.foo;
    |         ^^^ unknown field
 
-error[E0055]: reached the recursion limit while auto-dereferencing Foo
+error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/infinite-autoderef.rs:36:9
    |
 LL |     Foo.bar();
diff --git a/src/test/ui/inhabitedness-infinite-loop.rs b/src/test/ui/inhabitedness-infinite-loop.rs
deleted file mode 100644
index d11aace..0000000
--- a/src/test/ui/inhabitedness-infinite-loop.rs
+++ /dev/null
@@ -1,26 +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.
-
-// error-pattern:reached recursion limit
-
-#![feature(never_type)]
-#![feature(exhaustive_patterns)]
-
-struct Foo<'a, T: 'a> {
-    ph: std::marker::PhantomData<T>,
-    foo: &'a Foo<'a, (T, T)>,
-}
-
-fn wub(f: Foo<!>) {
-    match f {}
-}
-
-fn main() {}
-
diff --git a/src/test/ui/inhabitedness-infinite-loop.stderr b/src/test/ui/inhabitedness-infinite-loop.stderr
deleted file mode 100644
index 24237f3..0000000
--- a/src/test/ui/inhabitedness-infinite-loop.stderr
+++ /dev/null
@@ -1,4 +0,0 @@
-error: reached recursion limit while checking inhabitedness of `Foo<'_, (((((((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))))), (((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))))), ((((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))))), (((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))))))), (((((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))))), (((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))))), ((((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))))), (((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))))))), ((((((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))))), (((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))))), ((((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))))), (((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))))))), (((((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))))), (((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))))), ((((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))))), (((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))), ((((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))))), (((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))), ((((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))))), (((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))), ((((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !))))), (((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))), ((((!, !), (!, !)), ((!, !), (!, !))), (((!, !), (!, !)), ((!, !), (!, !)))))))))))))))>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-17905-2.rs b/src/test/ui/issues/issue-17905-2.rs
index 7b4a40e..fb9e9e1 100644
--- a/src/test/ui/issues/issue-17905-2.rs
+++ b/src/test/ui/issues/issue-17905-2.rs
@@ -16,6 +16,8 @@
     isize
 > {
     fn say(self: &Pair<&str, isize>) {
+//~^ ERROR mismatched method receiver
+//~| ERROR mismatched method receiver
         println!("{:?}", self);
     }
 }
diff --git a/src/test/ui/issues/issue-17905-2.stderr b/src/test/ui/issues/issue-17905-2.stderr
index f6f23be..cf8b519 100644
--- a/src/test/ui/issues/issue-17905-2.stderr
+++ b/src/test/ui/issues/issue-17905-2.stderr
@@ -10,6 +10,8 @@
   --> $DIR/issue-17905-2.rs:18:5
    |
 LL | /     fn say(self: &Pair<&str, isize>) {
+LL | | //~^ ERROR mismatched method receiver
+LL | | //~| ERROR mismatched method receiver
 LL | |         println!("{:?}", self);
 LL | |     }
    | |_____^
@@ -36,6 +38,8 @@
   --> $DIR/issue-17905-2.rs:18:5
    |
 LL | /     fn say(self: &Pair<&str, isize>) {
+LL | | //~^ ERROR mismatched method receiver
+LL | | //~| ERROR mismatched method receiver
 LL | |         println!("{:?}", self);
 LL | |     }
    | |_____^
diff --git a/src/test/ui/issues/issue-22872.rs b/src/test/ui/issues/issue-22872.rs
index 7a83b09..a6130d2 100644
--- a/src/test/ui/issues/issue-22872.rs
+++ b/src/test/ui/issues/issue-22872.rs
@@ -18,6 +18,8 @@
 
 fn push_process<P>(process: P) where P: Process<'static> {
     let _: Box<for<'b> Wrap<'b>> = Box::new(Wrapper(process));
+//~^ ERROR is not an iterator
+//~| ERROR is not satisfied
 }
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-3096-1.stderr b/src/test/ui/issues/issue-3096-1.stderr
index b2bfe6b..f0782bd 100644
--- a/src/test/ui/issues/issue-3096-1.stderr
+++ b/src/test/ui/issues/issue-3096-1.stderr
@@ -1,4 +1,4 @@
-error[E0004]: non-exhaustive patterns: type () is non-empty
+error[E0004]: non-exhaustive patterns: type `()` is non-empty
   --> $DIR/issue-3096-1.rs:12:11
    |
 LL |     match () { } //~ ERROR non-exhaustive
diff --git a/src/test/ui/issues/issue-3096-2.stderr b/src/test/ui/issues/issue-3096-2.stderr
index bb9dfab..e0fa641 100644
--- a/src/test/ui/issues/issue-3096-2.stderr
+++ b/src/test/ui/issues/issue-3096-2.stderr
@@ -1,4 +1,4 @@
-error[E0004]: non-exhaustive patterns: type *const bottom is non-empty
+error[E0004]: non-exhaustive patterns: type `*const bottom` is non-empty
   --> $DIR/issue-3096-2.rs:15:11
    |
 LL |     match x { } //~ ERROR non-exhaustive patterns
diff --git a/src/test/ui/issues/issue-34229.rs b/src/test/ui/issues/issue-34229.rs
index bcdfcc7..13e627a 100644
--- a/src/test/ui/issues/issue-34229.rs
+++ b/src/test/ui/issues/issue-34229.rs
@@ -1,4 +1,5 @@
 #[derive(PartialEq)] struct Comparable;
 #[derive(PartialEq, PartialOrd)] struct Nope(Comparable);
+//~^ ERROR can't compare `Comparable`
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-36638.rs b/src/test/ui/issues/issue-36638.rs
index 5e43536..acb501c 100644
--- a/src/test/ui/issues/issue-36638.rs
+++ b/src/test/ui/issues/issue-36638.rs
@@ -12,6 +12,7 @@
 
 struct Foo<Self>(Self);
 //~^ ERROR expected identifier, found keyword `Self`
+//~^^ ERROR E0392
 
 trait Bar<Self> {}
 //~^ ERROR expected identifier, found keyword `Self`
diff --git a/src/test/ui/issues/issue-36638.stderr b/src/test/ui/issues/issue-36638.stderr
index d111fb4..155eb17 100644
--- a/src/test/ui/issues/issue-36638.stderr
+++ b/src/test/ui/issues/issue-36638.stderr
@@ -5,10 +5,19 @@
    |            ^^^^ expected identifier, found keyword
 
 error: expected identifier, found keyword `Self`
-  --> $DIR/issue-36638.rs:16:11
+  --> $DIR/issue-36638.rs:17:11
    |
 LL | trait Bar<Self> {}
    |           ^^^^ expected identifier, found keyword
 
-error: aborting due to 2 previous errors
+error[E0392]: parameter `Self` is never used
+  --> $DIR/issue-36638.rs:13:12
+   |
+LL | struct Foo<Self>(Self);
+   |            ^^^^ unused type parameter
+   |
+   = help: consider removing `Self` or using a marker such as `std::marker::PhantomData`
 
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0392`.
diff --git a/src/test/ui/issues/issue-38940.rs b/src/test/ui/issues/issue-38940.rs
index 7f9b141..1c78594 100644
--- a/src/test/ui/issues/issue-38940.rs
+++ b/src/test/ui/issues/issue-38940.rs
@@ -42,5 +42,5 @@
     let t = Top::new();
     let x: &Bottom = &t;
     //~^ ERROR mismatched types
-    //~| ERROR reached the recursion limit while auto-dereferencing I
+    //~| ERROR reached the recursion limit while auto-dereferencing `I`
 }
diff --git a/src/test/ui/issues/issue-38940.stderr b/src/test/ui/issues/issue-38940.stderr
index 2d3cfda..d94a710 100644
--- a/src/test/ui/issues/issue-38940.stderr
+++ b/src/test/ui/issues/issue-38940.stderr
@@ -1,4 +1,4 @@
-error[E0055]: reached the recursion limit while auto-dereferencing I
+error[E0055]: reached the recursion limit while auto-dereferencing `I`
   --> $DIR/issue-38940.rs:43:22
    |
 LL |     let x: &Bottom = &t;
diff --git a/src/test/ui/issues/issue-39175.rs b/src/test/ui/issues/issue-39175.rs
index efe59c3..ca912b2 100644
--- a/src/test/ui/issues/issue-39175.rs
+++ b/src/test/ui/issues/issue-39175.rs
@@ -22,4 +22,5 @@
 
 fn main() {
     Command::new("echo").arg("hello").exec();
+//~^ ERROR no method named `exec`
 }
diff --git a/src/test/ui/issues/issue-44402.rs b/src/test/ui/issues/issue-44402.rs
index f44f261..ecc5edb 100644
--- a/src/test/ui/issues/issue-44402.rs
+++ b/src/test/ui/issues/issue-44402.rs
@@ -33,7 +33,10 @@
 
 fn test_b() {
     let x: Option<Bar> = None;
-    match x { None => () }
+    match x {
+        Some(_) => (),
+        None => ()
+    }
 }
 
 fn main() { }
diff --git a/src/test/ui/issues/issue-45829/import-self.rs b/src/test/ui/issues/issue-45829/import-self.rs
index eb5fb45..c4da18a 100644
--- a/src/test/ui/issues/issue-45829/import-self.rs
+++ b/src/test/ui/issues/issue-45829/import-self.rs
@@ -14,12 +14,16 @@
 }
 
 use foo::{self};
+//~^ ERROR is defined multiple times
 
 use foo as self;
+//~^ ERROR expected identifier
 
 use foo::self;
+//~^ ERROR `self` imports are only allowed within a { } list
 
 use foo::A;
 use foo::{self as A};
+//~^ ERROR is defined multiple times
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-45829/import-self.stderr b/src/test/ui/issues/issue-45829/import-self.stderr
index 55e5195..4e8b708 100644
--- a/src/test/ui/issues/issue-45829/import-self.stderr
+++ b/src/test/ui/issues/issue-45829/import-self.stderr
@@ -1,11 +1,11 @@
 error: expected identifier, found keyword `self`
-  --> $DIR/import-self.rs:18:12
+  --> $DIR/import-self.rs:19:12
    |
 LL | use foo as self;
    |            ^^^^ expected identifier, found keyword
 
 error[E0429]: `self` imports are only allowed within a { } list
-  --> $DIR/import-self.rs:20:5
+  --> $DIR/import-self.rs:22:5
    |
 LL | use foo::self;
    |     ^^^^^^^^^
@@ -26,7 +26,7 @@
    |           ^^^^^^^^^^^^^^^^^
 
 error[E0252]: the name `A` is defined multiple times
-  --> $DIR/import-self.rs:23:11
+  --> $DIR/import-self.rs:26:11
    |
 LL | use foo::A;
    |     ------ previous import of the type `A` here
diff --git a/src/test/ui/issues/issue-45829/import-twice.rs b/src/test/ui/issues/issue-45829/import-twice.rs
index 785932e..0ba6ef3 100644
--- a/src/test/ui/issues/issue-45829/import-twice.rs
+++ b/src/test/ui/issues/issue-45829/import-twice.rs
@@ -14,5 +14,6 @@
 }
 
 use foo::{A, A};
+//~^ ERROR is defined multiple times
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-45829/issue-45829.rs b/src/test/ui/issues/issue-45829/issue-45829.rs
index eca4648..5135151 100644
--- a/src/test/ui/issues/issue-45829/issue-45829.rs
+++ b/src/test/ui/issues/issue-45829/issue-45829.rs
@@ -14,5 +14,6 @@
 }
 
 use foo::{A, B as A};
+//~^ ERROR is defined multiple times
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-45829/rename-extern-vs-use.rs b/src/test/ui/issues/issue-45829/rename-extern-vs-use.rs
index 6befee3..e6040e5 100644
--- a/src/test/ui/issues/issue-45829/rename-extern-vs-use.rs
+++ b/src/test/ui/issues/issue-45829/rename-extern-vs-use.rs
@@ -16,5 +16,6 @@
 
 use foo::bar;
 extern crate issue_45829_b as bar;
+//~^ ERROR the name `bar` is defined multiple times
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-45829/rename-extern-with-tab.rs b/src/test/ui/issues/issue-45829/rename-extern-with-tab.rs
index 61c7e91..08cbbd6 100644
--- a/src/test/ui/issues/issue-45829/rename-extern-with-tab.rs
+++ b/src/test/ui/issues/issue-45829/rename-extern-with-tab.rs
@@ -13,5 +13,6 @@
 
 extern crate issue_45829_a;
 extern  crate    issue_45829_b  as  issue_45829_a;
+//~^ ERROR is defined multiple times
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-45829/rename-extern.rs b/src/test/ui/issues/issue-45829/rename-extern.rs
index 41e3e8b..d4c323d 100644
--- a/src/test/ui/issues/issue-45829/rename-extern.rs
+++ b/src/test/ui/issues/issue-45829/rename-extern.rs
@@ -13,5 +13,6 @@
 
 extern crate issue_45829_a;
 extern crate issue_45829_b as issue_45829_a;
+//~^ ERROR is defined multiple times
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-45829/rename-use-vs-extern.rs b/src/test/ui/issues/issue-45829/rename-use-vs-extern.rs
index 9a2ec7a..5e131f0 100644
--- a/src/test/ui/issues/issue-45829/rename-use-vs-extern.rs
+++ b/src/test/ui/issues/issue-45829/rename-use-vs-extern.rs
@@ -12,5 +12,6 @@
 
 extern crate issue_45829_b;
 use std as issue_45829_b;
+//~^ ERROR is defined multiple times
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-45829/rename-use-with-tabs.rs b/src/test/ui/issues/issue-45829/rename-use-with-tabs.rs
index c1e4d90..84bf8ed 100644
--- a/src/test/ui/issues/issue-45829/rename-use-with-tabs.rs
+++ b/src/test/ui/issues/issue-45829/rename-use-with-tabs.rs
@@ -17,5 +17,6 @@
 }
 
 use foo::{A, bar::B    as    A};
+//~^ ERROR is defined multiple times
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-45829/rename-with-path.rs b/src/test/ui/issues/issue-45829/rename-with-path.rs
index dbe8733..5be9c84 100644
--- a/src/test/ui/issues/issue-45829/rename-with-path.rs
+++ b/src/test/ui/issues/issue-45829/rename-with-path.rs
@@ -9,5 +9,6 @@
 // except according to those terms.
 
 use std::{collections::HashMap as A, sync::Arc as A};
+//~^ ERROR is defined multiple times
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-45829/rename.rs b/src/test/ui/issues/issue-45829/rename.rs
index 7c6d87b..8e146d8 100644
--- a/src/test/ui/issues/issue-45829/rename.rs
+++ b/src/test/ui/issues/issue-45829/rename.rs
@@ -10,6 +10,7 @@
 
 use core;
 use std as core;
+//~^ ERROR is defined multiple times
 
 fn main() {
     1 + 1;
diff --git a/src/test/ui/issues/issue-49257.stderr b/src/test/ui/issues/issue-49257.stderr
index 4017983..644df1f 100644
--- a/src/test/ui/issues/issue-49257.stderr
+++ b/src/test/ui/issues/issue-49257.stderr
@@ -8,8 +8,8 @@
    |                 `..` must be at the end and cannot have a trailing comma
 help: move the `..` to the end of the field list
    |
-LL |     let Point {  y, .. } = p; //~ ERROR expected `}`, found `,`
-   |                --   ^^^^
+LL |     let Point { y, .. } = p; //~ ERROR expected `}`, found `,`
+   |                --  ^^^^
 
 error: expected `}`, found `,`
   --> $DIR/issue-49257.rs:21:19
@@ -21,8 +21,8 @@
    |                 `..` must be at the end and cannot have a trailing comma
 help: move the `..` to the end of the field list
    |
-LL |     let Point {  y , .. } = p; //~ ERROR expected `}`, found `,`
-   |                --  ^^^^^^
+LL |     let Point { y , .. } = p; //~ ERROR expected `}`, found `,`
+   |                -- ^^^^^^
 
 error: expected `}`, found `,`
   --> $DIR/issue-49257.rs:22:19
diff --git a/src/test/ui/issues/issue-51602.rs b/src/test/ui/issues/issue-51602.rs
index a3edecb..7826ce6 100644
--- a/src/test/ui/issues/issue-51602.rs
+++ b/src/test/ui/issues/issue-51602.rs
@@ -10,6 +10,7 @@
 
 fn main(){
     if i in 1..10 {
+//~^ ERROR expected `{`, found keyword `in`
         break;
     }
 }
diff --git a/src/test/ui/issues/issue-52717.rs b/src/test/ui/issues/issue-52717.rs
index d40e2bd..52397aa 100644
--- a/src/test/ui/issues/issue-52717.rs
+++ b/src/test/ui/issues/issue-52717.rs
@@ -17,5 +17,6 @@
   let x = A::A { foo: 3 };
   match x {
     A::A { fob } => { println!("{}", fob); }
+//~^ ERROR does not have a field named `fob`
   }
 }
diff --git a/src/test/ui/issues/issue-53565.rs b/src/test/ui/issues/issue-53565.rs
index 2bf3829..987c940 100644
--- a/src/test/ui/issues/issue-53565.rs
+++ b/src/test/ui/issues/issue-53565.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 use std::time::{foo, bar, buzz};
+//~^ ERROR unresolved imports
 use std::time::{abc, def};
+//~^ ERROR unresolved imports
 fn main(){
-   println!("Hello World!");
+    println!("Hello World!");
 }
diff --git a/src/test/ui/issues/issue-53565.stderr b/src/test/ui/issues/issue-53565.stderr
index 945f5ef..b18d694 100644
--- a/src/test/ui/issues/issue-53565.stderr
+++ b/src/test/ui/issues/issue-53565.stderr
@@ -8,7 +8,7 @@
    |                 no `foo` in `time`
 
 error[E0432]: unresolved imports `std::time::abc`, `std::time::def`
-  --> $DIR/issue-53565.rs:11:17
+  --> $DIR/issue-53565.rs:12:17
    |
 LL | use std::time::{abc, def};
    |                 ^^^  ^^^ no `def` in `time`
diff --git a/src/test/ui/issues/issue-53692.rs b/src/test/ui/issues/issue-53692.rs
index 0b6cc36..fb76620 100644
--- a/src/test/ui/issues/issue-53692.rs
+++ b/src/test/ui/issues/issue-53692.rs
@@ -11,12 +11,14 @@
         let items = vec![1, 2, 3];
         let ref_items: &[i32] = &items;
         let items_clone: Vec<i32> = ref_items.clone();
+//~^ ERROR mismatched types
 
         // in that case no suggestion will be triggered
         let items_clone_2:Vec<i32> = items.clone();
 
         let s = "hi";
         let string: String = s.clone();
+//~^ ERROR mismatched types
 
         // in that case no suggestion will be triggered
         let s2 = "hi";
diff --git a/src/test/ui/issues/issue-53692.stderr b/src/test/ui/issues/issue-53692.stderr
index 9cd8a53..ff4660d 100644
--- a/src/test/ui/issues/issue-53692.stderr
+++ b/src/test/ui/issues/issue-53692.stderr
@@ -11,7 +11,7 @@
               found type `&[i32]`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-53692.rs:19:30
+  --> $DIR/issue-53692.rs:20:30
    |
 LL |         let string: String = s.clone();
    |                              ^^^^^^^^^
diff --git a/src/test/ui/issues/issue-53840.rs b/src/test/ui/issues/issue-53840.rs
index ece3caf..e178007 100644
--- a/src/test/ui/issues/issue-53840.rs
+++ b/src/test/ui/issues/issue-53840.rs
@@ -20,8 +20,10 @@
     let bar = Bar { a: "1".to_string(), b: "2".to_string() };
     match E::Foo("".into(), "".into(), "".into()) {
         E::Foo(a, b, ref c) => {}
+//~^ ERROR cannot bind by-move and by-ref in the same pattern
     }
     match bar {
         Bar {a, ref b} => {}
+//~^ ERROR cannot bind by-move and by-ref in the same pattern
     }
 }
diff --git a/src/test/ui/issues/issue-53840.stderr b/src/test/ui/issues/issue-53840.stderr
index 961e4c0..599abe9 100644
--- a/src/test/ui/issues/issue-53840.stderr
+++ b/src/test/ui/issues/issue-53840.stderr
@@ -8,7 +8,7 @@
    |                by-move pattern here
 
 error[E0009]: cannot bind by-move and by-ref in the same pattern
-  --> $DIR/issue-53840.rs:25:14
+  --> $DIR/issue-53840.rs:26:14
    |
 LL |         Bar {a, ref b} => {}
    |              ^  ----- both by-ref and by-move used
diff --git a/src/test/ui/issues/issue-54348.rs b/src/test/ui/issues/issue-54348.rs
index b980290..68d8380 100644
--- a/src/test/ui/issues/issue-54348.rs
+++ b/src/test/ui/issues/issue-54348.rs
@@ -1,5 +1,5 @@
 fn main() {
     [1][0u64 as usize];
-    [1][1.5 as usize]; // ERROR index out of bounds
-    [1][1u64 as usize]; // ERROR index out of bounds
+    [1][1.5 as usize]; //~ ERROR index out of bounds
+    [1][1u64 as usize]; //~ ERROR index out of bounds
 }
diff --git a/src/test/ui/issues/issue-54348.stderr b/src/test/ui/issues/issue-54348.stderr
index a9f1b49..d4ee94a 100644
--- a/src/test/ui/issues/issue-54348.stderr
+++ b/src/test/ui/issues/issue-54348.stderr
@@ -1,7 +1,7 @@
 error: index out of bounds: the len is 1 but the index is 1
   --> $DIR/issue-54348.rs:3:5
    |
-LL |     [1][1.5 as usize]; // ERROR index out of bounds
+LL |     [1][1.5 as usize]; //~ ERROR index out of bounds
    |     ^^^^^^^^^^^^^^^^^
    |
    = note: #[deny(const_err)] on by default
@@ -9,7 +9,7 @@
 error: index out of bounds: the len is 1 but the index is 1
   --> $DIR/issue-54348.rs:4:5
    |
-LL |     [1][1u64 as usize]; // ERROR index out of bounds
+LL |     [1][1u64 as usize]; //~ ERROR index out of bounds
    |     ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-55796.rs b/src/test/ui/issues/issue-55796.rs
index b48d4a9..a172f6a 100644
--- a/src/test/ui/issues/issue-55796.rs
+++ b/src/test/ui/issues/issue-55796.rs
@@ -14,9 +14,11 @@
 
     fn out_neighbors(&'a self, u: &Self::Node) -> Box<Iterator<Item = Self::Node>> {
         Box::new(self.out_edges(u).map(|e| e.target()))
+//~^ ERROR cannot infer
     }
 
     fn in_neighbors(&'a self, u: &Self::Node) -> Box<Iterator<Item = Self::Node>> {
         Box::new(self.in_edges(u).map(|e| e.target()))
+//~^ ERROR cannot infer
     }
 }
diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr
index 60ce829..f8ca072 100644
--- a/src/test/ui/issues/issue-55796.stderr
+++ b/src/test/ui/issues/issue-55796.stderr
@@ -24,7 +24,7 @@
               found std::boxed::Box<dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node>>
 
 error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
-  --> $DIR/issue-55796.rs:20:9
+  --> $DIR/issue-55796.rs:21:9
    |
 LL |         Box::new(self.in_edges(u).map(|e| e.target()))
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -34,8 +34,8 @@
    |
 LL | pub trait Graph<'a> {
    |                 ^^
-note: ...so that the type `std::iter::Map<<Self as Graph<'a>>::EdgesIter, [closure@$DIR/issue-55796.rs:20:39: 20:53]>` will meet its required lifetime bounds
-  --> $DIR/issue-55796.rs:20:9
+note: ...so that the type `std::iter::Map<<Self as Graph<'a>>::EdgesIter, [closure@$DIR/issue-55796.rs:21:39: 21:53]>` will meet its required lifetime bounds
+  --> $DIR/issue-55796.rs:21:9
    |
 LL |         Box::new(self.in_edges(u).map(|e| e.target()))
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-56202.rs b/src/test/ui/issues/issue-56202.rs
new file mode 100644
index 0000000..bd222b7
--- /dev/null
+++ b/src/test/ui/issues/issue-56202.rs
@@ -0,0 +1,17 @@
+// compile-pass
+
+trait FooTrait {}
+
+trait BarTrait {
+    fn foo<T: FooTrait>(_: T) -> Self;
+}
+
+struct FooStruct(u32);
+
+impl BarTrait for FooStruct {
+    fn foo<T: FooTrait>(_: T) -> Self {
+        Self(u32::default())
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/iterators/array-of-ranges.rs b/src/test/ui/iterators/array-of-ranges.rs
index a7d6e80..d2dfc7e 100644
--- a/src/test/ui/iterators/array-of-ranges.rs
+++ b/src/test/ui/iterators/array-of-ranges.rs
@@ -1,14 +1,23 @@
 fn main() {
     for _ in [0..1] {}
+//~^ ERROR is not an iterator
     for _ in [0..=1] {}
+//~^ ERROR is not an iterator
     for _ in [0..] {}
+//~^ ERROR is not an iterator
     for _ in [..1] {}
+//~^ ERROR is not an iterator
     for _ in [..=1] {}
+//~^ ERROR is not an iterator
     let start = 0;
     let end = 0;
     for _ in [start..end] {}
+//~^ ERROR is not an iterator
     let array_of_range = [start..end];
     for _ in array_of_range {}
+//~^ ERROR is not an iterator
     for _ in [0..1, 2..3] {}
+//~^ ERROR is not an iterator
     for _ in [0..=1] {}
+//~^ ERROR is not an iterator
 }
diff --git a/src/test/ui/iterators/array-of-ranges.stderr b/src/test/ui/iterators/array-of-ranges.stderr
index fbe7e0e..4956597 100644
--- a/src/test/ui/iterators/array-of-ranges.stderr
+++ b/src/test/ui/iterators/array-of-ranges.stderr
@@ -9,7 +9,7 @@
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `[std::ops::RangeInclusive<{integer}>; 1]` is not an iterator
-  --> $DIR/array-of-ranges.rs:3:14
+  --> $DIR/array-of-ranges.rs:4:14
    |
 LL |     for _ in [0..=1] {}
    |              ^^^^^^^ if you meant to iterate between two values, remove the square brackets
@@ -19,7 +19,7 @@
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `[std::ops::RangeFrom<{integer}>; 1]` is not an iterator
-  --> $DIR/array-of-ranges.rs:4:14
+  --> $DIR/array-of-ranges.rs:6:14
    |
 LL |     for _ in [0..] {}
    |              ^^^^^ if you meant to iterate from a value onwards, remove the square brackets
@@ -29,7 +29,7 @@
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `[std::ops::RangeTo<{integer}>; 1]` is not an iterator
-  --> $DIR/array-of-ranges.rs:5:14
+  --> $DIR/array-of-ranges.rs:8:14
    |
 LL |     for _ in [..1] {}
    |              ^^^^^ if you meant to iterate until a value, remove the square brackets and add a starting value
@@ -39,7 +39,7 @@
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `[std::ops::RangeToInclusive<{integer}>; 1]` is not an iterator
-  --> $DIR/array-of-ranges.rs:6:14
+  --> $DIR/array-of-ranges.rs:10:14
    |
 LL |     for _ in [..=1] {}
    |              ^^^^^^ if you meant to iterate until a value (including it), remove the square brackets and add a starting value
@@ -49,7 +49,7 @@
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator
-  --> $DIR/array-of-ranges.rs:9:14
+  --> $DIR/array-of-ranges.rs:14:14
    |
 LL |     for _ in [start..end] {}
    |              ^^^^^^^^^^^^ if you meant to iterate between two values, remove the square brackets
@@ -59,7 +59,7 @@
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator
-  --> $DIR/array-of-ranges.rs:11:14
+  --> $DIR/array-of-ranges.rs:17:14
    |
 LL |     for _ in array_of_range {}
    |              ^^^^^^^^^^^^^^ if you meant to iterate between two values, remove the square brackets
@@ -69,7 +69,7 @@
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `[std::ops::Range<{integer}>; 2]` is not an iterator
-  --> $DIR/array-of-ranges.rs:12:14
+  --> $DIR/array-of-ranges.rs:19:14
    |
 LL |     for _ in [0..1, 2..3] {}
    |              ^^^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
@@ -79,7 +79,7 @@
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `[std::ops::RangeInclusive<{integer}>; 1]` is not an iterator
-  --> $DIR/array-of-ranges.rs:13:14
+  --> $DIR/array-of-ranges.rs:21:14
    |
 LL |     for _ in [0..=1] {}
    |              ^^^^^^^ if you meant to iterate between two values, remove the square brackets
diff --git a/src/test/ui/iterators/array.rs b/src/test/ui/iterators/array.rs
index f54bb81..33c84f6 100644
--- a/src/test/ui/iterators/array.rs
+++ b/src/test/ui/iterators/array.rs
@@ -1,6 +1,9 @@
 fn main() {
     for _ in [1, 2] {}
+//~^ ERROR is not an iterator
     let x = [1, 2];
     for _ in x {}
+//~^ ERROR is not an iterator
     for _ in [1.0, 2.0] {}
+//~^ ERROR is not an iterator
 }
diff --git a/src/test/ui/iterators/array.stderr b/src/test/ui/iterators/array.stderr
index fd74cd7..582c812 100644
--- a/src/test/ui/iterators/array.stderr
+++ b/src/test/ui/iterators/array.stderr
@@ -9,7 +9,7 @@
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `[{integer}; 2]` is not an iterator
-  --> $DIR/array.rs:4:14
+  --> $DIR/array.rs:5:14
    |
 LL |     for _ in x {}
    |              ^ borrow the array with `&` or call `.iter()` on it to iterate over it
@@ -19,7 +19,7 @@
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `[{float}; 2]` is not an iterator
-  --> $DIR/array.rs:5:14
+  --> $DIR/array.rs:7:14
    |
 LL |     for _ in [1.0, 2.0] {}
    |              ^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
diff --git a/src/test/ui/iterators/bound.rs b/src/test/ui/iterators/bound.rs
index 78285b8..bdd99ef 100644
--- a/src/test/ui/iterators/bound.rs
+++ b/src/test/ui/iterators/bound.rs
@@ -1,3 +1,4 @@
 struct S<I: Iterator>(I);
 struct T(S<u8>);
+//~^ ERROR is not an iterator
 fn main() {}
diff --git a/src/test/ui/keyword/keyword-self-as-identifier.rs b/src/test/ui/keyword/keyword-self-as-identifier.rs
index ad5b8fb..b50fc68 100644
--- a/src/test/ui/keyword/keyword-self-as-identifier.rs
+++ b/src/test/ui/keyword/keyword-self-as-identifier.rs
@@ -10,5 +10,4 @@
 
 fn main() {
     let Self = 22; //~ ERROR cannot find unit struct/variant or constant `Self` in this scope
-        //~^ ERROR `Self` struct constructors are unstable (see issue #51994)
 }
diff --git a/src/test/ui/keyword/keyword-self-as-identifier.stderr b/src/test/ui/keyword/keyword-self-as-identifier.stderr
index 2962698..c47f4ae 100644
--- a/src/test/ui/keyword/keyword-self-as-identifier.stderr
+++ b/src/test/ui/keyword/keyword-self-as-identifier.stderr
@@ -4,15 +4,6 @@
 LL |     let Self = 22; //~ ERROR cannot find unit struct/variant or constant `Self` in this scope
    |         ^^^^ not found in this scope
 
-error[E0658]: `Self` struct constructors are unstable (see issue #51994)
-  --> $DIR/keyword-self-as-identifier.rs:12:9
-   |
-LL |     let Self = 22; //~ ERROR cannot find unit struct/variant or constant `Self` in this scope
-   |         ^^^^
-   |
-   = help: add #![feature(self_struct_ctor)] to the crate attributes to enable
+error: aborting due to previous error
 
-error: aborting due to 2 previous errors
-
-Some errors occurred: E0531, E0658.
-For more information about an error, try `rustc --explain E0531`.
+For more information about this error, try `rustc --explain E0531`.
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs
index eb959bf..1c288a7 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs
@@ -6,6 +6,7 @@
 use std::error::Error;
 
 fn foo() -> impl Future<Item=(), Error=Box<Error>> {
+//~^ ERROR missing lifetime
     Ok(())
 }
 
diff --git a/src/test/ui/loud_ui.rs b/src/test/ui/loud_ui.rs
new file mode 100644
index 0000000..6a151fa
--- /dev/null
+++ b/src/test/ui/loud_ui.rs
@@ -0,0 +1,6 @@
+// should-fail
+
+// this test ensures that when we forget to use
+// any `//~ ERROR` comments whatsoever, that the test doesn't succeed
+
+fn main() {}
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs
deleted file mode 100644
index 63a4ef1..0000000
--- a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test behavior of `?` macro _kleene op_ under the 2015 edition. Namely, it doesn't exist, even
-// with the feature flag.
-
-// gate-test-macro_at_most_once_rep
-// edition:2015
-
-#![feature(macro_at_most_once_rep)]
-
-macro_rules! bar {
-    ($(a)?) => {} //~ERROR expected `*` or `+`
-}
-
-macro_rules! baz {
-    ($(a),?) => {} //~ERROR expected `*` or `+`
-}
-
-fn main() {}
-
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.stderr b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.stderr
deleted file mode 100644
index 5f68790..0000000
--- a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs:20:10
-   |
-LL |     ($(a)?) => {} //~ERROR expected `*` or `+`
-   |          ^
-   |
-   = note: `?` is not a macro repetition operator
-
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs:24:11
-   |
-LL |     ($(a),?) => {} //~ERROR expected `*` or `+`
-   |           ^
-   |
-   = note: `?` is not a macro repetition operator
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs
deleted file mode 100644
index ffabf9b..0000000
--- a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Feature gate test for macro_at_most_once_rep under 2018 edition.
-
-// gate-test-macro_at_most_once_rep
-// edition:2018
-
-macro_rules! foo {
-    ($(a)?) => {}
-    //~^ERROR using the `?` macro Kleene operator for
-    //~|ERROR expected `*` or `+`
-}
-
-macro_rules! baz {
-    ($(a),?) => {} //~ERROR expected `*` or `+`
-}
-
-macro_rules! barplus {
-    ($(a)?+) => {}
-    //~^ERROR using the `?` macro Kleene operator for
-    //~|ERROR expected `*` or `+`
-}
-
-macro_rules! barstar {
-    ($(a)?*) => {}
-    //~^ERROR using the `?` macro Kleene operator for
-    //~|ERROR expected `*` or `+`
-}
-
-pub fn main() {
-    foo!();
-    foo!(a);
-    foo!(a?); //~ ERROR no rules expected the token `?`
-    foo!(a?a); //~ ERROR no rules expected the token `?`
-    foo!(a?a?a); //~ ERROR no rules expected the token `?`
-}
-
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr
deleted file mode 100644
index 27dc03e..0000000
--- a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr
+++ /dev/null
@@ -1,80 +0,0 @@
-error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075)
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:17:10
-   |
-LL |     ($(a)?) => {}
-   |          ^
-   |
-   = help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable
-
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:17:10
-   |
-LL |     ($(a)?) => {}
-   |          ^
-
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:23:11
-   |
-LL |     ($(a),?) => {} //~ERROR expected `*` or `+`
-   |           ^
-   |
-   = note: `?` is not a macro repetition operator
-
-error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075)
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:27:10
-   |
-LL |     ($(a)?+) => {}
-   |          ^
-   |
-   = help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable
-
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:27:10
-   |
-LL |     ($(a)?+) => {}
-   |          ^
-
-error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075)
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:33:10
-   |
-LL |     ($(a)?*) => {}
-   |          ^
-   |
-   = help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable
-
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:33:10
-   |
-LL |     ($(a)?*) => {}
-   |          ^
-
-error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:41:11
-   |
-LL | macro_rules! foo {
-   | ---------------- when calling this macro
-...
-LL |     foo!(a?); //~ ERROR no rules expected the token `?`
-   |           ^ no rules expected this token in macro call
-
-error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:42:11
-   |
-LL | macro_rules! foo {
-   | ---------------- when calling this macro
-...
-LL |     foo!(a?a); //~ ERROR no rules expected the token `?`
-   |           ^ no rules expected this token in macro call
-
-error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:43:11
-   |
-LL | macro_rules! foo {
-   | ---------------- when calling this macro
-...
-LL |     foo!(a?a?a); //~ ERROR no rules expected the token `?`
-   |           ^ no rules expected this token in macro call
-
-error: aborting due to 10 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.rs b/src/test/ui/macros/macro-at-most-once-rep-2018.rs
index 5dabe8d..78bdf8f 100644
--- a/src/test/ui/macros/macro-at-most-once-rep-2018.rs
+++ b/src/test/ui/macros/macro-at-most-once-rep-2018.rs
@@ -12,22 +12,20 @@
 
 // edition:2018
 
-#![feature(macro_at_most_once_rep)]
-
 macro_rules! foo {
-    ($(a)?) => {}
+    ($(a)?) => {};
 }
 
 macro_rules! baz {
-    ($(a),?) => {} //~ERROR the `?` macro repetition operator
+    ($(a),?) => {}; //~ERROR the `?` macro repetition operator
 }
 
 macro_rules! barplus {
-    ($(a)?+) => {} // ok. matches "a+" and "+"
+    ($(a)?+) => {}; // ok. matches "a+" and "+"
 }
 
 macro_rules! barstar {
-    ($(a)?*) => {} // ok. matches "a*" and "*"
+    ($(a)?*) => {}; // ok. matches "a*" and "*"
 }
 
 pub fn main() {
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr
index d363b67..da76d1f 100644
--- a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr
+++ b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr
@@ -1,11 +1,11 @@
 error: the `?` macro repetition operator does not take a separator
-  --> $DIR/macro-at-most-once-rep-2018.rs:22:10
+  --> $DIR/macro-at-most-once-rep-2018.rs:20:10
    |
-LL |     ($(a),?) => {} //~ERROR the `?` macro repetition operator
+LL |     ($(a),?) => {}; //~ERROR the `?` macro repetition operator
    |          ^
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:36:11
+  --> $DIR/macro-at-most-once-rep-2018.rs:34:11
    |
 LL | macro_rules! foo {
    | ---------------- when calling this macro
@@ -14,7 +14,7 @@
    |           ^ no rules expected this token in macro call
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:37:11
+  --> $DIR/macro-at-most-once-rep-2018.rs:35:11
    |
 LL | macro_rules! foo {
    | ---------------- when calling this macro
@@ -23,7 +23,7 @@
    |           ^ no rules expected this token in macro call
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:38:11
+  --> $DIR/macro-at-most-once-rep-2018.rs:36:11
    |
 LL | macro_rules! foo {
    | ---------------- when calling this macro
@@ -32,7 +32,7 @@
    |           ^ no rules expected this token in macro call
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-2018.rs:40:5
+  --> $DIR/macro-at-most-once-rep-2018.rs:38:5
    |
 LL | macro_rules! barplus {
    | -------------------- when calling this macro
@@ -41,7 +41,7 @@
    |     ^^^^^^^^^^^ missing tokens in macro arguments
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-2018.rs:41:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:39:15
    |
 LL | macro_rules! barplus {
    | -------------------- when calling this macro
@@ -50,7 +50,7 @@
    |               ^ missing tokens in macro arguments
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:42:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:40:15
    |
 LL | macro_rules! barplus {
    | -------------------- when calling this macro
@@ -59,7 +59,7 @@
    |               ^ no rules expected this token in macro call
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:43:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:41:15
    |
 LL | macro_rules! barplus {
    | -------------------- when calling this macro
@@ -68,7 +68,7 @@
    |               ^ no rules expected this token in macro call
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-2018.rs:47:5
+  --> $DIR/macro-at-most-once-rep-2018.rs:45:5
    |
 LL | macro_rules! barstar {
    | -------------------- when calling this macro
@@ -77,7 +77,7 @@
    |     ^^^^^^^^^^^ missing tokens in macro arguments
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-2018.rs:48:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:46:15
    |
 LL | macro_rules! barstar {
    | -------------------- when calling this macro
@@ -86,7 +86,7 @@
    |               ^ missing tokens in macro arguments
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:49:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:47:15
    |
 LL | macro_rules! barstar {
    | -------------------- when calling this macro
@@ -95,7 +95,7 @@
    |               ^ no rules expected this token in macro call
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:50:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:48:15
    |
 LL | macro_rules! barstar {
    | -------------------- when calling this macro
diff --git a/src/test/ui/macros/macro-in-expression-context-2.rs b/src/test/ui/macros/macro-in-expression-context-2.rs
index cf8572a..9423f0a 100644
--- a/src/test/ui/macros/macro-in-expression-context-2.rs
+++ b/src/test/ui/macros/macro-in-expression-context-2.rs
@@ -3,5 +3,6 @@
 fn main() {
     match 42 {
         _ => { empty!() }
+//~^ ERROR macro expansion ends with an incomplete expression
     };
 }
diff --git a/src/test/ui/match/match-non-exhaustive.stderr b/src/test/ui/match/match-non-exhaustive.stderr
index 04f09ca..ad895b4 100644
--- a/src/test/ui/match/match-non-exhaustive.stderr
+++ b/src/test/ui/match/match-non-exhaustive.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `_` not covered
+error[E0004]: non-exhaustive patterns: `-2147483648i32..=0i32` and `2i32..=2147483647i32` not covered
   --> $DIR/match-non-exhaustive.rs:12:11
    |
 LL |     match 0 { 1 => () } //~ ERROR non-exhaustive patterns
-   |           ^ pattern `_` not covered
+   |           ^ patterns `-2147483648i32..=0i32` and `2i32..=2147483647i32` not covered
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/match-non-exhaustive.rs:13:11
diff --git a/src/test/ui/mismatched_types/numeric-literal-cast.rs b/src/test/ui/mismatched_types/numeric-literal-cast.rs
index 516b2e8..9b5f732 100644
--- a/src/test/ui/mismatched_types/numeric-literal-cast.rs
+++ b/src/test/ui/mismatched_types/numeric-literal-cast.rs
@@ -14,7 +14,10 @@
 
 fn main() {
     foo(1u8);
+//~^ ERROR mismatched types
     foo1(2f32);
+//~^ ERROR mismatched types
     foo2(3i16);
+//~^ ERROR mismatched types
 }
 
diff --git a/src/test/ui/mismatched_types/numeric-literal-cast.stderr b/src/test/ui/mismatched_types/numeric-literal-cast.stderr
index e2fe1a0..3aabbf5 100644
--- a/src/test/ui/mismatched_types/numeric-literal-cast.stderr
+++ b/src/test/ui/mismatched_types/numeric-literal-cast.stderr
@@ -9,7 +9,7 @@
    |         ^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-literal-cast.rs:17:10
+  --> $DIR/numeric-literal-cast.rs:18:10
    |
 LL |     foo1(2f32);
    |          ^^^^ expected f64, found f32
@@ -19,7 +19,7 @@
    |          ^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/numeric-literal-cast.rs:18:10
+  --> $DIR/numeric-literal-cast.rs:20:10
    |
 LL |     foo2(3i16);
    |          ^^^^ expected i32, found i16
diff --git a/src/test/ui/nll/closure-borrow-spans.stderr b/src/test/ui/nll/closure-borrow-spans.stderr
index 3e423da..98a2616 100644
--- a/src/test/ui/nll/closure-borrow-spans.stderr
+++ b/src/test/ui/nll/closure-borrow-spans.stderr
@@ -126,7 +126,7 @@
    |             |
    |             closure construction occurs here
 LL |     let y = &x; //~ ERROR
-   |             ^^ borrow occurs here
+   |             ^^ second borrow occurs here
 LL |     f.use_ref();
    |     - first borrow later used here
 
@@ -138,7 +138,7 @@
    |             |
    |             closure construction occurs here
 LL |     let y = &mut x; //~ ERROR
-   |             ^^^^^^ borrow occurs here
+   |             ^^^^^^ second borrow occurs here
 LL |     f.use_ref();
    |     - first borrow later used here
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.rs b/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.rs
new file mode 100644
index 0000000..dbc659b
--- /dev/null
+++ b/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.rs
@@ -0,0 +1,25 @@
+// Test that we propagate *all* requirements to the caller, not just the first
+// one.
+
+#![feature(nll)]
+
+fn once<S, T, U, F: FnOnce(S, T) -> U>(f: F, s: S, t: T) -> U {
+    f(s, t)
+}
+
+pub fn dangle() -> &'static [i32] {
+    let other_local_arr = [0, 2, 4];
+    let local_arr = other_local_arr;
+    let mut out: &mut &'static [i32] = &mut (&[1] as _);
+    once(|mut z: &[i32], mut out_val: &mut &[i32]| {
+        // We unfortunately point to the first use in the closure in the error
+        // message
+        z = &local_arr; //~ ERROR
+        *out_val = &local_arr;
+    }, &[] as &[_], &mut *out);
+    *out
+}
+
+fn main() {
+    println!("{:?}", dangle());
+}
diff --git a/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.stderr b/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.stderr
new file mode 100644
index 0000000..2ad4577
--- /dev/null
+++ b/src/test/ui/nll/closure-requirements/propagate-multiple-requirements.stderr
@@ -0,0 +1,17 @@
+error[E0597]: `local_arr` does not live long enough
+  --> $DIR/propagate-multiple-requirements.rs:17:14
+   |
+LL |     let mut out: &mut &'static [i32] = &mut (&[1] as _);
+   |                  ------------------- type annotation requires that `local_arr` is borrowed for `'static`
+LL |     once(|mut z: &[i32], mut out_val: &mut &[i32]| {
+   |          ----------------------------------------- value captured here
+...
+LL |         z = &local_arr; //~ ERROR
+   |              ^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+   | - `local_arr` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/nll/issue-52086.rs b/src/test/ui/nll/issue-52086.rs
index 248f4ba..6795678 100644
--- a/src/test/ui/nll/issue-52086.rs
+++ b/src/test/ui/nll/issue-52086.rs
@@ -18,7 +18,9 @@
 fn main() {
     let x = Rc::new(Bar { field: vec![] });
     drop(x.field);
+//~^ ERROR cannot move out of an `Rc`
 
     let y = Arc::new(Bar { field: vec![] });
     drop(y.field);
+//~^ ERROR cannot move out of an `Arc`
 }
diff --git a/src/test/ui/nll/issue-52086.stderr b/src/test/ui/nll/issue-52086.stderr
index 1455c49..1834b9b 100644
--- a/src/test/ui/nll/issue-52086.stderr
+++ b/src/test/ui/nll/issue-52086.stderr
@@ -5,7 +5,7 @@
    |          ^^^^^^^ cannot move out of an `Rc`
 
 error[E0507]: cannot move out of an `Arc`
-  --> $DIR/issue-52086.rs:23:10
+  --> $DIR/issue-52086.rs:24:10
    |
 LL |     drop(y.field);
    |          ^^^^^^^ cannot move out of an `Arc`
diff --git a/src/test/ui/nll/issue-52534-1.rs b/src/test/ui/nll/issue-52534-1.rs
index cd6c103..07f9cf7 100644
--- a/src/test/ui/nll/issue-52534-1.rs
+++ b/src/test/ui/nll/issue-52534-1.rs
@@ -17,37 +17,45 @@
     fn bar(&self, x: &u32) -> &u32 {
         let x = 22;
         &x
+//~^ ERROR cannot return reference to local variable
     }
 }
 
 fn foo(x: &u32) -> &u32 {
     let x = 22;
     &x
+//~^ ERROR cannot return reference to local variable
 }
 
 fn baz(x: &u32) -> &&u32 {
     let x = 22;
     &&x
+//~^ ERROR cannot return value referencing local variable
+//~| ERROR cannot return reference to temporary value
 }
 
 fn foobazbar<'a>(x: u32, y: &'a u32) -> &'a u32 {
     let x = 22;
     &x
+//~^ ERROR cannot return reference to local variable
 }
 
 fn foobar<'a>(x: &'a u32) -> &'a u32 {
     let x = 22;
     &x
+//~^ ERROR cannot return reference to local variable
 }
 
 fn foobaz<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
     let x = 22;
     &x
+//~^ ERROR cannot return reference to local variable
 }
 
 fn foobarbaz<'a, 'b>(x: &'a u32, y: &'b u32, z: &'a u32) -> &'a u32 {
     let x = 22;
     &x
+//~^ ERROR cannot return reference to local variable
 }
 
 fn main() { }
diff --git a/src/test/ui/nll/issue-52534-1.stderr b/src/test/ui/nll/issue-52534-1.stderr
index 44a3ef3..e6556cd 100644
--- a/src/test/ui/nll/issue-52534-1.stderr
+++ b/src/test/ui/nll/issue-52534-1.stderr
@@ -5,13 +5,13 @@
    |         ^^ returns a reference to data owned by the current function
 
 error[E0515]: cannot return reference to local variable `x`
-  --> $DIR/issue-52534-1.rs:25:5
+  --> $DIR/issue-52534-1.rs:26:5
    |
 LL |     &x
    |     ^^ returns a reference to data owned by the current function
 
 error[E0515]: cannot return value referencing local variable `x`
-  --> $DIR/issue-52534-1.rs:30:5
+  --> $DIR/issue-52534-1.rs:32:5
    |
 LL |     &&x
    |     ^--
@@ -20,7 +20,7 @@
    |     returns a value referencing data owned by the current function
 
 error[E0515]: cannot return reference to temporary value
-  --> $DIR/issue-52534-1.rs:30:5
+  --> $DIR/issue-52534-1.rs:32:5
    |
 LL |     &&x
    |     ^--
@@ -29,13 +29,7 @@
    |     returns a reference to data owned by the current function
 
 error[E0515]: cannot return reference to local variable `x`
-  --> $DIR/issue-52534-1.rs:35:5
-   |
-LL |     &x
-   |     ^^ returns a reference to data owned by the current function
-
-error[E0515]: cannot return reference to local variable `x`
-  --> $DIR/issue-52534-1.rs:40:5
+  --> $DIR/issue-52534-1.rs:39:5
    |
 LL |     &x
    |     ^^ returns a reference to data owned by the current function
@@ -47,7 +41,13 @@
    |     ^^ returns a reference to data owned by the current function
 
 error[E0515]: cannot return reference to local variable `x`
-  --> $DIR/issue-52534-1.rs:50:5
+  --> $DIR/issue-52534-1.rs:51:5
+   |
+LL |     &x
+   |     ^^ returns a reference to data owned by the current function
+
+error[E0515]: cannot return reference to local variable `x`
+  --> $DIR/issue-52534-1.rs:57:5
    |
 LL |     &x
    |     ^^ returns a reference to data owned by the current function
diff --git a/src/test/ui/nll/issue-52534-2.rs b/src/test/ui/nll/issue-52534-2.rs
index 4eac6fea..91f9302 100644
--- a/src/test/ui/nll/issue-52534-2.rs
+++ b/src/test/ui/nll/issue-52534-2.rs
@@ -17,6 +17,7 @@
     {
         let x = 32;
         y = &x
+//~^ ERROR does not live long enough
     }
 
     println!("{}", y);
diff --git a/src/test/ui/nll/issue-52534-2.stderr b/src/test/ui/nll/issue-52534-2.stderr
index 51cd7c7..8bc463f 100644
--- a/src/test/ui/nll/issue-52534-2.stderr
+++ b/src/test/ui/nll/issue-52534-2.stderr
@@ -3,6 +3,7 @@
    |
 LL |         y = &x
    |         ^^^^^^ borrowed value does not live long enough
+LL | //~^ ERROR does not live long enough
 LL |     }
    |     - `x` dropped here while still borrowed
 LL | 
diff --git a/src/test/ui/nll/issue-52534.rs b/src/test/ui/nll/issue-52534.rs
index 273c9b3..bf395a5 100644
--- a/src/test/ui/nll/issue-52534.rs
+++ b/src/test/ui/nll/issue-52534.rs
@@ -20,11 +20,13 @@
 fn bar() {
     let x = 22;
     foo(|a| &x)
+//~^ ERROR does not live long enough
 }
 
 fn foobar() {
     let y = 22;
     baz(|first, second| &y)
+//~^ ERROR does not live long enough
 }
 
 fn main() { }
diff --git a/src/test/ui/nll/issue-52534.stderr b/src/test/ui/nll/issue-52534.stderr
index 00d7254..7c3006b 100644
--- a/src/test/ui/nll/issue-52534.stderr
+++ b/src/test/ui/nll/issue-52534.stderr
@@ -5,6 +5,7 @@
    |          -   ^ `x` would have to be valid for `'0`...
    |          |
    |          has type `&'0 u32`
+LL | //~^ ERROR does not live long enough
 LL | }
    | - ...but `x` will be dropped here, when the function `bar` returns
    |
@@ -12,12 +13,13 @@
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch04-02-references-and-borrowing.html#dangling-references>
 
 error[E0597]: `y` does not live long enough
-  --> $DIR/issue-52534.rs:27:26
+  --> $DIR/issue-52534.rs:28:26
    |
 LL |     baz(|first, second| &y)
    |          -----           ^ `y` would have to be valid for `'0`...
    |          |
    |          has type `&'0 u32`
+LL | //~^ ERROR does not live long enough
 LL | }
    | - ...but `y` will be dropped here, when the function `foobar` returns
    |
diff --git a/src/test/ui/nll/issue-52669.rs b/src/test/ui/nll/issue-52669.rs
index 17a5999..7bf0c7b 100644
--- a/src/test/ui/nll/issue-52669.rs
+++ b/src/test/ui/nll/issue-52669.rs
@@ -23,6 +23,7 @@
     a.b = B;
     foo(a);
     a.b.clone()
+//~^ ERROR borrow of moved value
 }
 
 fn main() {}
diff --git a/src/test/ui/nll/issue-53040.rs b/src/test/ui/nll/issue-53040.rs
index 2b6e67b..a08e7ff 100644
--- a/src/test/ui/nll/issue-53040.rs
+++ b/src/test/ui/nll/issue-53040.rs
@@ -13,4 +13,5 @@
 fn main() {
     let mut v: Vec<()> = Vec::new();
     || &mut v;
+//~^ ERROR captured variable cannot escape `FnMut` closure body
 }
diff --git a/src/test/ui/nll/issue-53807.rs b/src/test/ui/nll/issue-53807.rs
index 791dee2..007e40e 100644
--- a/src/test/ui/nll/issue-53807.rs
+++ b/src/test/ui/nll/issue-53807.rs
@@ -10,8 +10,10 @@
 
 pub fn main(){
     let maybe = Some(vec![true, true]);
-     loop {
+    loop {
         if let Some(thing) = maybe {
+//~^ ERROR use of partially moved value
+//~| ERROR use of moved value
         }
     }
 }
diff --git a/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.nll.stderr b/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.nll.stderr
index c308562..8412cbd 100644
--- a/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.nll.stderr
+++ b/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.nll.stderr
@@ -6,7 +6,7 @@
    |             |               |
    |             |               borrowed value does not live long enough
    |             a temporary with access to the borrow is created here ...
-LL |         }
+...
 LL |     }
    |     - `_thing1` dropped here while still borrowed
 LL | 
diff --git a/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.rs b/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.rs
index 99eafe0..312e6dc 100644
--- a/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.rs
+++ b/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.rs
@@ -5,6 +5,7 @@
             let _thing2 = D("thing2");
             side_effects();
             D("other").next(&_thing1)
+//~^ ERROR does not live long enough
         }
     }
 
diff --git a/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr b/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr
index eeba7d6..8d23891 100644
--- a/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr
+++ b/src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr
@@ -3,7 +3,7 @@
    |
 LL |             D("other").next(&_thing1)
    |                              ^^^^^^^ borrowed value does not live long enough
-LL |         }
+...
 LL |     }
    |     - `_thing1` dropped here while still borrowed
 LL | 
diff --git a/src/test/ui/nll/issue-54556-niconii.nll.stderr b/src/test/ui/nll/issue-54556-niconii.nll.stderr
index 40cd04d..58239fe 100644
--- a/src/test/ui/nll/issue-54556-niconii.nll.stderr
+++ b/src/test/ui/nll/issue-54556-niconii.nll.stderr
@@ -1,7 +1,7 @@
 error[E0597]: `counter` does not live long enough
   --> $DIR/issue-54556-niconii.rs:22:20
    |
-LL |     if let Ok(_) = counter.lock() { }
+LL |     if let Ok(_) = counter.lock() { } //~ ERROR does not live long enough
    |                    ^^^^^^^-------
    |                    |
    |                    borrowed value does not live long enough
diff --git a/src/test/ui/nll/issue-54556-niconii.rs b/src/test/ui/nll/issue-54556-niconii.rs
index 49b063f..cae389e 100644
--- a/src/test/ui/nll/issue-54556-niconii.rs
+++ b/src/test/ui/nll/issue-54556-niconii.rs
@@ -19,7 +19,7 @@
 fn main() {
     let counter = Mutex;
 
-    if let Ok(_) = counter.lock() { }
+    if let Ok(_) = counter.lock() { } //~ ERROR does not live long enough
 
     // With this code as written, the dynamic semantics here implies
     // that `Mutex::drop` for `counter` runs *before*
diff --git a/src/test/ui/nll/issue-54556-niconii.stderr b/src/test/ui/nll/issue-54556-niconii.stderr
index 2d0de26..03a7b94 100644
--- a/src/test/ui/nll/issue-54556-niconii.stderr
+++ b/src/test/ui/nll/issue-54556-niconii.stderr
@@ -1,7 +1,7 @@
 error[E0597]: `counter` does not live long enough
   --> $DIR/issue-54556-niconii.rs:22:20
    |
-LL |     if let Ok(_) = counter.lock() { }
+LL |     if let Ok(_) = counter.lock() { } //~ ERROR does not live long enough
    |                    ^^^^^^^ borrowed value does not live long enough
 ...
 LL | }
diff --git a/src/test/ui/nll/issue-54556-stephaneyfx.nll.stderr b/src/test/ui/nll/issue-54556-stephaneyfx.nll.stderr
index 0bf7648..b584544 100644
--- a/src/test/ui/nll/issue-54556-stephaneyfx.nll.stderr
+++ b/src/test/ui/nll/issue-54556-stephaneyfx.nll.stderr
@@ -1,7 +1,7 @@
 error[E0597]: `stmt` does not live long enough
   --> $DIR/issue-54556-stephaneyfx.rs:27:21
    |
-LL |     let rows = Rows(&stmt);
+LL |     let rows = Rows(&stmt); //~ ERROR does not live long enough
    |                     ^^^^^ borrowed value does not live long enough
 LL |     rows.map(|row| row).next()
    |     ------------------- a temporary with access to the borrow is created here ...
diff --git a/src/test/ui/nll/issue-54556-stephaneyfx.rs b/src/test/ui/nll/issue-54556-stephaneyfx.rs
index 10a4e21..b758228 100644
--- a/src/test/ui/nll/issue-54556-stephaneyfx.rs
+++ b/src/test/ui/nll/issue-54556-stephaneyfx.rs
@@ -24,7 +24,7 @@
 
 fn get_names() -> Option<String> {
     let stmt = Statement;
-    let rows = Rows(&stmt);
+    let rows = Rows(&stmt); //~ ERROR does not live long enough
     rows.map(|row| row).next()
     // let x = rows.map(|row| row).next();
     // x
diff --git a/src/test/ui/nll/issue-54556-stephaneyfx.stderr b/src/test/ui/nll/issue-54556-stephaneyfx.stderr
index 4e581a5..bf3285a 100644
--- a/src/test/ui/nll/issue-54556-stephaneyfx.stderr
+++ b/src/test/ui/nll/issue-54556-stephaneyfx.stderr
@@ -1,7 +1,7 @@
 error[E0597]: `stmt` does not live long enough
   --> $DIR/issue-54556-stephaneyfx.rs:27:22
    |
-LL |     let rows = Rows(&stmt);
+LL |     let rows = Rows(&stmt); //~ ERROR does not live long enough
    |                      ^^^^ borrowed value does not live long enough
 ...
 LL | }
diff --git a/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.nll.stderr b/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.nll.stderr
index 513dca7..1bc4301 100644
--- a/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.nll.stderr
+++ b/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.nll.stderr
@@ -1,7 +1,7 @@
 error[E0597]: `_thing1` does not live long enough
   --> $DIR/issue-54556-temps-in-tail-diagnostic.rs:5:11
    |
-LL |         D(&_thing1).end()
+LL |         D(&_thing1).end() //~ ERROR does not live long enough
    |         --^^^^^^^^-
    |         | |
    |         | borrowed value does not live long enough
diff --git a/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.rs b/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.rs
index 63b0433..2935caa 100644
--- a/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.rs
+++ b/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.rs
@@ -2,7 +2,7 @@
     {
         let mut _thing1 = D(Box::new("thing1"));
         // D("other").next(&_thing1).end()
-        D(&_thing1).end()
+        D(&_thing1).end() //~ ERROR does not live long enough
     }
 
     ;
diff --git a/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr b/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr
index a74970f..ca636e7 100644
--- a/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr
+++ b/src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr
@@ -1,7 +1,7 @@
 error[E0597]: `_thing1` does not live long enough
   --> $DIR/issue-54556-temps-in-tail-diagnostic.rs:5:12
    |
-LL |         D(&_thing1).end()
+LL |         D(&_thing1).end() //~ ERROR does not live long enough
    |            ^^^^^^^ borrowed value does not live long enough
 LL |     }
    |     - `_thing1` dropped here while still borrowed
diff --git a/src/test/ui/nll/issue-54556-used-vs-unused-tails.nll.stderr b/src/test/ui/nll/issue-54556-used-vs-unused-tails.nll.stderr
index 9911fc9..52d0870 100644
--- a/src/test/ui/nll/issue-54556-used-vs-unused-tails.nll.stderr
+++ b/src/test/ui/nll/issue-54556-used-vs-unused-tails.nll.stderr
@@ -11,7 +11,7 @@
    = note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:12:55
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:13:55
    |
 LL |     {            { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }  } ; // suggest `;`
    |                                                     --^^^^-       -    - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
@@ -23,7 +23,7 @@
    = note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:14:55
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:16:55
    |
 LL |     {            { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }; }   // suggest `;`
    |                                                     --^^^^-       -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
@@ -35,7 +35,7 @@
    = note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:16:55
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:19:55
    |
 LL |     let _ =      { let mut _t1 = D(Box::new("t1")); D(&_t1).end()    } ; // suggest `;`
    |                                                     --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
@@ -47,7 +47,7 @@
    = note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:18:55
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:22:55
    |
 LL |     let _u =     { let mut _t1 = D(Box::new("t1")); D(&_t1).unit()   } ; // suggest `;`
    |                                                     --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
@@ -59,7 +59,7 @@
    = note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:20:55
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:25:55
    |
 LL |     let _x =     { let mut _t1 = D(Box::new("t1")); D(&_t1).end()    } ; // `let x = ...; x`
    |                                                     --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
@@ -71,7 +71,7 @@
    = note: The temporary is part of an expression at the end of a block. Consider forcing this temporary to be dropped sooner, before the block's local variables are dropped. For example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block.
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:24:55
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:30:55
    |
 LL |     _y =         { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // `let x = ...; x`
    |                                                     --^^^^-       - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
@@ -83,7 +83,7 @@
    = note: The temporary is part of an expression at the end of a block. Consider forcing this temporary to be dropped sooner, before the block's local variables are dropped. For example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block.
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:30:55
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:37:55
    |
 LL | fn f_local_ref() { let mut _t1 = D(Box::new("t1")); D(&_t1).unit()   }  // suggest `;`
    |                                                     --^^^^-          -
@@ -96,7 +96,7 @@
    = note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:32:55
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:40:55
    |
 LL | fn f() -> String { let mut _t1 = D(Box::new("t1")); D(&_t1).end()   }   // `let x = ...; x`
    |                                                     --^^^^-         -
diff --git a/src/test/ui/nll/issue-54556-used-vs-unused-tails.rs b/src/test/ui/nll/issue-54556-used-vs-unused-tails.rs
index 64e4f75..0d96767 100644
--- a/src/test/ui/nll/issue-54556-used-vs-unused-tails.rs
+++ b/src/test/ui/nll/issue-54556-used-vs-unused-tails.rs
@@ -8,29 +8,37 @@
 
 fn main() {
     {              let mut _t1 = D(Box::new("t1")); D(&_t1).end()    } ; // suggest `;`
+//~^ ERROR does not live long enough
 
     {            { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }  } ; // suggest `;`
+//~^ ERROR does not live long enough
 
     {            { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }; }   // suggest `;`
+//~^ ERROR does not live long enough
 
     let _ =      { let mut _t1 = D(Box::new("t1")); D(&_t1).end()    } ; // suggest `;`
+//~^ ERROR does not live long enough
 
     let _u =     { let mut _t1 = D(Box::new("t1")); D(&_t1).unit()   } ; // suggest `;`
+//~^ ERROR does not live long enough
 
     let _x =     { let mut _t1 = D(Box::new("t1")); D(&_t1).end()    } ; // `let x = ...; x`
+//~^ ERROR does not live long enough
     let _x =     { let mut _t1 = D(Box::new("t1")); let x = D(&_t1).end(); x } ; // no error
 
     let mut _y;
     _y =         { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // `let x = ...; x`
+//~^ ERROR does not live long enough
     _y =         { let mut _t1 = D(Box::new("t1")); let x = D(&_t1).end(); x } ; // no error
 }
 
 fn f_param_ref(_t1: D<Box<&'static str>>) {         D(&_t1).unit()   }  // no error
 
 fn f_local_ref() { let mut _t1 = D(Box::new("t1")); D(&_t1).unit()   }  // suggest `;`
+//~^ ERROR does not live long enough
 
 fn f() -> String { let mut _t1 = D(Box::new("t1")); D(&_t1).end()   }   // `let x = ...; x`
-
+//~^ ERROR does not live long enough
 
 #[derive(Debug)]
 struct D<T: std::fmt::Debug>(T);
diff --git a/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr b/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr
index c75707b..e9e4e51 100644
--- a/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr
+++ b/src/test/ui/nll/issue-54556-used-vs-unused-tails.stderr
@@ -8,7 +8,7 @@
    |                                                        borrowed value does not live long enough
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:12:56
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:13:56
    |
 LL |     {            { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }  } ; // suggest `;`
    |                                                        ^^^        -    - borrowed value needs to live until here
@@ -17,7 +17,7 @@
    |                                                        borrowed value does not live long enough
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:14:56
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:16:56
    |
 LL |     {            { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }; }   // suggest `;`
    |                                                        ^^^        -- borrowed value needs to live until here
@@ -26,7 +26,7 @@
    |                                                        borrowed value does not live long enough
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:16:56
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:19:56
    |
 LL |     let _ =      { let mut _t1 = D(Box::new("t1")); D(&_t1).end()    } ; // suggest `;`
    |                                                        ^^^           - - borrowed value needs to live until here
@@ -35,7 +35,7 @@
    |                                                        borrowed value does not live long enough
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:18:56
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:22:56
    |
 LL |     let _u =     { let mut _t1 = D(Box::new("t1")); D(&_t1).unit()   } ; // suggest `;`
    |                                                        ^^^           - - borrowed value needs to live until here
@@ -44,7 +44,7 @@
    |                                                        borrowed value does not live long enough
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:20:56
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:25:56
    |
 LL |     let _x =     { let mut _t1 = D(Box::new("t1")); D(&_t1).end()    } ; // `let x = ...; x`
    |                                                        ^^^           - - borrowed value needs to live until here
@@ -53,7 +53,7 @@
    |                                                        borrowed value does not live long enough
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:24:56
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:30:56
    |
 LL |     _y =         { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // `let x = ...; x`
    |                                                        ^^^        - - borrowed value needs to live until here
@@ -62,7 +62,7 @@
    |                                                        borrowed value does not live long enough
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:30:56
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:37:56
    |
 LL | fn f_local_ref() { let mut _t1 = D(Box::new("t1")); D(&_t1).unit()   }  // suggest `;`
    |                                                        ^^^           - `_t1` dropped here while still borrowed
@@ -72,7 +72,7 @@
    = note: values in a scope are dropped in the opposite order they are created
 
 error[E0597]: `_t1` does not live long enough
-  --> $DIR/issue-54556-used-vs-unused-tails.rs:32:56
+  --> $DIR/issue-54556-used-vs-unused-tails.rs:40:56
    |
 LL | fn f() -> String { let mut _t1 = D(Box::new("t1")); D(&_t1).end()   }   // `let x = ...; x`
    |                                                        ^^^          - `_t1` dropped here while still borrowed
diff --git a/src/test/ui/nll/issue-55394.rs b/src/test/ui/nll/issue-55394.rs
index 452fc88..e396864 100644
--- a/src/test/ui/nll/issue-55394.rs
+++ b/src/test/ui/nll/issue-55394.rs
@@ -18,7 +18,7 @@
 
 impl Foo<'_> {
     fn new(bar: &mut Bar) -> Self {
-        Foo { bar }
+        Foo { bar } //~ ERROR unsatisfied lifetime constraints
     }
 }
 
diff --git a/src/test/ui/nll/issue-55394.stderr b/src/test/ui/nll/issue-55394.stderr
index 284d7af..a194e08 100644
--- a/src/test/ui/nll/issue-55394.stderr
+++ b/src/test/ui/nll/issue-55394.stderr
@@ -5,7 +5,7 @@
    |                 -            ---- return type is Foo<'2>
    |                 |
    |                 let's call the lifetime of this reference `'1`
-LL |         Foo { bar }
+LL |         Foo { bar } //~ ERROR unsatisfied lifetime constraints
    |         ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
 
 error: aborting due to previous error
diff --git a/src/test/ui/nll/move-subpaths-moves-root.rs b/src/test/ui/nll/move-subpaths-moves-root.rs
index 7a4e518..ffa1171 100644
--- a/src/test/ui/nll/move-subpaths-moves-root.rs
+++ b/src/test/ui/nll/move-subpaths-moves-root.rs
@@ -13,5 +13,5 @@
 fn main() {
     let x = (vec![1, 2, 3], );
     drop(x.0);
-    drop(x);
+    drop(x); //~ ERROR use of moved value
 }
diff --git a/src/test/ui/nll/move-subpaths-moves-root.stderr b/src/test/ui/nll/move-subpaths-moves-root.stderr
index 76a1279..e9c1e7b 100644
--- a/src/test/ui/nll/move-subpaths-moves-root.stderr
+++ b/src/test/ui/nll/move-subpaths-moves-root.stderr
@@ -3,7 +3,7 @@
    |
 LL |     drop(x.0);
    |          --- value moved here
-LL |     drop(x);
+LL |     drop(x); //~ ERROR use of moved value
    |          ^ value used here after move
    |
    = note: move occurs because `x.0` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/nll/relate_tys/universe-violation.rs b/src/test/ui/nll/relate_tys/universe-violation.rs
index cc86c8d..d29f8f8 100644
--- a/src/test/ui/nll/relate_tys/universe-violation.rs
+++ b/src/test/ui/nll/relate_tys/universe-violation.rs
@@ -12,6 +12,6 @@
 
 fn main() {
     let a: fn(_) -> _ = make_it();
-    let b: fn(&u32) -> &u32 = a;
+    let b: fn(&u32) -> &u32 = a; //~ ERROR higher-ranked subtype error
     drop(a);
 }
diff --git a/src/test/ui/nll/relate_tys/universe-violation.stderr b/src/test/ui/nll/relate_tys/universe-violation.stderr
index 6dc7878..0a2e0ed 100644
--- a/src/test/ui/nll/relate_tys/universe-violation.stderr
+++ b/src/test/ui/nll/relate_tys/universe-violation.stderr
@@ -1,7 +1,7 @@
 error: higher-ranked subtype error
   --> $DIR/universe-violation.rs:15:31
    |
-LL |     let b: fn(&u32) -> &u32 = a;
+LL |     let b: fn(&u32) -> &u32 = a; //~ ERROR higher-ranked subtype error
    |                               ^
 
 error: aborting due to previous error
diff --git a/src/test/ui/nll/user-annotations/cast_static_lifetime.rs b/src/test/ui/nll/user-annotations/cast_static_lifetime.rs
index aa2cf85..2fd5989 100644
--- a/src/test/ui/nll/user-annotations/cast_static_lifetime.rs
+++ b/src/test/ui/nll/user-annotations/cast_static_lifetime.rs
@@ -13,5 +13,5 @@
 
 fn main() {
     let x = 22_u32;
-    let y: &u32 = (&x) as &'static u32;
+    let y: &u32 = (&x) as &'static u32; //~ ERROR `x` does not live long enough
 }
diff --git a/src/test/ui/nll/user-annotations/cast_static_lifetime.stderr b/src/test/ui/nll/user-annotations/cast_static_lifetime.stderr
index c664746..908d03b 100644
--- a/src/test/ui/nll/user-annotations/cast_static_lifetime.stderr
+++ b/src/test/ui/nll/user-annotations/cast_static_lifetime.stderr
@@ -1,7 +1,7 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/cast_static_lifetime.rs:16:19
    |
-LL |     let y: &u32 = (&x) as &'static u32;
+LL |     let y: &u32 = (&x) as &'static u32; //~ ERROR `x` does not live long enough
    |                   ^^^^----------------
    |                   |
    |                   borrowed value does not live long enough
diff --git a/src/test/ui/nll/user-annotations/issue-54124.rs b/src/test/ui/nll/user-annotations/issue-54124.rs
index 8cdd390..042ad02 100644
--- a/src/test/ui/nll/user-annotations/issue-54124.rs
+++ b/src/test/ui/nll/user-annotations/issue-54124.rs
@@ -1,7 +1,8 @@
 #![feature(nll)]
 
 fn test<'a>() {
-    let _:fn(&()) = |_:&'a ()| {};
+    let _:fn(&()) = |_:&'a ()| {}; //~ ERROR unsatisfied lifetime constraints
+    //~^ ERROR unsatisfied lifetime constraints
 }
 
 fn main() {
diff --git a/src/test/ui/nll/user-annotations/issue-54124.stderr b/src/test/ui/nll/user-annotations/issue-54124.stderr
index df5e4b0..5b5afaee 100644
--- a/src/test/ui/nll/user-annotations/issue-54124.stderr
+++ b/src/test/ui/nll/user-annotations/issue-54124.stderr
@@ -3,7 +3,7 @@
    |
 LL | fn test<'a>() {
    |         -- lifetime `'a` defined here
-LL |     let _:fn(&()) = |_:&'a ()| {};
+LL |     let _:fn(&()) = |_:&'a ()| {}; //~ ERROR unsatisfied lifetime constraints
    |                      ^ - let's call the lifetime of this reference `'1`
    |                      |
    |                      requires that `'1` must outlive `'a`
@@ -13,7 +13,7 @@
    |
 LL | fn test<'a>() {
    |         -- lifetime `'a` defined here
-LL |     let _:fn(&()) = |_:&'a ()| {};
+LL |     let _:fn(&()) = |_:&'a ()| {}; //~ ERROR unsatisfied lifetime constraints
    |                      ^ requires that `'a` must outlive `'static`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.rs b/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.rs
new file mode 100644
index 0000000..588fecb
--- /dev/null
+++ b/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.rs
@@ -0,0 +1,13 @@
+#![allow(illegal_floating_point_literal_pattern)]
+#![deny(unreachable_patterns)]
+
+fn main() {
+    match 0.0 {
+      0.0..=1.0 => {}
+      _ => {} // ok
+    }
+
+    match 0.0 { //~ ERROR non-exhaustive patterns
+      0.0..=1.0 => {}
+    }
+}
diff --git a/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr b/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr
new file mode 100644
index 0000000..2e285af
--- /dev/null
+++ b/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr
@@ -0,0 +1,9 @@
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/non-exhaustive-float-range-match.rs:10:11
+   |
+LL |     match 0.0 { //~ ERROR non-exhaustive patterns
+   |           ^^^ pattern `_` not covered
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/non-exhaustive/non-exhaustive-match.rs b/src/test/ui/non-exhaustive/non-exhaustive-match.rs
index 13b6242..99a0c5d 100644
--- a/src/test/ui/non-exhaustive/non-exhaustive-match.rs
+++ b/src/test/ui/non-exhaustive/non-exhaustive-match.rs
@@ -22,7 +22,8 @@
     match Some(10) { //~ ERROR non-exhaustive patterns: `Some(_)` not covered
       None => {}
     }
-    match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, _)` not covered
+    match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)`
+                      //  and `(_, _, 5i32..=2147483647i32)` not covered
       (_, _, 4) => {}
     }
     match (t::a, t::a) { //~ ERROR non-exhaustive patterns: `(a, a)` not covered
diff --git a/src/test/ui/non-exhaustive/non-exhaustive-match.stderr b/src/test/ui/non-exhaustive/non-exhaustive-match.stderr
index f48a0bc..d3703a4 100644
--- a/src/test/ui/non-exhaustive/non-exhaustive-match.stderr
+++ b/src/test/ui/non-exhaustive/non-exhaustive-match.stderr
@@ -16,32 +16,32 @@
 LL |     match Some(10) { //~ ERROR non-exhaustive patterns: `Some(_)` not covered
    |           ^^^^^^^^ pattern `Some(_)` not covered
 
-error[E0004]: non-exhaustive patterns: `(_, _, _)` not covered
+error[E0004]: non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered
   --> $DIR/non-exhaustive-match.rs:25:11
    |
-LL |     match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, _)` not covered
-   |           ^^^^^^^^^ pattern `(_, _, _)` not covered
+LL |     match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)`
+   |           ^^^^^^^^^ patterns `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered
 
 error[E0004]: non-exhaustive patterns: `(a, a)` not covered
-  --> $DIR/non-exhaustive-match.rs:28:11
+  --> $DIR/non-exhaustive-match.rs:29:11
    |
 LL |     match (t::a, t::a) { //~ ERROR non-exhaustive patterns: `(a, a)` not covered
    |           ^^^^^^^^^^^^ pattern `(a, a)` not covered
 
 error[E0004]: non-exhaustive patterns: `b` not covered
-  --> $DIR/non-exhaustive-match.rs:32:11
+  --> $DIR/non-exhaustive-match.rs:33:11
    |
 LL |     match t::a { //~ ERROR non-exhaustive patterns: `b` not covered
    |           ^^^^ pattern `b` not covered
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
-  --> $DIR/non-exhaustive-match.rs:43:11
+  --> $DIR/non-exhaustive-match.rs:44:11
    |
 LL |     match *vec { //~ ERROR non-exhaustive patterns: `[]` not covered
    |           ^^^^ pattern `[]` not covered
 
 error[E0004]: non-exhaustive patterns: `[_, _, _, _]` not covered
-  --> $DIR/non-exhaustive-match.rs:56:11
+  --> $DIR/non-exhaustive-match.rs:57:11
    |
 LL |     match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _]` not covered
    |           ^^^^ pattern `[_, _, _, _]` not covered
diff --git a/src/test/ui/panic-handler/panic-handler-wrong-location.rs b/src/test/ui/panic-handler/panic-handler-wrong-location.rs
index 04e0268..441a0d8 100644
--- a/src/test/ui/panic-handler/panic-handler-wrong-location.rs
+++ b/src/test/ui/panic-handler/panic-handler-wrong-location.rs
@@ -13,6 +13,6 @@
 #![no_std]
 #![no_main]
 
-#[panic_handler]
+#[panic_handler] //~ ERROR `panic_impl` language item must be applied to a function
 #[no_mangle]
 static X: u32 = 42;
diff --git a/src/test/ui/panic-handler/panic-handler-wrong-location.stderr b/src/test/ui/panic-handler/panic-handler-wrong-location.stderr
index f761e26..513c991 100644
--- a/src/test/ui/panic-handler/panic-handler-wrong-location.stderr
+++ b/src/test/ui/panic-handler/panic-handler-wrong-location.stderr
@@ -1,7 +1,7 @@
 error[E0718]: `panic_impl` language item must be applied to a function
   --> $DIR/panic-handler-wrong-location.rs:16:1
    |
-LL | #[panic_handler]
+LL | #[panic_handler] //~ ERROR `panic_impl` language item must be applied to a function
    | ^^^^^^^^^^^^^^^^ attribute should be applied to a function, not a static item
 
 error: `#[panic_handler]` function required, but not found
diff --git a/src/test/ui/parser/if-in-in.rs b/src/test/ui/parser/if-in-in.rs
index 735d571..7008863 100644
--- a/src/test/ui/parser/if-in-in.rs
+++ b/src/test/ui/parser/if-in-in.rs
@@ -1,7 +1,7 @@
 // compile-flags: -Z parse-only
 
 fn main() {
-    for i in in 1..2 {
+    for i in in 1..2 { //~ ERROR expected iterable, found keyword `in`
         println!("{}", i);
     }
 }
diff --git a/src/test/ui/parser/if-in-in.stderr b/src/test/ui/parser/if-in-in.stderr
index 65da252..d741c70 100644
--- a/src/test/ui/parser/if-in-in.stderr
+++ b/src/test/ui/parser/if-in-in.stderr
@@ -1,7 +1,7 @@
 error: expected iterable, found keyword `in`
   --> $DIR/if-in-in.rs:4:14
    |
-LL |     for i in in 1..2 {
+LL |     for i in in 1..2 { //~ ERROR expected iterable, found keyword `in`
    |           ---^^
    |           |
    |           help: remove the duplicated `in`
diff --git a/src/test/ui/parser/issue-14303-enum.stderr b/src/test/ui/parser/issue-14303-enum.stderr
index 7d546cb..622066a 100644
--- a/src/test/ui/parser/issue-14303-enum.stderr
+++ b/src/test/ui/parser/issue-14303-enum.stderr
@@ -3,6 +3,10 @@
    |
 LL | enum X<'a, T, 'b> {
    |               ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | enum X<'a, 'b, T> {
+   |            ^^^ --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-fn-def.stderr b/src/test/ui/parser/issue-14303-fn-def.stderr
index c7b57f3..630c9cb 100644
--- a/src/test/ui/parser/issue-14303-fn-def.stderr
+++ b/src/test/ui/parser/issue-14303-fn-def.stderr
@@ -3,6 +3,10 @@
    |
 LL | fn foo<'a, T, 'b>(x: &'a T) {}
    |               ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | fn foo<'a, 'b, T>(x: &'a T) {}
+   |            ^^^ --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-impl.stderr b/src/test/ui/parser/issue-14303-impl.stderr
index 0b7016e..2e3181d 100644
--- a/src/test/ui/parser/issue-14303-impl.stderr
+++ b/src/test/ui/parser/issue-14303-impl.stderr
@@ -3,6 +3,10 @@
    |
 LL | impl<'a, T, 'b> X {}
    |             ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | impl<'a, 'b, T> X {}
+   |          ^^^ --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-struct.stderr b/src/test/ui/parser/issue-14303-struct.stderr
index 4a4b678..c6b3312 100644
--- a/src/test/ui/parser/issue-14303-struct.stderr
+++ b/src/test/ui/parser/issue-14303-struct.stderr
@@ -3,6 +3,10 @@
    |
 LL | struct X<'a, T, 'b> {
    |                 ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct X<'a, 'b, T> {
+   |              ^^^ --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-trait.stderr b/src/test/ui/parser/issue-14303-trait.stderr
index ab5cc56..6d00f28 100644
--- a/src/test/ui/parser/issue-14303-trait.stderr
+++ b/src/test/ui/parser/issue-14303-trait.stderr
@@ -3,6 +3,10 @@
    |
 LL | trait Foo<'a, T, 'b> {}
    |                  ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | trait Foo<'a, 'b, T> {}
+   |               ^^^ --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/underscore_static.rs b/src/test/ui/parser/underscore_static.rs
new file mode 100644
index 0000000..e1a9a02
--- /dev/null
+++ b/src/test/ui/parser/underscore_static.rs
@@ -0,0 +1,3 @@
+// compile-flags: -Z parse-only
+
+static _: () = (); //~ ERROR expected identifier, found reserved identifier `_`
diff --git a/src/test/ui/parser/underscore_static.stderr b/src/test/ui/parser/underscore_static.stderr
new file mode 100644
index 0000000..1b766f7
--- /dev/null
+++ b/src/test/ui/parser/underscore_static.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found reserved identifier `_`
+  --> $DIR/underscore_static.rs:3:8
+   |
+LL | static _: () = (); //~ ERROR expected identifier, found reserved identifier `_`
+   |        ^ expected identifier, found reserved identifier
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pattern/slice-pattern-const-2.rs b/src/test/ui/pattern/slice-pattern-const-2.rs
new file mode 100644
index 0000000..6f9501d
--- /dev/null
+++ b/src/test/ui/pattern/slice-pattern-const-2.rs
@@ -0,0 +1,24 @@
+// compile-pass
+
+fn main() {
+    let s = &[0x00; 4][..]; //Slice of any value
+    const MAGIC_TEST: &[u32] = &[4, 5, 6, 7]; //Const slice to pattern match with
+    match s {
+        MAGIC_TEST => (),
+        [0x00, 0x00, 0x00, 0x00] => (),
+        [4, 5, 6, 7] => (), // this should warn
+        _ => (),
+    }
+    match s {
+        [0x00, 0x00, 0x00, 0x00] => (),
+        MAGIC_TEST => (),
+        [4, 5, 6, 7] => (), // this should warn
+        _ => (),
+    }
+    match s {
+        [0x00, 0x00, 0x00, 0x00] => (),
+        [4, 5, 6, 7] => (),
+        MAGIC_TEST => (), // this should warn
+        _ => (),
+    }
+}
diff --git a/src/test/ui/pattern/slice-pattern-const-3.rs b/src/test/ui/pattern/slice-pattern-const-3.rs
new file mode 100644
index 0000000..e7a30ce
--- /dev/null
+++ b/src/test/ui/pattern/slice-pattern-const-3.rs
@@ -0,0 +1,24 @@
+// compile-pass
+
+fn main() {
+    let s = &["0x00"; 4][..]; //Slice of any value
+    const MAGIC_TEST: &[&str] = &["4", "5", "6", "7"]; //Const slice to pattern match with
+    match s {
+        MAGIC_TEST => (),
+        ["0x00", "0x00", "0x00", "0x00"] => (),
+        ["4", "5", "6", "7"] => (), // this should warn
+        _ => (),
+    }
+    match s {
+        ["0x00", "0x00", "0x00", "0x00"] => (),
+        MAGIC_TEST => (),
+        ["4", "5", "6", "7"] => (), // this should warn
+        _ => (),
+    }
+    match s {
+        ["0x00", "0x00", "0x00", "0x00"] => (),
+        ["4", "5", "6", "7"] => (),
+        MAGIC_TEST => (), // this should warn
+        _ => (),
+    }
+}
diff --git a/src/test/ui/pattern/slice-pattern-const.rs b/src/test/ui/pattern/slice-pattern-const.rs
new file mode 100644
index 0000000..d353f6c
--- /dev/null
+++ b/src/test/ui/pattern/slice-pattern-const.rs
@@ -0,0 +1,24 @@
+//compile-pass
+
+fn main() {
+    let s = &[0x00; 4][..]; //Slice of any value
+    const MAGIC_TEST: &[u8] = b"TEST"; //Const slice to pattern match with
+    match s {
+        MAGIC_TEST => (),
+        [0x00, 0x00, 0x00, 0x00] => (),
+        [84, 69, 83, 84] => (), // this should warn
+        _ => (),
+    }
+    match s {
+        [0x00, 0x00, 0x00, 0x00] => (),
+        MAGIC_TEST => (),
+        [84, 69, 83, 84] => (), // this should warn
+        _ => (),
+    }
+    match s {
+        [0x00, 0x00, 0x00, 0x00] => (),
+        [84, 69, 83, 84] => (),
+        MAGIC_TEST => (), // this should warn
+        _ => (),
+    }
+}
diff --git a/src/test/ui/precise_pointer_size_matching.rs b/src/test/ui/precise_pointer_size_matching.rs
new file mode 100644
index 0000000..759b63b
--- /dev/null
+++ b/src/test/ui/precise_pointer_size_matching.rs
@@ -0,0 +1,33 @@
+// normalize-stderr-32bit: "-2147483648isize" -> "$$ISIZE_MIN"
+// normalize-stderr-64bit: "-9223372036854775808isize" -> "$$ISIZE_MIN"
+// normalize-stderr-32bit: "2147483647isize" -> "$$ISIZE_MAX"
+// normalize-stderr-64bit: "9223372036854775807isize" -> "$$ISIZE_MAX"
+// normalize-stderr-32bit: "4294967295usize" -> "$$USIZE_MAX"
+// normalize-stderr-64bit: "18446744073709551615usize" -> "$$USIZE_MAX"
+
+#![feature(precise_pointer_size_matching)]
+#![feature(exclusive_range_pattern)]
+
+#![deny(unreachable_patterns)]
+
+use std::{usize, isize};
+
+fn main() {
+    match 0isize {
+        isize::MIN ..= isize::MAX => {} // ok
+    }
+
+    match 0usize {
+        0 ..= usize::MAX => {} // ok
+    }
+
+    match 0isize { //~ ERROR non-exhaustive patterns
+        1 ..= 8 => {}
+        -5 ..= 20 => {}
+    }
+
+    match 0usize { //~ ERROR non-exhaustive patterns
+        1 ..= 8 => {}
+        5 ..= 20 => {}
+    }
+}
diff --git a/src/test/ui/precise_pointer_size_matching.stderr b/src/test/ui/precise_pointer_size_matching.stderr
new file mode 100644
index 0000000..4acbec6
--- /dev/null
+++ b/src/test/ui/precise_pointer_size_matching.stderr
@@ -0,0 +1,15 @@
+error[E0004]: non-exhaustive patterns: `$ISIZE_MIN..=-6isize` and `21isize..=$ISIZE_MAX` not covered
+  --> $DIR/precise_pointer_size_matching.rs:24:11
+   |
+LL |     match 0isize { //~ ERROR non-exhaustive patterns
+   |           ^^^^^^ patterns `$ISIZE_MIN..=-6isize` and `21isize..=$ISIZE_MAX` not covered
+
+error[E0004]: non-exhaustive patterns: `0usize` and `21usize..=$USIZE_MAX` not covered
+  --> $DIR/precise_pointer_size_matching.rs:29:11
+   |
+LL |     match 0usize { //~ ERROR non-exhaustive patterns
+   |           ^^^^^^ patterns `0usize` and `21usize..=$USIZE_MAX` not covered
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs-test.rs b/src/test/ui/proc-macro/ambiguous-builtin-attrs-test.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs-test.rs
rename to src/test/ui/proc-macro/ambiguous-builtin-attrs-test.rs
diff --git a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs-test.stderr b/src/test/ui/proc-macro/ambiguous-builtin-attrs-test.stderr
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs-test.stderr
rename to src/test/ui/proc-macro/ambiguous-builtin-attrs-test.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.rs b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.rs
rename to src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
diff --git a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr
rename to src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
diff --git a/src/test/ui-fulldeps/attribute-order-restricted.rs b/src/test/ui/proc-macro/attribute-order-restricted.rs
similarity index 100%
rename from src/test/ui-fulldeps/attribute-order-restricted.rs
rename to src/test/ui/proc-macro/attribute-order-restricted.rs
diff --git a/src/test/ui-fulldeps/attribute-order-restricted.stderr b/src/test/ui/proc-macro/attribute-order-restricted.stderr
similarity index 100%
rename from src/test/ui-fulldeps/attribute-order-restricted.stderr
rename to src/test/ui/proc-macro/attribute-order-restricted.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.rs b/src/test/ui/proc-macro/attribute-spans-preserved.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.rs
rename to src/test/ui/proc-macro/attribute-spans-preserved.rs
diff --git a/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.stderr b/src/test/ui/proc-macro/attribute-spans-preserved.stderr
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.stderr
rename to src/test/ui/proc-macro/attribute-spans-preserved.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.stdout b/src/test/ui/proc-macro/attribute-spans-preserved.stdout
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/attribute-spans-preserved.stdout
rename to src/test/ui/proc-macro/attribute-spans-preserved.stdout
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/attr_proc_macro.rs b/src/test/ui/proc-macro/auxiliary/attr_proc_macro.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/attr_proc_macro.rs
rename to src/test/ui/proc-macro/auxiliary/attr_proc_macro.rs
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/attribute-spans-preserved.rs b/src/test/ui/proc-macro/auxiliary/attribute-spans-preserved.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/attribute-spans-preserved.rs
rename to src/test/ui/proc-macro/auxiliary/attribute-spans-preserved.rs
index e725cc7..9f7a7e4 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/attribute-spans-preserved.rs
+++ b/src/test/ui/proc-macro/auxiliary/attribute-spans-preserved.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/bang_proc_macro.rs b/src/test/ui/proc-macro/auxiliary/bang_proc_macro.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/bang_proc_macro.rs
rename to src/test/ui/proc-macro/auxiliary/bang_proc_macro.rs
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/builtin-attrs.rs b/src/test/ui/proc-macro/auxiliary/builtin-attrs.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/builtin-attrs.rs
rename to src/test/ui/proc-macro/auxiliary/builtin-attrs.rs
index e18ca57..571ea1b 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/builtin-attrs.rs
+++ b/src/test/ui/proc-macro/auxiliary/builtin-attrs.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/auxiliary/derive-clona.rs b/src/test/ui/proc-macro/auxiliary/derive-clona.rs
similarity index 100%
rename from src/test/ui-fulldeps/auxiliary/derive-clona.rs
rename to src/test/ui/proc-macro/auxiliary/derive-clona.rs
diff --git a/src/test/ui-fulldeps/auxiliary/derive-foo.rs b/src/test/ui/proc-macro/auxiliary/derive-foo.rs
similarity index 100%
rename from src/test/ui-fulldeps/auxiliary/derive-foo.rs
rename to src/test/ui/proc-macro/auxiliary/derive-foo.rs
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed-2.rs b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowed-2.rs
rename to src/test/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/issue-53481.rs b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowed.rs
similarity index 93%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/issue-53481.rs
rename to src/test/ui/proc-macro/auxiliary/derive-helper-shadowed.rs
index 9554cdd..5b5243d 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/issue-53481.rs
+++ b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowed.rs
@@ -1,9 +1,9 @@
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
 
 extern crate proc_macro;
-
 use proc_macro::*;
 
 #[proc_macro_derive(MyTrait, attributes(my_attr))]
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowing.rs b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing.rs
similarity index 95%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowing.rs
rename to src/test/ui/proc-macro/auxiliary/derive-helper-shadowing.rs
index 0fd8aa5..6e0bdcb 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/derive-helper-shadowing.rs
+++ b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing.rs
@@ -1,3 +1,4 @@
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/derive-panic.rs b/src/test/ui/proc-macro/auxiliary/derive-panic.rs
similarity index 99%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/derive-panic.rs
rename to src/test/ui/proc-macro/auxiliary/derive-panic.rs
index 3274f03..d7fa5b6 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/derive-panic.rs
+++ b/src/test/ui/proc-macro/auxiliary/derive-panic.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// no-prefer-dynamic
 // force-host
+// no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
 
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs b/src/test/ui/proc-macro/auxiliary/generate-mod.rs
similarity index 99%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs
rename to src/test/ui/proc-macro/auxiliary/generate-mod.rs
index 1ed8ef5..a1f025d 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs
+++ b/src/test/ui/proc-macro/auxiliary/generate-mod.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // run-pass
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/auxiliary/invalid-punct-ident.rs b/src/test/ui/proc-macro/auxiliary/invalid-punct-ident.rs
similarity index 100%
rename from src/test/ui-fulldeps/auxiliary/invalid-punct-ident.rs
rename to src/test/ui/proc-macro/auxiliary/invalid-punct-ident.rs
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/issue-53481.rs b/src/test/ui/proc-macro/auxiliary/issue-53481.rs
similarity index 93%
copy from src/test/ui-fulldeps/proc-macro/auxiliary/issue-53481.rs
copy to src/test/ui/proc-macro/auxiliary/issue-53481.rs
index 9554cdd..d9f290d 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/issue-53481.rs
+++ b/src/test/ui/proc-macro/auxiliary/issue-53481.rs
@@ -1,3 +1,4 @@
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/auxiliary/lifetimes.rs b/src/test/ui/proc-macro/auxiliary/lifetimes.rs
similarity index 98%
rename from src/test/ui-fulldeps/auxiliary/lifetimes.rs
rename to src/test/ui/proc-macro/auxiliary/lifetimes.rs
index fc59a62..8348d08 100644
--- a/src/test/ui-fulldeps/auxiliary/lifetimes.rs
+++ b/src/test/ui/proc-macro/auxiliary/lifetimes.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/macro-brackets.rs b/src/test/ui/proc-macro/auxiliary/macro-brackets.rs
similarity index 97%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/macro-brackets.rs
rename to src/test/ui/proc-macro/auxiliary/macro-brackets.rs
index be1777f..08ff604 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/macro-brackets.rs
+++ b/src/test/ui/proc-macro/auxiliary/macro-brackets.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/multispan.rs b/src/test/ui/proc-macro/auxiliary/multispan.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/multispan.rs
rename to src/test/ui/proc-macro/auxiliary/multispan.rs
index 383016f..e122b22 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/multispan.rs
+++ b/src/test/ui/proc-macro/auxiliary/multispan.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/nested-item-spans.rs b/src/test/ui/proc-macro/auxiliary/nested-item-spans.rs
similarity index 97%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/nested-item-spans.rs
rename to src/test/ui/proc-macro/auxiliary/nested-item-spans.rs
index 6b89315..e195f42 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/nested-item-spans.rs
+++ b/src/test/ui/proc-macro/auxiliary/nested-item-spans.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/parent-source-spans.rs b/src/test/ui/proc-macro/auxiliary/parent-source-spans.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/parent-source-spans.rs
rename to src/test/ui/proc-macro/auxiliary/parent-source-spans.rs
index f559040..a007fad 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/parent-source-spans.rs
+++ b/src/test/ui/proc-macro/auxiliary/parent-source-spans.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![feature(proc_macro_diagnostic, proc_macro_span)]
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/span-preservation.rs b/src/test/ui/proc-macro/auxiliary/span-preservation.rs
similarity index 94%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/span-preservation.rs
rename to src/test/ui/proc-macro/auxiliary/span-preservation.rs
index 65ed9cf..33c7968 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/span-preservation.rs
+++ b/src/test/ui/proc-macro/auxiliary/span-preservation.rs
@@ -1,3 +1,4 @@
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/auxiliary/subspan.rs b/src/test/ui/proc-macro/auxiliary/subspan.rs
similarity index 98%
rename from src/test/ui-fulldeps/auxiliary/subspan.rs
rename to src/test/ui/proc-macro/auxiliary/subspan.rs
index 134b04d..dbf355f 100644
--- a/src/test/ui-fulldeps/auxiliary/subspan.rs
+++ b/src/test/ui/proc-macro/auxiliary/subspan.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/three-equals.rs b/src/test/ui/proc-macro/auxiliary/three-equals.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/three-equals.rs
rename to src/test/ui/proc-macro/auxiliary/three-equals.rs
index 569a458..b238410 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/three-equals.rs
+++ b/src/test/ui/proc-macro/auxiliary/three-equals.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowed.rs b/src/test/ui/proc-macro/derive-helper-shadowed.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/derive-helper-shadowed.rs
rename to src/test/ui/proc-macro/derive-helper-shadowed.rs
diff --git a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.rs b/src/test/ui/proc-macro/derive-helper-shadowing.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.rs
rename to src/test/ui/proc-macro/derive-helper-shadowing.rs
diff --git a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr
rename to src/test/ui/proc-macro/derive-helper-shadowing.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs b/src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs
rename to src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs
diff --git a/src/test/ui-fulldeps/proc-macro/generate-mod.rs b/src/test/ui/proc-macro/generate-mod.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/generate-mod.rs
rename to src/test/ui/proc-macro/generate-mod.rs
diff --git a/src/test/ui-fulldeps/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/generate-mod.stderr
rename to src/test/ui/proc-macro/generate-mod.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/invalid-attributes.rs b/src/test/ui/proc-macro/invalid-attributes.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/invalid-attributes.rs
rename to src/test/ui/proc-macro/invalid-attributes.rs
index 8b940a0..cca954f 100644
--- a/src/test/ui-fulldeps/proc-macro/invalid-attributes.rs
+++ b/src/test/ui/proc-macro/invalid-attributes.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/invalid-attributes.stderr b/src/test/ui/proc-macro/invalid-attributes.stderr
similarity index 82%
rename from src/test/ui-fulldeps/proc-macro/invalid-attributes.stderr
rename to src/test/ui/proc-macro/invalid-attributes.stderr
index 5fd8736..c480bcb 100644
--- a/src/test/ui-fulldeps/proc-macro/invalid-attributes.stderr
+++ b/src/test/ui/proc-macro/invalid-attributes.stderr
@@ -1,35 +1,35 @@
 error: `#[proc_macro]` attribute does not take any arguments
-  --> $DIR/invalid-attributes.rs:19:1
+  --> $DIR/invalid-attributes.rs:20:1
    |
 LL | #[proc_macro = "test"] //~ ERROR: does not take any arguments
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[proc_macro]` attribute does not take any arguments
-  --> $DIR/invalid-attributes.rs:22:1
+  --> $DIR/invalid-attributes.rs:23:1
    |
 LL | #[proc_macro()] //~ ERROR: does not take any arguments
    | ^^^^^^^^^^^^^^^
 
 error: `#[proc_macro]` attribute does not take any arguments
-  --> $DIR/invalid-attributes.rs:25:1
+  --> $DIR/invalid-attributes.rs:26:1
    |
 LL | #[proc_macro(x)] //~ ERROR: does not take any arguments
    | ^^^^^^^^^^^^^^^^
 
 error: `#[proc_macro_attribute]` attribute does not take any arguments
-  --> $DIR/invalid-attributes.rs:28:1
+  --> $DIR/invalid-attributes.rs:29:1
    |
 LL | #[proc_macro_attribute = "test"] //~ ERROR: does not take any arguments
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[proc_macro_attribute]` attribute does not take any arguments
-  --> $DIR/invalid-attributes.rs:31:1
+  --> $DIR/invalid-attributes.rs:32:1
    |
 LL | #[proc_macro_attribute()] //~ ERROR: does not take any arguments
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[proc_macro_attribute]` attribute does not take any arguments
-  --> $DIR/invalid-attributes.rs:34:1
+  --> $DIR/invalid-attributes.rs:35:1
    |
 LL | #[proc_macro_attribute(x)] //~ ERROR: does not take any arguments
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui-fulldeps/invalid-punct-ident-1.rs b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
similarity index 100%
rename from src/test/ui-fulldeps/invalid-punct-ident-1.rs
rename to src/test/ui/proc-macro/invalid-punct-ident-1.rs
diff --git a/src/test/ui-fulldeps/invalid-punct-ident-1.stderr b/src/test/ui/proc-macro/invalid-punct-ident-1.stderr
similarity index 100%
rename from src/test/ui-fulldeps/invalid-punct-ident-1.stderr
rename to src/test/ui/proc-macro/invalid-punct-ident-1.stderr
diff --git a/src/test/ui-fulldeps/invalid-punct-ident-2.rs b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
similarity index 100%
rename from src/test/ui-fulldeps/invalid-punct-ident-2.rs
rename to src/test/ui/proc-macro/invalid-punct-ident-2.rs
diff --git a/src/test/ui-fulldeps/invalid-punct-ident-2.stderr b/src/test/ui/proc-macro/invalid-punct-ident-2.stderr
similarity index 100%
rename from src/test/ui-fulldeps/invalid-punct-ident-2.stderr
rename to src/test/ui/proc-macro/invalid-punct-ident-2.stderr
diff --git a/src/test/ui-fulldeps/invalid-punct-ident-3.rs b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
similarity index 100%
rename from src/test/ui-fulldeps/invalid-punct-ident-3.rs
rename to src/test/ui/proc-macro/invalid-punct-ident-3.rs
diff --git a/src/test/ui-fulldeps/invalid-punct-ident-3.stderr b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr
similarity index 100%
rename from src/test/ui-fulldeps/invalid-punct-ident-3.stderr
rename to src/test/ui/proc-macro/invalid-punct-ident-3.stderr
diff --git a/src/test/ui-fulldeps/invalid-punct-ident-4.rs b/src/test/ui/proc-macro/invalid-punct-ident-4.rs
similarity index 100%
rename from src/test/ui-fulldeps/invalid-punct-ident-4.rs
rename to src/test/ui/proc-macro/invalid-punct-ident-4.rs
diff --git a/src/test/ui-fulldeps/invalid-punct-ident-4.stderr b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
similarity index 100%
rename from src/test/ui-fulldeps/invalid-punct-ident-4.stderr
rename to src/test/ui/proc-macro/invalid-punct-ident-4.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/issue-53481.rs b/src/test/ui/proc-macro/issue-53481.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/issue-53481.rs
rename to src/test/ui/proc-macro/issue-53481.rs
diff --git a/src/test/ui-fulldeps/lifetimes.rs b/src/test/ui/proc-macro/lifetimes.rs
similarity index 100%
rename from src/test/ui-fulldeps/lifetimes.rs
rename to src/test/ui/proc-macro/lifetimes.rs
diff --git a/src/test/ui-fulldeps/lifetimes.stderr b/src/test/ui/proc-macro/lifetimes.stderr
similarity index 100%
rename from src/test/ui-fulldeps/lifetimes.stderr
rename to src/test/ui/proc-macro/lifetimes.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/load-panic.rs b/src/test/ui/proc-macro/load-panic.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/load-panic.rs
rename to src/test/ui/proc-macro/load-panic.rs
diff --git a/src/test/ui-fulldeps/proc-macro/load-panic.stderr b/src/test/ui/proc-macro/load-panic.stderr
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/load-panic.stderr
rename to src/test/ui/proc-macro/load-panic.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/macro-brackets.rs b/src/test/ui/proc-macro/macro-brackets.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/macro-brackets.rs
rename to src/test/ui/proc-macro/macro-brackets.rs
diff --git a/src/test/ui-fulldeps/proc-macro/macro-brackets.stderr b/src/test/ui/proc-macro/macro-brackets.stderr
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/macro-brackets.stderr
rename to src/test/ui/proc-macro/macro-brackets.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved-2.rs b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/macro-namespace-reserved-2.rs
rename to src/test/ui/proc-macro/macro-namespace-reserved-2.rs
index fa05ad2..02526b6 100644
--- a/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved-2.rs
+++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
similarity index 81%
rename from src/test/ui-fulldeps/proc-macro/macro-namespace-reserved-2.stderr
rename to src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
index 9def03e..9e989eb 100644
--- a/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved-2.stderr
+++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
@@ -1,53 +1,53 @@
 error: can't use a procedural macro from the same crate that defines it
-  --> $DIR/macro-namespace-reserved-2.rs:34:5
+  --> $DIR/macro-namespace-reserved-2.rs:35:5
    |
 LL |     my_macro!(); //~ ERROR can't use a procedural macro from the same crate that defines it
    |     ^^^^^^^^
 
 error: can't use a procedural macro from the same crate that defines it
-  --> $DIR/macro-namespace-reserved-2.rs:37:5
+  --> $DIR/macro-namespace-reserved-2.rs:38:5
    |
 LL |     my_macro_attr!(); //~ ERROR can't use a procedural macro from the same crate that defines it
    |     ^^^^^^^^^^^^^
 
 error: can't use a procedural macro from the same crate that defines it
-  --> $DIR/macro-namespace-reserved-2.rs:40:5
+  --> $DIR/macro-namespace-reserved-2.rs:41:5
    |
 LL |     MyTrait!(); //~ ERROR can't use a procedural macro from the same crate that defines it
    |     ^^^^^^^
 
 error: can't use a procedural macro from the same crate that defines it
-  --> $DIR/macro-namespace-reserved-2.rs:43:3
+  --> $DIR/macro-namespace-reserved-2.rs:44:3
    |
 LL | #[my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it
    |   ^^^^^^^^
 
 error: can't use a procedural macro from the same crate that defines it
-  --> $DIR/macro-namespace-reserved-2.rs:45:3
+  --> $DIR/macro-namespace-reserved-2.rs:46:3
    |
 LL | #[my_macro_attr] //~ ERROR can't use a procedural macro from the same crate that defines it
    |   ^^^^^^^^^^^^^
 
 error: can't use a procedural macro from the same crate that defines it
-  --> $DIR/macro-namespace-reserved-2.rs:47:3
+  --> $DIR/macro-namespace-reserved-2.rs:48:3
    |
 LL | #[MyTrait] //~ ERROR can't use a procedural macro from the same crate that defines it
    |   ^^^^^^^
 
 error: can't use a procedural macro from the same crate that defines it
-  --> $DIR/macro-namespace-reserved-2.rs:50:10
+  --> $DIR/macro-namespace-reserved-2.rs:51:10
    |
 LL | #[derive(my_macro)] //~ ERROR can't use a procedural macro from the same crate that defines it
    |          ^^^^^^^^
 
 error: can't use a procedural macro from the same crate that defines it
-  --> $DIR/macro-namespace-reserved-2.rs:52:10
+  --> $DIR/macro-namespace-reserved-2.rs:53:10
    |
 LL | #[derive(my_macro_attr)] //~ ERROR can't use a procedural macro from the same crate that defines it
    |          ^^^^^^^^^^^^^
 
 error: can't use a procedural macro from the same crate that defines it
-  --> $DIR/macro-namespace-reserved-2.rs:54:10
+  --> $DIR/macro-namespace-reserved-2.rs:55:10
    |
 LL | #[derive(MyTrait)] //~ ERROR can't use a procedural macro from the same crate that defines it
    |          ^^^^^^^
diff --git a/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved.rs b/src/test/ui/proc-macro/macro-namespace-reserved.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/macro-namespace-reserved.rs
rename to src/test/ui/proc-macro/macro-namespace-reserved.rs
index e7bb05d..b0a3dbf 100644
--- a/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved.rs
+++ b/src/test/ui/proc-macro/macro-namespace-reserved.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![feature(decl_macro)]
diff --git a/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved.stderr b/src/test/ui/proc-macro/macro-namespace-reserved.stderr
similarity index 95%
rename from src/test/ui-fulldeps/proc-macro/macro-namespace-reserved.stderr
rename to src/test/ui/proc-macro/macro-namespace-reserved.stderr
index 44b51ed..c453bde 100644
--- a/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved.stderr
+++ b/src/test/ui/proc-macro/macro-namespace-reserved.stderr
@@ -1,5 +1,5 @@
 error[E0428]: the name `my_macro` is defined multiple times
-  --> $DIR/macro-namespace-reserved.rs:34:1
+  --> $DIR/macro-namespace-reserved.rs:35:1
    |
 LL | pub fn my_macro(input: TokenStream) -> TokenStream {
    | -------------------------------------------------- previous definition of the macro `my_macro` here
@@ -10,7 +10,7 @@
    = note: `my_macro` must be defined only once in the macro namespace of this module
 
 error[E0428]: the name `my_macro_attr` is defined multiple times
-  --> $DIR/macro-namespace-reserved.rs:35:1
+  --> $DIR/macro-namespace-reserved.rs:36:1
    |
 LL | pub fn my_macro_attr(input: TokenStream, _: TokenStream) -> TokenStream {
    | ----------------------------------------------------------------------- previous definition of the macro `my_macro_attr` here
@@ -21,7 +21,7 @@
    = note: `my_macro_attr` must be defined only once in the macro namespace of this module
 
 error[E0428]: the name `MyTrait` is defined multiple times
-  --> $DIR/macro-namespace-reserved.rs:36:1
+  --> $DIR/macro-namespace-reserved.rs:37:1
    |
 LL | #[proc_macro_derive(MyTrait)]
    |                     ------- previous definition of the macro `MyTrait` here
@@ -32,7 +32,7 @@
    = note: `MyTrait` must be defined only once in the macro namespace of this module
 
 error[E0428]: the name `SameName` is defined multiple times
-  --> $DIR/macro-namespace-reserved.rs:44:1
+  --> $DIR/macro-namespace-reserved.rs:45:1
    |
 LL | #[proc_macro_derive(SameName)]
    |                     -------- previous definition of the macro `SameName` here
diff --git a/src/test/ui-fulldeps/proc-macro/macro-use-attr.rs b/src/test/ui/proc-macro/macro-use-attr.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/macro-use-attr.rs
rename to src/test/ui/proc-macro/macro-use-attr.rs
diff --git a/src/test/ui-fulldeps/proc-macro/macro-use-bang.rs b/src/test/ui/proc-macro/macro-use-bang.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/macro-use-bang.rs
rename to src/test/ui/proc-macro/macro-use-bang.rs
diff --git a/src/test/ui-fulldeps/proc-macro/multispan.rs b/src/test/ui/proc-macro/multispan.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/multispan.rs
rename to src/test/ui/proc-macro/multispan.rs
index 63a95ce..0306786 100644
--- a/src/test/ui-fulldeps/proc-macro/multispan.rs
+++ b/src/test/ui/proc-macro/multispan.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:multispan.rs
-// ignore-stage1
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/ui-fulldeps/proc-macro/multispan.stderr b/src/test/ui/proc-macro/multispan.stderr
similarity index 87%
rename from src/test/ui-fulldeps/proc-macro/multispan.stderr
rename to src/test/ui/proc-macro/multispan.stderr
index 267313e..39bdbb5 100644
--- a/src/test/ui-fulldeps/proc-macro/multispan.stderr
+++ b/src/test/ui/proc-macro/multispan.stderr
@@ -1,83 +1,83 @@
 error: hello to you, too!
-  --> $DIR/multispan.rs:25:5
+  --> $DIR/multispan.rs:24:5
    |
 LL |     hello!(hi); //~ ERROR hello to you, too!
    |     ^^^^^^^^^^^
    |
 note: found these 'hi's
-  --> $DIR/multispan.rs:25:12
+  --> $DIR/multispan.rs:24:12
    |
 LL |     hello!(hi); //~ ERROR hello to you, too!
    |            ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:28:5
+  --> $DIR/multispan.rs:27:5
    |
 LL |     hello!(hi hi); //~ ERROR hello to you, too!
    |     ^^^^^^^^^^^^^^
    |
 note: found these 'hi's
-  --> $DIR/multispan.rs:28:12
+  --> $DIR/multispan.rs:27:12
    |
 LL |     hello!(hi hi); //~ ERROR hello to you, too!
    |            ^^ ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:31:5
+  --> $DIR/multispan.rs:30:5
    |
 LL |     hello!(hi hi hi); //~ ERROR hello to you, too!
    |     ^^^^^^^^^^^^^^^^^
    |
 note: found these 'hi's
-  --> $DIR/multispan.rs:31:12
+  --> $DIR/multispan.rs:30:12
    |
 LL |     hello!(hi hi hi); //~ ERROR hello to you, too!
    |            ^^ ^^ ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:34:5
+  --> $DIR/multispan.rs:33:5
    |
 LL |     hello!(hi hey hi yo hi beep beep hi hi); //~ ERROR hello to you, too!
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: found these 'hi's
-  --> $DIR/multispan.rs:34:12
+  --> $DIR/multispan.rs:33:12
    |
 LL |     hello!(hi hey hi yo hi beep beep hi hi); //~ ERROR hello to you, too!
    |            ^^     ^^    ^^           ^^ ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:35:5
+  --> $DIR/multispan.rs:34:5
    |
 LL |     hello!(hi there, hi how are you? hi... hi.); //~ ERROR hello to you, too!
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: found these 'hi's
-  --> $DIR/multispan.rs:35:12
+  --> $DIR/multispan.rs:34:12
    |
 LL |     hello!(hi there, hi how are you? hi... hi.); //~ ERROR hello to you, too!
    |            ^^        ^^              ^^    ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:36:5
+  --> $DIR/multispan.rs:35:5
    |
 LL |     hello!(whoah. hi di hi di ho); //~ ERROR hello to you, too!
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: found these 'hi's
-  --> $DIR/multispan.rs:36:19
+  --> $DIR/multispan.rs:35:19
    |
 LL |     hello!(whoah. hi di hi di ho); //~ ERROR hello to you, too!
    |                   ^^    ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:37:5
+  --> $DIR/multispan.rs:36:5
    |
 LL |     hello!(hi good hi and good bye); //~ ERROR hello to you, too!
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: found these 'hi's
-  --> $DIR/multispan.rs:37:12
+  --> $DIR/multispan.rs:36:12
    |
 LL |     hello!(hi good hi and good bye); //~ ERROR hello to you, too!
    |            ^^      ^^
diff --git a/src/test/ui-fulldeps/proc-macro/nested-item-spans.rs b/src/test/ui/proc-macro/nested-item-spans.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/nested-item-spans.rs
rename to src/test/ui/proc-macro/nested-item-spans.rs
diff --git a/src/test/ui-fulldeps/proc-macro/nested-item-spans.stderr b/src/test/ui/proc-macro/nested-item-spans.stderr
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/nested-item-spans.stderr
rename to src/test/ui/proc-macro/nested-item-spans.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/non-root.rs b/src/test/ui/proc-macro/non-root.rs
similarity index 97%
rename from src/test/ui-fulldeps/proc-macro/non-root.rs
rename to src/test/ui/proc-macro/non-root.rs
index 2440488..437973a 100644
--- a/src/test/ui-fulldeps/proc-macro/non-root.rs
+++ b/src/test/ui/proc-macro/non-root.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui-fulldeps/proc-macro/non-root.stderr b/src/test/ui/proc-macro/non-root.stderr
similarity index 90%
rename from src/test/ui-fulldeps/proc-macro/non-root.stderr
rename to src/test/ui/proc-macro/non-root.stderr
index 23222a2..8c14f64 100644
--- a/src/test/ui-fulldeps/proc-macro/non-root.stderr
+++ b/src/test/ui/proc-macro/non-root.stderr
@@ -1,5 +1,5 @@
 error: functions tagged with `#[proc_macro]` must currently reside in the root of the crate
-  --> $DIR/non-root.rs:20:5
+  --> $DIR/non-root.rs:21:5
    |
 LL |     pub fn foo(arg: TokenStream) -> TokenStream { arg }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui-fulldeps/proc-macro/parent-source-spans.rs b/src/test/ui/proc-macro/parent-source-spans.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/parent-source-spans.rs
rename to src/test/ui/proc-macro/parent-source-spans.rs
index 7c30a8e..8f8e22b 100644
--- a/src/test/ui-fulldeps/proc-macro/parent-source-spans.rs
+++ b/src/test/ui/proc-macro/parent-source-spans.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:parent-source-spans.rs
-// ignore-stage1
+
 
 #![feature(decl_macro, proc_macro_hygiene)]
 
diff --git a/src/test/ui-fulldeps/proc-macro/parent-source-spans.stderr b/src/test/ui/proc-macro/parent-source-spans.stderr
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/parent-source-spans.stderr
rename to src/test/ui/proc-macro/parent-source-spans.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/reserved-macro-names.rs b/src/test/ui/proc-macro/reserved-macro-names.rs
similarity index 93%
rename from src/test/ui-fulldeps/proc-macro/reserved-macro-names.rs
rename to src/test/ui/proc-macro/reserved-macro-names.rs
index ff5984a..7c66af1 100644
--- a/src/test/ui-fulldeps/proc-macro/reserved-macro-names.rs
+++ b/src/test/ui/proc-macro/reserved-macro-names.rs
@@ -1,3 +1,6 @@
+// force-host
+// no-prefer-dynamic
+
 #![crate_type = "proc-macro"]
 
 extern crate proc_macro;
diff --git a/src/test/ui-fulldeps/proc-macro/reserved-macro-names.stderr b/src/test/ui/proc-macro/reserved-macro-names.stderr
similarity index 80%
rename from src/test/ui-fulldeps/proc-macro/reserved-macro-names.stderr
rename to src/test/ui/proc-macro/reserved-macro-names.stderr
index be6e80c..5ebe62a 100644
--- a/src/test/ui-fulldeps/proc-macro/reserved-macro-names.stderr
+++ b/src/test/ui/proc-macro/reserved-macro-names.stderr
@@ -1,17 +1,17 @@
 error: name `cfg` is reserved in macro namespace
-  --> $DIR/reserved-macro-names.rs:7:8
+  --> $DIR/reserved-macro-names.rs:10:8
    |
 LL | pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream {
    |        ^^^
 
 error: name `cfg_attr` is reserved in macro namespace
-  --> $DIR/reserved-macro-names.rs:13:8
+  --> $DIR/reserved-macro-names.rs:16:8
    |
 LL | pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream {
    |        ^^^^^^^^
 
 error: name `derive` is reserved in macro namespace
-  --> $DIR/reserved-macro-names.rs:19:8
+  --> $DIR/reserved-macro-names.rs:22:8
    |
 LL | pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream {
    |        ^^^^^^
diff --git a/src/test/ui-fulldeps/resolve-error.rs b/src/test/ui/proc-macro/resolve-error.rs
similarity index 100%
rename from src/test/ui-fulldeps/resolve-error.rs
rename to src/test/ui/proc-macro/resolve-error.rs
diff --git a/src/test/ui-fulldeps/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr
similarity index 100%
rename from src/test/ui-fulldeps/resolve-error.stderr
rename to src/test/ui/proc-macro/resolve-error.stderr
diff --git a/src/test/ui-fulldeps/proc-macro/signature.rs b/src/test/ui/proc-macro/signature.rs
similarity index 94%
rename from src/test/ui-fulldeps/proc-macro/signature.rs
rename to src/test/ui/proc-macro/signature.rs
index f2ea6f7..4d69031 100644
--- a/src/test/ui-fulldeps/proc-macro/signature.rs
+++ b/src/test/ui/proc-macro/signature.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
+// no-prefer-dynamic
+
 #![crate_type = "proc-macro"]
 #![allow(warnings)]
 
diff --git a/src/test/ui-fulldeps/proc-macro/signature.stderr b/src/test/ui/proc-macro/signature.stderr
similarity index 93%
rename from src/test/ui-fulldeps/proc-macro/signature.stderr
rename to src/test/ui/proc-macro/signature.stderr
index fdd10c3..681e72c 100644
--- a/src/test/ui-fulldeps/proc-macro/signature.stderr
+++ b/src/test/ui/proc-macro/signature.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/signature.rs:17:1
+  --> $DIR/signature.rs:20:1
    |
 LL | / pub unsafe extern fn foo(a: i32, b: u32) -> u32 {
 LL | |     //~^ ERROR: mismatched types
diff --git a/src/test/ui-fulldeps/proc-macro/span-preservation.rs b/src/test/ui/proc-macro/span-preservation.rs
similarity index 70%
rename from src/test/ui-fulldeps/proc-macro/span-preservation.rs
rename to src/test/ui/proc-macro/span-preservation.rs
index adcb42a..64f675e 100644
--- a/src/test/ui-fulldeps/proc-macro/span-preservation.rs
+++ b/src/test/ui/proc-macro/span-preservation.rs
@@ -1,3 +1,4 @@
+//~ ERROR mismatched types
 // aux-build:span-preservation.rs
 
 // For each of these, we should get the appropriate type mismatch error message,
@@ -9,13 +10,13 @@
 
 #[foo]
 fn a() {
-    let x: usize = "hello";;;;;
+    let x: usize = "hello";;;;; //~ ERROR mismatched types
 }
 
 #[foo]
 fn b(x: Option<isize>) -> usize {
     match x {
-        Some(x) => { return x },
+        Some(x) => { return x }, //~ ERROR mismatched types
         None => 10
     }
 }
@@ -31,8 +32,8 @@
         b: usize
     }
 
-    let x = Foo { a: 10isize };
-    let y = Foo { a: 10, b: 10isize };
+    let x = Foo { a: 10isize }; //~ ERROR mismatched types
+    let y = Foo { a: 10, b: 10isize }; //~ ERROR has no field named `b`
 }
 
 // FIXME: This doesn't work at the moment. See the one below. The pretty-printer
@@ -45,7 +46,7 @@
 
 #[foo]
 extern "C" fn baz() {
-    0
+    0 //~ ERROR mismatched types
 }
 
 fn main() {}
diff --git a/src/test/ui-fulldeps/proc-macro/span-preservation.stderr b/src/test/ui/proc-macro/span-preservation.stderr
similarity index 67%
rename from src/test/ui-fulldeps/proc-macro/span-preservation.stderr
rename to src/test/ui/proc-macro/span-preservation.stderr
index f33245a..64d0173 100644
--- a/src/test/ui-fulldeps/proc-macro/span-preservation.stderr
+++ b/src/test/ui/proc-macro/span-preservation.stderr
@@ -4,40 +4,40 @@
               found type `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/span-preservation.rs:12:20
+  --> $DIR/span-preservation.rs:13:20
    |
-LL |     let x: usize = "hello";;;;;
+LL |     let x: usize = "hello";;;;; //~ ERROR mismatched types
    |                    ^^^^^^^ expected usize, found reference
    |
    = note: expected type `usize`
               found type `&'static str`
 
 error[E0308]: mismatched types
-  --> $DIR/span-preservation.rs:18:29
+  --> $DIR/span-preservation.rs:19:29
    |
-LL |         Some(x) => { return x },
+LL |         Some(x) => { return x }, //~ ERROR mismatched types
    |                             ^ expected usize, found isize
 
 error[E0308]: mismatched types
-  --> $DIR/span-preservation.rs:34:22
+  --> $DIR/span-preservation.rs:35:22
    |
-LL |     let x = Foo { a: 10isize };
+LL |     let x = Foo { a: 10isize }; //~ ERROR mismatched types
    |                      ^^^^^^^ expected usize, found isize
 
 error[E0560]: struct `c::Foo` has no field named `b`
-  --> $DIR/span-preservation.rs:35:26
+  --> $DIR/span-preservation.rs:36:26
    |
-LL |     let y = Foo { a: 10, b: 10isize };
+LL |     let y = Foo { a: 10, b: 10isize }; //~ ERROR has no field named `b`
    |                          ^ `c::Foo` does not have this field
    |
    = note: available fields are: `a`
 
 error[E0308]: mismatched types
-  --> $DIR/span-preservation.rs:48:5
+  --> $DIR/span-preservation.rs:49:5
    |
 LL | extern "C" fn baz() {
    |                     - possibly return type missing here?
-LL |     0
+LL |     0 //~ ERROR mismatched types
    |     ^ expected (), found integral variable
    |
    = note: expected type `()`
diff --git a/src/test/ui-fulldeps/subspan.rs b/src/test/ui/proc-macro/subspan.rs
similarity index 98%
rename from src/test/ui-fulldeps/subspan.rs
rename to src/test/ui/proc-macro/subspan.rs
index 437123c..dccf6e2 100644
--- a/src/test/ui-fulldeps/subspan.rs
+++ b/src/test/ui/proc-macro/subspan.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:subspan.rs
-// ignore-stage1
 
 extern crate subspan;
 
diff --git a/src/test/ui-fulldeps/subspan.stderr b/src/test/ui/proc-macro/subspan.stderr
similarity index 85%
rename from src/test/ui-fulldeps/subspan.stderr
rename to src/test/ui/proc-macro/subspan.stderr
index 4d3928c..d9339bd 100644
--- a/src/test/ui-fulldeps/subspan.stderr
+++ b/src/test/ui/proc-macro/subspan.stderr
@@ -1,95 +1,95 @@
 error: found 'hi's
-  --> $DIR/subspan.rs:22:1
+  --> $DIR/subspan.rs:21:1
    |
 LL | subspan!("hi"); //~ ERROR found 'hi's
    | ^^^^^^^^^^^^^^^
    |
 note: here
-  --> $DIR/subspan.rs:22:11
+  --> $DIR/subspan.rs:21:11
    |
 LL | subspan!("hi"); //~ ERROR found 'hi's
    |           ^^
 
 error: found 'hi's
-  --> $DIR/subspan.rs:25:1
+  --> $DIR/subspan.rs:24:1
    |
 LL | subspan!("hihi"); //~ ERROR found 'hi's
    | ^^^^^^^^^^^^^^^^^
    |
 note: here
-  --> $DIR/subspan.rs:25:11
+  --> $DIR/subspan.rs:24:11
    |
 LL | subspan!("hihi"); //~ ERROR found 'hi's
    |           ^^^^
 
 error: found 'hi's
-  --> $DIR/subspan.rs:28:1
+  --> $DIR/subspan.rs:27:1
    |
 LL | subspan!("hihihi"); //~ ERROR found 'hi's
    | ^^^^^^^^^^^^^^^^^^^
    |
 note: here
-  --> $DIR/subspan.rs:28:11
+  --> $DIR/subspan.rs:27:11
    |
 LL | subspan!("hihihi"); //~ ERROR found 'hi's
    |           ^^^^^^
 
 error: found 'hi's
-  --> $DIR/subspan.rs:31:1
+  --> $DIR/subspan.rs:30:1
    |
 LL | subspan!("why I hide? hi!"); //~ ERROR found 'hi's
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: here
-  --> $DIR/subspan.rs:31:17
+  --> $DIR/subspan.rs:30:17
    |
 LL | subspan!("why I hide? hi!"); //~ ERROR found 'hi's
    |                 ^^    ^^
 
 error: found 'hi's
-  --> $DIR/subspan.rs:32:1
+  --> $DIR/subspan.rs:31:1
    |
 LL | subspan!("hey, hi, hidy, hidy, hi hi"); //~ ERROR found 'hi's
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: here
-  --> $DIR/subspan.rs:32:16
+  --> $DIR/subspan.rs:31:16
    |
 LL | subspan!("hey, hi, hidy, hidy, hi hi"); //~ ERROR found 'hi's
    |                ^^  ^^    ^^    ^^ ^^
 
 error: found 'hi's
-  --> $DIR/subspan.rs:33:1
+  --> $DIR/subspan.rs:32:1
    |
 LL | subspan!("this is a hi, and this is another hi"); //~ ERROR found 'hi's
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: here
-  --> $DIR/subspan.rs:33:12
+  --> $DIR/subspan.rs:32:12
    |
 LL | subspan!("this is a hi, and this is another hi"); //~ ERROR found 'hi's
    |            ^^       ^^       ^^             ^^
 
 error: found 'hi's
-  --> $DIR/subspan.rs:34:1
+  --> $DIR/subspan.rs:33:1
    |
 LL | subspan!("how are you this evening"); //~ ERROR found 'hi's
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: here
-  --> $DIR/subspan.rs:34:24
+  --> $DIR/subspan.rs:33:24
    |
 LL | subspan!("how are you this evening"); //~ ERROR found 'hi's
    |                        ^^
 
 error: found 'hi's
-  --> $DIR/subspan.rs:35:1
+  --> $DIR/subspan.rs:34:1
    |
 LL | subspan!("this is highly eradic"); //~ ERROR found 'hi's
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: here
-  --> $DIR/subspan.rs:35:12
+  --> $DIR/subspan.rs:34:12
    |
 LL | subspan!("this is highly eradic"); //~ ERROR found 'hi's
    |            ^^     ^^
diff --git a/src/test/ui-fulldeps/proc-macro/three-equals.rs b/src/test/ui/proc-macro/three-equals.rs
similarity index 98%
rename from src/test/ui-fulldeps/proc-macro/three-equals.rs
rename to src/test/ui/proc-macro/three-equals.rs
index dd81b10..e3285d3 100644
--- a/src/test/ui-fulldeps/proc-macro/three-equals.rs
+++ b/src/test/ui/proc-macro/three-equals.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:three-equals.rs
-// ignore-stage1
+
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/ui-fulldeps/proc-macro/three-equals.stderr b/src/test/ui/proc-macro/three-equals.stderr
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/three-equals.stderr
rename to src/test/ui/proc-macro/three-equals.stderr
diff --git a/src/test/ui/refutable-pattern-errors.rs b/src/test/ui/refutable-pattern-errors.rs
index 7b40094..a140e42 100644
--- a/src/test/ui/refutable-pattern-errors.rs
+++ b/src/test/ui/refutable-pattern-errors.rs
@@ -14,5 +14,5 @@
 
 fn main() {
     let (1, (Some(1), 2..=3)) = (1, (None, 2));
-    //~^ ERROR refutable pattern in local binding: `(_, _)` not covered
+    //~^ ERROR refutable pattern in local binding: `(-2147483648i32..=0i32, _)` not covered
 }
diff --git a/src/test/ui/refutable-pattern-errors.stderr b/src/test/ui/refutable-pattern-errors.stderr
index c2d5fe0..42aa572 100644
--- a/src/test/ui/refutable-pattern-errors.stderr
+++ b/src/test/ui/refutable-pattern-errors.stderr
@@ -4,11 +4,11 @@
 LL | fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
    |         ^^^^^^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered
 
-error[E0005]: refutable pattern in local binding: `(_, _)` not covered
+error[E0005]: refutable pattern in local binding: `(-2147483648i32..=0i32, _)` not covered
   --> $DIR/refutable-pattern-errors.rs:16:9
    |
 LL |     let (1, (Some(1), 2..=3)) = (1, (None, 2));
-   |         ^^^^^^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered
+   |         ^^^^^^^^^^^^^^^^^^^^^ pattern `(-2147483648i32..=0i32, _)` not covered
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/regions/regions-struct-not-wf.rs b/src/test/ui/regions/regions-struct-not-wf.rs
deleted file mode 100644
index bdd7081..0000000
--- a/src/test/ui/regions/regions-struct-not-wf.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.
-
-// Various examples of structs whose fields are not well-formed.
-
-#![allow(dead_code)]
-
-trait Trait<'a, T> {
-    type Out;
-}
-trait Trait1<'a, 'b, T> {
-    type Out;
-}
-
-impl<'a, T> Trait<'a, T> for usize {
-    type Out = &'a T;
-}
-
-struct RefOk<'a, T:'a> {
-    field: &'a T
-}
-
-impl<'a, T> Trait<'a, T> for u32 {
-    type Out = RefOk<'a, T>;
-}
-
-impl<'a, 'b, T> Trait1<'a, 'b, T> for u32 {
-    type Out = &'a &'b T;
-}
-
-fn main() { }
diff --git a/src/test/ui/regions/regions-struct-not-wf.stderr b/src/test/ui/regions/regions-struct-not-wf.stderr
deleted file mode 100644
index d8c8b6c..0000000
--- a/src/test/ui/regions/regions-struct-not-wf.stderr
+++ /dev/null
@@ -1,49 +0,0 @@
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/regions-struct-not-wf.rs:23:5
-   |
-LL | impl<'a, T> Trait<'a, T> for usize {
-   |          - help: consider adding an explicit lifetime bound `T: 'a`...
-LL |     type Out = &'a T;
-   |     ^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'a T` does not outlive the data it points at
-  --> $DIR/regions-struct-not-wf.rs:23:5
-   |
-LL |     type Out = &'a T;
-   |     ^^^^^^^^^^^^^^^^^
-
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/regions-struct-not-wf.rs:31:5
-   |
-LL | impl<'a, T> Trait<'a, T> for u32 {
-   |          - help: consider adding an explicit lifetime bound `T: 'a`...
-LL |     type Out = RefOk<'a, T>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-struct-not-wf.rs:31:5
-   |
-LL |     type Out = RefOk<'a, T>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0491]: in type `&'a &'b T`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-struct-not-wf.rs:35:5
-   |
-LL |     type Out = &'a &'b T;
-   |     ^^^^^^^^^^^^^^^^^^^^^
-   |
-note: the pointer is valid for the lifetime 'a as defined on the impl at 34:6
-  --> $DIR/regions-struct-not-wf.rs:34:6
-   |
-LL | impl<'a, 'b, T> Trait1<'a, 'b, T> for u32 {
-   |      ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 34:10
-  --> $DIR/regions-struct-not-wf.rs:34:10
-   |
-LL | impl<'a, 'b, T> Trait1<'a, 'b, T> for u32 {
-   |          ^^
-
-error: aborting due to 3 previous errors
-
-Some errors occurred: E0309, E0491.
-For more information about an error, try `rustc --explain E0309`.
diff --git a/src/test/ui/resolve/issue-22692.rs b/src/test/ui/resolve/issue-22692.rs
index 06648c5..600dd16 100644
--- a/src/test/ui/resolve/issue-22692.rs
+++ b/src/test/ui/resolve/issue-22692.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let _ = String.new();
+    let _ = String.new(); //~ ERROR expected value, found struct `String`
 }
diff --git a/src/test/ui/resolve/issue-22692.stderr b/src/test/ui/resolve/issue-22692.stderr
index ecdd4ff..b964d3d 100644
--- a/src/test/ui/resolve/issue-22692.stderr
+++ b/src/test/ui/resolve/issue-22692.stderr
@@ -1,7 +1,7 @@
 error[E0423]: expected value, found struct `String`
   --> $DIR/issue-22692.rs:12:13
    |
-LL |     let _ = String.new();
+LL |     let _ = String.new(); //~ ERROR expected value, found struct `String`
    |             ^^^^^^----
    |             |
    |             help: use `::` to access an associated function: `String::new`
diff --git a/src/test/ui/resolve/issue-24968.stderr b/src/test/ui/resolve/issue-24968.stderr
index 9a1d5ea..cfb2034 100644
--- a/src/test/ui/resolve/issue-24968.stderr
+++ b/src/test/ui/resolve/issue-24968.stderr
@@ -2,7 +2,7 @@
   --> $DIR/issue-24968.rs:11:11
    |
 LL | fn foo(_: Self) {
-   |           ^^^^ `Self` is only available in traits and impls
+   |           ^^^^ `Self` is only available in impls, traits, and type definitions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/issue-54379.rs b/src/test/ui/resolve/issue-54379.rs
index 24aa758..60949a6 100644
--- a/src/test/ui/resolve/issue-54379.rs
+++ b/src/test/ui/resolve/issue-54379.rs
@@ -15,7 +15,9 @@
     let thing = MyStruct { s1: None };
 
     match thing {
-        MyStruct { .., Some(_) } => {},
+        MyStruct { .., Some(_) } => {}, //~ ERROR pattern does not mention field `s1`
+        //~^ ERROR expected `,`
+        //~| ERROR expected `}`, found `,`
         _ => {}
     }
 }
diff --git a/src/test/ui/resolve/issue-54379.stderr b/src/test/ui/resolve/issue-54379.stderr
index d1d693a..49612a4 100644
--- a/src/test/ui/resolve/issue-54379.stderr
+++ b/src/test/ui/resolve/issue-54379.stderr
@@ -1,7 +1,7 @@
 error: expected `}`, found `,`
   --> $DIR/issue-54379.rs:18:22
    |
-LL |         MyStruct { .., Some(_) } => {},
+LL |         MyStruct { .., Some(_) } => {}, //~ ERROR pattern does not mention field `s1`
    |                    --^
    |                    | |
    |                    | expected `}`
@@ -10,13 +10,13 @@
 error: expected `,`
   --> $DIR/issue-54379.rs:18:24
    |
-LL |         MyStruct { .., Some(_) } => {},
+LL |         MyStruct { .., Some(_) } => {}, //~ ERROR pattern does not mention field `s1`
    |                        ^^^^
 
 error[E0027]: pattern does not mention field `s1`
   --> $DIR/issue-54379.rs:18:9
    |
-LL |         MyStruct { .., Some(_) } => {},
+LL |         MyStruct { .., Some(_) } => {}, //~ ERROR pattern does not mention field `s1`
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ missing field `s1`
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/resolve/resolve-self-in-impl-2.stderr b/src/test/ui/resolve/resolve-self-in-impl-2.stderr
index 183b9b6..b3a8261 100644
--- a/src/test/ui/resolve/resolve-self-in-impl-2.stderr
+++ b/src/test/ui/resolve/resolve-self-in-impl-2.stderr
@@ -2,7 +2,7 @@
   --> $DIR/resolve-self-in-impl-2.rs:14:6
    |
 LL | impl Self for S {} //~ ERROR expected trait, found self type `Self`
-   |      ^^^^ `Self` is only available in traits and impls
+   |      ^^^^ `Self` is only available in impls, traits, and type definitions
 
 error[E0405]: cannot find trait `N` in `Self`
   --> $DIR/resolve-self-in-impl-2.rs:15:12
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.rs b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.rs
index bdd7081..e8bb584 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.rs
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.rs
@@ -20,7 +20,7 @@
 }
 
 impl<'a, T> Trait<'a, T> for usize {
-    type Out = &'a T;
+    type Out = &'a T; //~ ERROR `T` may not live long enough
 }
 
 struct RefOk<'a, T:'a> {
@@ -28,11 +28,11 @@
 }
 
 impl<'a, T> Trait<'a, T> for u32 {
-    type Out = RefOk<'a, T>;
+    type Out = RefOk<'a, T>; //~ ERROR `T` may not live long enough
 }
 
 impl<'a, 'b, T> Trait1<'a, 'b, T> for u32 {
-    type Out = &'a &'b T;
+    type Out = &'a &'b T; //~ ERROR reference has a longer lifetime than the data
 }
 
 fn main() { }
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
index d8c8b6c..35a4f0c 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
@@ -3,13 +3,13 @@
    |
 LL | impl<'a, T> Trait<'a, T> for usize {
    |          - help: consider adding an explicit lifetime bound `T: 'a`...
-LL |     type Out = &'a T;
+LL |     type Out = &'a T; //~ ERROR `T` may not live long enough
    |     ^^^^^^^^^^^^^^^^^
    |
 note: ...so that the reference type `&'a T` does not outlive the data it points at
   --> $DIR/regions-struct-not-wf.rs:23:5
    |
-LL |     type Out = &'a T;
+LL |     type Out = &'a T; //~ ERROR `T` may not live long enough
    |     ^^^^^^^^^^^^^^^^^
 
 error[E0309]: the parameter type `T` may not live long enough
@@ -17,19 +17,19 @@
    |
 LL | impl<'a, T> Trait<'a, T> for u32 {
    |          - help: consider adding an explicit lifetime bound `T: 'a`...
-LL |     type Out = RefOk<'a, T>;
+LL |     type Out = RefOk<'a, T>; //~ ERROR `T` may not live long enough
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: ...so that the type `T` will meet its required lifetime bounds
   --> $DIR/regions-struct-not-wf.rs:31:5
    |
-LL |     type Out = RefOk<'a, T>;
+LL |     type Out = RefOk<'a, T>; //~ ERROR `T` may not live long enough
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0491]: in type `&'a &'b T`, reference has a longer lifetime than the data it references
   --> $DIR/regions-struct-not-wf.rs:35:5
    |
-LL |     type Out = &'a &'b T;
+LL |     type Out = &'a &'b T; //~ ERROR reference has a longer lifetime than the data
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
 note: the pointer is valid for the lifetime 'a as defined on the impl at 34:6
diff --git a/src/test/ui/rfc-2166-underscore-imports/auxiliary/duplicate.rs b/src/test/ui/rfc-2166-underscore-imports/auxiliary/duplicate.rs
new file mode 100644
index 0000000..92d741b
--- /dev/null
+++ b/src/test/ui/rfc-2166-underscore-imports/auxiliary/duplicate.rs
@@ -0,0 +1,14 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::*;
+
+#[proc_macro_attribute]
+pub fn duplicate(_: TokenStream, input: TokenStream) -> TokenStream {
+    let clone = input.clone();
+    input.into_iter().chain(clone.into_iter()).collect()
+}
diff --git a/src/test/ui/rfc-2166-underscore-imports/auxiliary/underscore-imports.rs b/src/test/ui/rfc-2166-underscore-imports/auxiliary/underscore-imports.rs
new file mode 100644
index 0000000..70de916
--- /dev/null
+++ b/src/test/ui/rfc-2166-underscore-imports/auxiliary/underscore-imports.rs
@@ -0,0 +1,22 @@
+#![feature(underscore_imports)]
+
+#[macro_export]
+macro_rules! do_nothing {
+    () => ()
+}
+
+mod m1 {
+    pub trait InScope1 {
+        fn in_scope1(&self) {}
+    }
+    impl InScope1 for () {}
+}
+mod m2 {
+    pub trait InScope2 {
+        fn in_scope2(&self) {}
+    }
+    impl InScope2 for () {}
+}
+
+pub use m1::InScope1 as _;
+pub use m2::InScope2 as _;
diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.rs b/src/test/ui/rfc-2166-underscore-imports/basic.rs
index 104bd9e..64a8d07 100644
--- a/src/test/ui/rfc-2166-underscore-imports/basic.rs
+++ b/src/test/ui/rfc-2166-underscore-imports/basic.rs
@@ -9,10 +9,16 @@
 // except according to those terms.
 
 // compile-pass
+// aux-build:underscore-imports.rs
 
 #![feature(underscore_imports)]
 #![warn(unused_imports, unused_extern_crates)]
 
+#[macro_use]
+extern crate underscore_imports as _;
+
+do_nothing!(); // OK
+
 struct S;
 
 mod m {
diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.stderr b/src/test/ui/rfc-2166-underscore-imports/basic.stderr
index 2be0317..e1fe5cc 100644
--- a/src/test/ui/rfc-2166-underscore-imports/basic.stderr
+++ b/src/test/ui/rfc-2166-underscore-imports/basic.stderr
@@ -1,17 +1,17 @@
 warning: unused import: `m::Tr1 as _`
-  --> $DIR/basic.rs:31:9
+  --> $DIR/basic.rs:37:9
    |
 LL |     use m::Tr1 as _; //~ WARN unused import
    |         ^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/basic.rs:14:9
+  --> $DIR/basic.rs:15:9
    |
 LL | #![warn(unused_imports, unused_extern_crates)]
    |         ^^^^^^^^^^^^^^
 
 warning: unused import: `S as _`
-  --> $DIR/basic.rs:32:9
+  --> $DIR/basic.rs:38:9
    |
 LL |     use S as _; //~ WARN unused import
    |         ^^^^^^
diff --git a/src/test/ui/rfc-2166-underscore-imports/duplicate.rs b/src/test/ui/rfc-2166-underscore-imports/duplicate.rs
new file mode 100644
index 0000000..92615c4
--- /dev/null
+++ b/src/test/ui/rfc-2166-underscore-imports/duplicate.rs
@@ -0,0 +1,17 @@
+// compile-pass
+// aux-build:duplicate.rs
+
+#![feature(underscore_imports)]
+
+extern crate duplicate;
+
+#[duplicate::duplicate]
+use main as _; // OK
+
+macro_rules! duplicate {
+    ($item: item) => { $item $item }
+}
+
+duplicate!(use std as _;); // OK
+
+fn main() {}
diff --git a/src/test/ui/rfc-2166-underscore-imports/intercrate.rs b/src/test/ui/rfc-2166-underscore-imports/intercrate.rs
new file mode 100644
index 0000000..8b5bb8b
--- /dev/null
+++ b/src/test/ui/rfc-2166-underscore-imports/intercrate.rs
@@ -0,0 +1,11 @@
+// compile-pass
+// aux-build:underscore-imports.rs
+
+extern crate underscore_imports;
+
+use underscore_imports::*;
+
+fn main() {
+    ().in_scope1();
+    ().in_scope2();
+}
diff --git a/src/test/ui/rfc-2166-underscore-imports/unused-2018.rs b/src/test/ui/rfc-2166-underscore-imports/unused-2018.rs
new file mode 100644
index 0000000..611eb3c
--- /dev/null
+++ b/src/test/ui/rfc-2166-underscore-imports/unused-2018.rs
@@ -0,0 +1,18 @@
+// edition:2018
+
+#![feature(underscore_imports)]
+#![deny(unused_imports)]
+
+mod multi_segment {
+    use core::any; //~ ERROR unused import: `core::any`
+}
+
+mod single_segment {
+    use core; //~ ERROR unused import: `core`
+}
+
+mod single_segment_underscore {
+    use core as _; // OK
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr b/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr
new file mode 100644
index 0000000..02b29b3
--- /dev/null
+++ b/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr
@@ -0,0 +1,20 @@
+error: unused import: `core::any`
+  --> $DIR/unused-2018.rs:7:9
+   |
+LL |     use core::any; //~ ERROR unused import: `core::any`
+   |         ^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/unused-2018.rs:4:9
+   |
+LL | #![deny(unused_imports)]
+   |         ^^^^^^^^^^^^^^
+
+error: unused import: `core`
+  --> $DIR/unused-2018.rs:11:9
+   |
+LL |     use core; //~ ERROR unused import: `core`
+   |         ^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
index f7216c5..3d24f49 100644
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
@@ -5,8 +5,6 @@
 // Tests ensuring that `dbg!(expr)` has the expected run-time behavior.
 // as well as some compile time properties we expect.
 
-#![feature(dbg_macro)]
-
 #[derive(Copy, Clone, Debug)]
 struct Unit;
 
@@ -57,31 +55,31 @@
 
 fn validate_stderr(stderr: Vec<String>) {
     assert_eq!(stderr, &[
-        ":23] Unit = Unit",
+        ":21] Unit = Unit",
 
-        ":24] a = Unit",
+        ":22] a = Unit",
 
-        ":30] Point{x: 42, y: 24,} = Point {",
+        ":28] Point{x: 42, y: 24,} = Point {",
         "    x: 42,",
         "    y: 24",
         "}",
 
-        ":31] b = Point {",
+        ":29] b = Point {",
         "    x: 42,",
         "    y: 24",
         "}",
 
-        ":40] &a = NoCopy(",
+        ":38] &a = NoCopy(",
         "    1337",
         ")",
 
-        ":40] dbg!(& a) = NoCopy(",
+        ":38] dbg!(& a) = NoCopy(",
         "    1337",
         ")",
-        ":45] f(&42) = 42",
+        ":43] f(&42) = 42",
 
         "before",
-        ":50] { foo += 1; eprintln!(\"before\"); 7331 } = 7331",
+        ":48] { foo += 1; eprintln!(\"before\"); 7331 } = 7331",
     ]);
 }
 
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.rs
deleted file mode 100644
index b237c6f..0000000
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-// Feature gate test for `dbg!(..)`.
-
-fn main() {
-    dbg!(1);
-}
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.stderr
deleted file mode 100644
index 64df1e1..0000000
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-feature-gate.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: macro dbg! is unstable (see issue #54306)
-  --> $DIR/dbg-macro-feature-gate.rs:4:5
-   |
-LL |     dbg!(1);
-   |     ^^^^^^^^
-   |
-   = help: add #![feature(dbg_macro)] 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/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr
index bf99fef..0b3f59f 100644
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.nll.stderr
@@ -1,9 +1,9 @@
 error[E0382]: use of moved value: `a`
-  --> $DIR/dbg-macro-move-semantics.rs:11:18
+  --> $DIR/dbg-macro-move-semantics.rs:9:18
    |
 LL |     let _ = dbg!(a);
    |             ------- value moved here
-LL |     let _ = dbg!(a);
+LL |     let _ = dbg!(a); //~ ERROR use of moved value
    |                  ^ value used here after move
    |
    = note: move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs
index bcf508d..e6ddb3d 100644
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs
@@ -1,12 +1,11 @@
 // Test ensuring that `dbg!(expr)` will take ownership of the argument.
 
-#![feature(dbg_macro)]
-
 #[derive(Debug)]
 struct NoCopy(usize);
 
 fn main() {
     let a = NoCopy(0);
     let _ = dbg!(a);
-    let _ = dbg!(a);
+    let _ = dbg!(a); //~ ERROR use of moved value
+    //~^ ERROR use of moved value
 }
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
index 1064317..5f3a6b4 100644
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
@@ -1,20 +1,20 @@
 error[E0382]: use of moved value: `a`
-  --> $DIR/dbg-macro-move-semantics.rs:11:18
+  --> $DIR/dbg-macro-move-semantics.rs:9:18
    |
 LL |     let _ = dbg!(a);
    |             ------- value moved here
-LL |     let _ = dbg!(a);
+LL |     let _ = dbg!(a); //~ ERROR use of moved value
    |                  ^ value used here after move
    |
    = note: move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
 error[E0382]: use of moved value: `a`
-  --> $DIR/dbg-macro-move-semantics.rs:11:13
+  --> $DIR/dbg-macro-move-semantics.rs:9:13
    |
 LL |     let _ = dbg!(a);
    |             ------- value moved here
-LL |     let _ = dbg!(a);
+LL |     let _ = dbg!(a); //~ ERROR use of moved value
    |             ^^^^^^^ value used here after move
    |
    = note: move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs
index 8e6f3b2..bdde484 100644
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs
@@ -1,9 +1,7 @@
 // Test ensuring that `dbg!(expr)` requires the passed type to implement `Debug`.
 
-#![feature(dbg_macro)]
-
 struct NotDebug;
 
 fn main() {
-    let _: NotDebug = dbg!(NotDebug);
+    let _: NotDebug = dbg!(NotDebug); //~ ERROR `NotDebug` doesn't implement `std::fmt::Debug`
 }
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr
index a3b6a17..bd41f7b 100644
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr
@@ -1,7 +1,7 @@
 error[E0277]: `NotDebug` doesn't implement `std::fmt::Debug`
-  --> $DIR/dbg-macro-requires-debug.rs:8:23
+  --> $DIR/dbg-macro-requires-debug.rs:6:23
    |
-LL |     let _: NotDebug = dbg!(NotDebug);
+LL |     let _: NotDebug = dbg!(NotDebug); //~ ERROR `NotDebug` doesn't implement `std::fmt::Debug`
    |                       ^^^^^^^^^^^^^^ `NotDebug` cannot be formatted using `{:?}`
    |
    = help: the trait `std::fmt::Debug` is not implemented for `NotDebug`
diff --git a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.rs b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.rs
index 9b59b24..0f67956 100644
--- a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(generic_associated_types)]
+#![feature(generic_associated_types)] //~ WARN `generic_associated_types` is incomplete
 
 // Checking the interaction with this other feature
 #![feature(associated_type_defaults)]
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 97d5482..8801ce3 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,6 +1,6 @@
 warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash
   --> $DIR/generic-associated-types-where.rs:11:12
    |
-LL | #![feature(generic_associated_types)]
+LL | #![feature(generic_associated_types)] //~ WARN `generic_associated_types` is incomplete
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/src/test/ui/rust-2018/auxiliary/edition-lint-paths.rs b/src/test/ui/rust-2018/auxiliary/edition-lint-paths.rs
index cc17a9b..dc4ab21 100644
--- a/src/test/ui/rust-2018/auxiliary/edition-lint-paths.rs
+++ b/src/test/ui/rust-2018/auxiliary/edition-lint-paths.rs
@@ -9,3 +9,14 @@
 // except according to those terms.
 
 pub fn foo() {}
+
+#[macro_export]
+macro_rules! macro_2015 {
+    () => {
+        use edition_lint_paths as other_name;
+        use edition_lint_paths::foo as other_foo;
+        fn check_macro_2015() {
+            ::edition_lint_paths::foo();
+        }
+    }
+}
diff --git a/src/test/ui-fulldeps/rust-2018/auxiliary/suggestions-not-always-applicable.rs b/src/test/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs
similarity index 97%
rename from src/test/ui-fulldeps/rust-2018/auxiliary/suggestions-not-always-applicable.rs
rename to src/test/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs
index 7ae4731..b8a05e8 100644
--- a/src/test/ui-fulldeps/rust-2018/auxiliary/suggestions-not-always-applicable.rs
+++ b/src/test/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/ui/rust-2018/dyn-trait-compatibility.rs b/src/test/ui/rust-2018/dyn-trait-compatibility.rs
index 9548df5..377c85f 100644
--- a/src/test/ui/rust-2018/dyn-trait-compatibility.rs
+++ b/src/test/ui/rust-2018/dyn-trait-compatibility.rs
@@ -1,7 +1,7 @@
 // edition:2018
 
 type A0 = dyn;
-type A1 = dyn::dyn; //~ERROR expected identifier, found reserved keyword
+type A1 = dyn::dyn; //~ERROR expected identifier, found keyword `dyn`
 type A2 = dyn<dyn, dyn>; //~ERROR expected identifier, found `<`
 type A3 = dyn<<dyn as dyn>::dyn>;
 
diff --git a/src/test/ui/rust-2018/dyn-trait-compatibility.stderr b/src/test/ui/rust-2018/dyn-trait-compatibility.stderr
index ea04833..bd72f9c 100644
--- a/src/test/ui/rust-2018/dyn-trait-compatibility.stderr
+++ b/src/test/ui/rust-2018/dyn-trait-compatibility.stderr
@@ -1,8 +1,8 @@
-error: expected identifier, found reserved keyword `dyn`
+error: expected identifier, found keyword `dyn`
   --> $DIR/dyn-trait-compatibility.rs:4:16
    |
-LL | type A1 = dyn::dyn; //~ERROR expected identifier, found reserved keyword
-   |                ^^^ expected identifier, found reserved keyword
+LL | type A1 = dyn::dyn; //~ERROR expected identifier, found keyword `dyn`
+   |                ^^^ expected identifier, found keyword
 
 error: expected identifier, found `<`
   --> $DIR/dyn-trait-compatibility.rs:5:14
diff --git a/src/test/ui/rust-2018/edition-lint-paths-2018.rs b/src/test/ui/rust-2018/edition-lint-paths-2018.rs
new file mode 100644
index 0000000..09b31be
--- /dev/null
+++ b/src/test/ui/rust-2018/edition-lint-paths-2018.rs
@@ -0,0 +1,10 @@
+// compile-pass
+// edition:2018
+// compile-flags:--extern edition_lint_paths
+// aux-build:edition-lint-paths.rs
+
+#![deny(absolute_paths_not_starting_with_crate)]
+
+edition_lint_paths::macro_2015!(); // OK
+
+fn main() {}
diff --git a/src/test/ui/rust-2018/local-path-suggestions-2015.rs b/src/test/ui/rust-2018/local-path-suggestions-2015.rs
index c691d29..89fed56 100644
--- a/src/test/ui/rust-2018/local-path-suggestions-2015.rs
+++ b/src/test/ui/rust-2018/local-path-suggestions-2015.rs
@@ -31,6 +31,6 @@
 
 use foo::Bar;
 
-use foobar::Baz;
+use foobar::Baz; //~ ERROR unresolved import `foobar`
 
 fn main() { }
diff --git a/src/test/ui/rust-2018/local-path-suggestions-2015.stderr b/src/test/ui/rust-2018/local-path-suggestions-2015.stderr
index 741b2ca..3f56b98 100644
--- a/src/test/ui/rust-2018/local-path-suggestions-2015.stderr
+++ b/src/test/ui/rust-2018/local-path-suggestions-2015.stderr
@@ -1,7 +1,7 @@
 error[E0432]: unresolved import `foobar`
   --> $DIR/local-path-suggestions-2015.rs:34:5
    |
-LL | use foobar::Baz;
+LL | use foobar::Baz; //~ ERROR unresolved import `foobar`
    |     ^^^^^^ did you mean `aux_baz::foobar`?
 
 error: aborting due to previous error
diff --git a/src/test/ui-fulldeps/rust-2018/proc-macro-crate-in-paths.rs b/src/test/ui/rust-2018/proc-macro-crate-in-paths.rs
similarity index 95%
rename from src/test/ui-fulldeps/rust-2018/proc-macro-crate-in-paths.rs
rename to src/test/ui/rust-2018/proc-macro-crate-in-paths.rs
index 1068c05..51314ab 100644
--- a/src/test/ui-fulldeps/rust-2018/proc-macro-crate-in-paths.rs
+++ b/src/test/ui/rust-2018/proc-macro-crate-in-paths.rs
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // compile-pass
+// force-host
+// no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
 #![deny(rust_2018_compatibility)]
diff --git a/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.fixed b/src/test/ui/rust-2018/suggestions-not-always-applicable.fixed
similarity index 100%
rename from src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.fixed
rename to src/test/ui/rust-2018/suggestions-not-always-applicable.fixed
diff --git a/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs b/src/test/ui/rust-2018/suggestions-not-always-applicable.rs
similarity index 100%
rename from src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs
rename to src/test/ui/rust-2018/suggestions-not-always-applicable.rs
diff --git a/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.stderr b/src/test/ui/rust-2018/suggestions-not-always-applicable.stderr
similarity index 100%
rename from src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.stderr
rename to src/test/ui/rust-2018/suggestions-not-always-applicable.stderr
diff --git a/src/test/ui/rust-2018/trait-import-suggestions.rs b/src/test/ui/rust-2018/trait-import-suggestions.rs
index d603d82..9e5e698 100644
--- a/src/test/ui/rust-2018/trait-import-suggestions.rs
+++ b/src/test/ui/rust-2018/trait-import-suggestions.rs
@@ -29,13 +29,13 @@
 
     fn in_foo() {
         let x: u32 = 22;
-        x.foobar();
+        x.foobar(); //~ ERROR no method named `foobar`
     }
 }
 
 fn main() {
     let x: u32 = 22;
-    x.bar();
-    x.baz();
-    let y = u32::from_str("33");
+    x.bar(); //~ ERROR no method named `bar`
+    x.baz(); //~ ERROR no method named `baz`
+    let y = u32::from_str("33"); //~ ERROR no function or associated item named `from_str`
 }
diff --git a/src/test/ui/rust-2018/trait-import-suggestions.stderr b/src/test/ui/rust-2018/trait-import-suggestions.stderr
index 59fe7b9..d5d996e 100644
--- a/src/test/ui/rust-2018/trait-import-suggestions.stderr
+++ b/src/test/ui/rust-2018/trait-import-suggestions.stderr
@@ -1,7 +1,7 @@
 error[E0599]: no method named `foobar` found for type `u32` in the current scope
   --> $DIR/trait-import-suggestions.rs:32:11
    |
-LL |         x.foobar();
+LL |         x.foobar(); //~ ERROR no method named `foobar`
    |           ^^^^^^
    |
    = help: items from traits can only be used if the trait is in scope
@@ -11,7 +11,7 @@
 error[E0599]: no method named `bar` found for type `u32` in the current scope
   --> $DIR/trait-import-suggestions.rs:38:7
    |
-LL |     x.bar();
+LL |     x.bar(); //~ ERROR no method named `bar`
    |       ^^^
    |
    = help: items from traits can only be used if the trait is in scope
@@ -23,13 +23,13 @@
 error[E0599]: no method named `baz` found for type `u32` in the current scope
   --> $DIR/trait-import-suggestions.rs:39:7
    |
-LL |     x.baz();
+LL |     x.baz(); //~ ERROR no method named `baz`
    |       ^^^
 
 error[E0599]: no function or associated item named `from_str` found for type `u32` in the current scope
   --> $DIR/trait-import-suggestions.rs:40:13
    |
-LL |     let y = u32::from_str("33");
+LL |     let y = u32::from_str("33"); //~ ERROR no function or associated item named `from_str`
    |             ^^^^^^^^^^^^^ function or associated item not found in `u32`
    |
    = help: items from traits can only be used if the trait is in scope
diff --git a/src/test/ui/self/self_type_keyword-2.rs b/src/test/ui/self/self_type_keyword-2.rs
index bbaf060..8331ae0 100644
--- a/src/test/ui/self/self_type_keyword-2.rs
+++ b/src/test/ui/self/self_type_keyword-2.rs
@@ -13,14 +13,11 @@
 pub fn main() {
     let Self = 5;
     //~^ ERROR cannot find unit struct/variant or constant `Self` in this scope
-    //~^^ ERROR `Self` struct constructors are unstable (see issue #51994)
 
     match 15 {
         Self => (),
         //~^ ERROR cannot find unit struct/variant or constant `Self` in this scope
-        //~^^ ERROR `Self` struct constructors are unstable (see issue #51994)
         Foo { x: Self } => (),
         //~^ ERROR cannot find unit struct/variant or constant `Self` in this scope
-        //~^^ ERROR `Self` struct constructors are unstable (see issue #51994)
     }
 }
diff --git a/src/test/ui/self/self_type_keyword-2.stderr b/src/test/ui/self/self_type_keyword-2.stderr
index 8252997..972e5bd 100644
--- a/src/test/ui/self/self_type_keyword-2.stderr
+++ b/src/test/ui/self/self_type_keyword-2.stderr
@@ -11,42 +11,18 @@
    |         ^^^^ not found in this scope
 
 error[E0531]: cannot find unit struct/variant or constant `Self` in this scope
-  --> $DIR/self_type_keyword-2.rs:19:9
+  --> $DIR/self_type_keyword-2.rs:18:9
    |
 LL |         Self => (),
    |         ^^^^ not found in this scope
 
 error[E0531]: cannot find unit struct/variant or constant `Self` in this scope
-  --> $DIR/self_type_keyword-2.rs:22:18
+  --> $DIR/self_type_keyword-2.rs:20:18
    |
 LL |         Foo { x: Self } => (),
    |                  ^^^^ not found in this scope
 
-error[E0658]: `Self` struct constructors are unstable (see issue #51994)
-  --> $DIR/self_type_keyword-2.rs:14:9
-   |
-LL |     let Self = 5;
-   |         ^^^^
-   |
-   = help: add #![feature(self_struct_ctor)] to the crate attributes to enable
+error: aborting due to 4 previous errors
 
-error[E0658]: `Self` struct constructors are unstable (see issue #51994)
-  --> $DIR/self_type_keyword-2.rs:19:9
-   |
-LL |         Self => (),
-   |         ^^^^
-   |
-   = help: add #![feature(self_struct_ctor)] to the crate attributes to enable
-
-error[E0658]: `Self` struct constructors are unstable (see issue #51994)
-  --> $DIR/self_type_keyword-2.rs:22:18
-   |
-LL |         Foo { x: Self } => (),
-   |                  ^^^^
-   |
-   = help: add #![feature(self_struct_ctor)] to the crate attributes to enable
-
-error: aborting due to 7 previous errors
-
-Some errors occurred: E0432, E0531, E0658.
+Some errors occurred: E0432, E0531.
 For more information about an error, try `rustc --explain E0432`.
diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.rs b/src/test/ui/suggestions/suggest-move-lifetimes.rs
new file mode 100644
index 0000000..6b26f12
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-move-lifetimes.rs
@@ -0,0 +1,21 @@
+struct A<T, 'a> { //~ ERROR lifetime parameters must be declared
+    t: &'a T,
+}
+
+struct B<T, 'a, U> { //~ ERROR lifetime parameters must be declared
+    t: &'a T,
+    u: U,
+}
+
+struct C<T, U, 'a> { //~ ERROR lifetime parameters must be declared
+    t: &'a T,
+    u: U,
+}
+
+struct D<T, U, 'a, 'b, V, 'c> { //~ ERROR lifetime parameters must be declared
+    t: &'a T,
+    u: &'b U,
+    v: &'c V,
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
new file mode 100644
index 0000000..72a2cbe
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
@@ -0,0 +1,42 @@
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/suggest-move-lifetimes.rs:1:13
+   |
+LL | struct A<T, 'a> { //~ ERROR lifetime parameters must be declared
+   |             ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct A<'a, T> { //~ ERROR lifetime parameters must be declared
+   |          ^^^ --
+
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/suggest-move-lifetimes.rs:5:13
+   |
+LL | struct B<T, 'a, U> { //~ ERROR lifetime parameters must be declared
+   |             ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct B<'a, T, U> { //~ ERROR lifetime parameters must be declared
+   |          ^^^   --
+
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/suggest-move-lifetimes.rs:10:16
+   |
+LL | struct C<T, U, 'a> { //~ ERROR lifetime parameters must be declared
+   |                ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct C<'a, T, U> { //~ ERROR lifetime parameters must be declared
+   |          ^^^    --
+
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/suggest-move-lifetimes.rs:15:16
+   |
+LL | struct D<T, U, 'a, 'b, V, 'c> { //~ ERROR lifetime parameters must be declared
+   |                ^^  ^^     ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct D<'a, 'b, 'c, T, U, V> { //~ ERROR lifetime parameters must be declared
+   |          ^^^ ^^^ ^^^      ---
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/suggestions/suggest-variants.rs b/src/test/ui/suggestions/suggest-variants.rs
index 4a131ed..6d6e280 100644
--- a/src/test/ui/suggestions/suggest-variants.rs
+++ b/src/test/ui/suggestions/suggest-variants.rs
@@ -9,7 +9,7 @@
 }
 
 fn main() {
-    println!("My shape is {:?}", Shape::Squareee { size: 5});
-    println!("My shape is {:?}", Shape::Circl { size: 5});
-    println!("My shape is {:?}", Shape::Rombus{ size: 5});
+    println!("My shape is {:?}", Shape::Squareee { size: 5});  //~ ERROR no variant `Squareee`
+    println!("My shape is {:?}", Shape::Circl { size: 5}); //~ ERROR no variant `Circl`
+    println!("My shape is {:?}", Shape::Rombus{ size: 5}); //~ ERROR no variant `Rombus`
 }
diff --git a/src/test/ui/suggestions/suggest-variants.stderr b/src/test/ui/suggestions/suggest-variants.stderr
index 08ae68e..36abda2 100644
--- a/src/test/ui/suggestions/suggest-variants.stderr
+++ b/src/test/ui/suggestions/suggest-variants.stderr
@@ -1,19 +1,19 @@
 error: no variant `Squareee` on enum `Shape`
   --> $DIR/suggest-variants.rs:12:34
    |
-LL |     println!("My shape is {:?}", Shape::Squareee { size: 5});
+LL |     println!("My shape is {:?}", Shape::Squareee { size: 5});  //~ ERROR no variant `Squareee`
    |                                  ^^^^^^^^^^^^^^^ help: did you mean: `Shape::Square`
 
 error: no variant `Circl` on enum `Shape`
   --> $DIR/suggest-variants.rs:13:34
    |
-LL |     println!("My shape is {:?}", Shape::Circl { size: 5});
+LL |     println!("My shape is {:?}", Shape::Circl { size: 5}); //~ ERROR no variant `Circl`
    |                                  ^^^^^^^^^^^^ help: did you mean: `Shape::Circle`
 
 error: no variant `Rombus` on enum `Shape`
   --> $DIR/suggest-variants.rs:14:34
    |
-LL |     println!("My shape is {:?}", Shape::Rombus{ size: 5});
+LL |     println!("My shape is {:?}", Shape::Rombus{ size: 5}); //~ ERROR no variant `Rombus`
    |                                  ^^^^^^^^^^^^^ unknown variant
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
index 58e7718..a3cc53e 100644
--- a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
+++ b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
@@ -3,6 +3,11 @@
     type B;
     type C;
 }
- pub struct Foo { i: Box<T<usize, usize, usize, usize, B=usize>> }
+pub struct Foo {
+    i: Box<T<usize, usize, usize, usize, B=usize>>,
+    //~^ ERROR must be specified
+    //~| ERROR wrong number of type arguments
+}
 
- fn main() {}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
index b62b5d3..16e9fa9 100644
--- a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
+++ b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
@@ -1,29 +1,29 @@
 error[E0107]: wrong number of type arguments: expected 2, found 4
-  --> $DIR/use-type-argument-instead-of-assoc-type.rs:6:42
+  --> $DIR/use-type-argument-instead-of-assoc-type.rs:7:28
    |
-LL |  pub struct Foo { i: Box<T<usize, usize, usize, usize, B=usize>> }
-   |                                          ^^^^^  ^^^^^ unexpected type argument
-   |                                          |
-   |                                          unexpected type argument
+LL |     i: Box<T<usize, usize, usize, usize, B=usize>>,
+   |                            ^^^^^  ^^^^^ unexpected type argument
+   |                            |
+   |                            unexpected type argument
 
 error[E0191]: the value of the associated types `A` (from the trait `T`), `C` (from the trait `T`) must be specified
-  --> $DIR/use-type-argument-instead-of-assoc-type.rs:6:26
+  --> $DIR/use-type-argument-instead-of-assoc-type.rs:7:12
    |
 LL |     type A;
    |     ------- `A` defined here
 LL |     type B;
 LL |     type C;
    |     ------- `C` defined here
-LL | }
-LL |  pub struct Foo { i: Box<T<usize, usize, usize, usize, B=usize>> }
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                          |
-   |                          associated type `A` must be specified
-   |                          associated type `C` must be specified
+...
+LL |     i: Box<T<usize, usize, usize, usize, B=usize>>,
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            |
+   |            associated type `A` must be specified
+   |            associated type `C` must be specified
 help: if you meant to specify the associated types, write
    |
-LL |  pub struct Foo { i: Box<T<usize, usize, A = usize, C = usize, B=usize>> }
-   |                                          ^^^^^^^^^  ^^^^^^^^^
+LL |     i: Box<T<usize, usize, A = usize, C = usize, B=usize>>,
+   |                            ^^^^^^^^^  ^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/trait-alias-impl.rs b/src/test/ui/traits/trait-alias-impl.rs
index bf34830..802fdd0 100644
--- a/src/test/ui/traits/trait-alias-impl.rs
+++ b/src/test/ui/traits/trait-alias-impl.rs
@@ -12,6 +12,6 @@
 
 trait DefaultAlias = Default;
 
-impl DefaultAlias for () {}
+impl DefaultAlias for () {} //~ ERROR expected trait, found trait alias
 
 fn main() {}
diff --git a/src/test/ui/traits/trait-alias-impl.stderr b/src/test/ui/traits/trait-alias-impl.stderr
index 9ad6251..f94e4a4 100644
--- a/src/test/ui/traits/trait-alias-impl.stderr
+++ b/src/test/ui/traits/trait-alias-impl.stderr
@@ -1,7 +1,7 @@
 error[E0404]: expected trait, found trait alias `DefaultAlias`
   --> $DIR/trait-alias-impl.rs:15:6
    |
-LL | impl DefaultAlias for () {}
+LL | impl DefaultAlias for () {} //~ ERROR expected trait, found trait alias
    |      ^^^^^^^^^^^^ not a trait
 
 error: aborting due to previous error
diff --git a/src/test/ui/traits/trait-alias-object.rs b/src/test/ui/traits/trait-alias-object.rs
index 3adcd84..4694135 100644
--- a/src/test/ui/traits/trait-alias-object.rs
+++ b/src/test/ui/traits/trait-alias-object.rs
@@ -14,6 +14,6 @@
 trait IteratorAlias = Iterator;
 
 fn main() {
-    let _: &dyn EqAlias = &123;
-    let _: &dyn IteratorAlias = &vec![123].into_iter();
+    let _: &dyn EqAlias = &123; //~ ERROR `EqAlias` cannot be made into an object
+    let _: &dyn IteratorAlias = &vec![123].into_iter(); //~ ERROR must be specified
 }
diff --git a/src/test/ui/traits/trait-alias-object.stderr b/src/test/ui/traits/trait-alias-object.stderr
index fdb9427..9d9c142 100644
--- a/src/test/ui/traits/trait-alias-object.stderr
+++ b/src/test/ui/traits/trait-alias-object.stderr
@@ -1,7 +1,7 @@
 error[E0038]: the trait `EqAlias` cannot be made into an object
   --> $DIR/trait-alias-object.rs:17:13
    |
-LL |     let _: &dyn EqAlias = &123;
+LL |     let _: &dyn EqAlias = &123; //~ ERROR `EqAlias` cannot be made into an object
    |             ^^^^^^^^^^^ the trait `EqAlias` cannot be made into an object
    |
    = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses
@@ -9,7 +9,7 @@
 error[E0191]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified
   --> $DIR/trait-alias-object.rs:18:13
    |
-LL |     let _: &dyn IteratorAlias = &vec![123].into_iter();
+LL |     let _: &dyn IteratorAlias = &vec![123].into_iter(); //~ ERROR must be specified
    |             ^^^^^^^^^^^^^^^^^ associated type `Item` must be specified
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/traits/trait-alias-wf.rs b/src/test/ui/traits/trait-alias-wf.rs
index 8c8ce12..59ac5a0 100644
--- a/src/test/ui/traits/trait-alias-wf.rs
+++ b/src/test/ui/traits/trait-alias-wf.rs
@@ -12,6 +12,6 @@
 
 trait Foo {}
 trait A<T: Foo> {}
-trait B<T> = A<T>; // T cannot be unbounded
+trait B<T> = A<T>; //~ ERROR `T: Foo` is not satisfied
 
 fn main() {}
diff --git a/src/test/ui/traits/trait-alias-wf.stderr b/src/test/ui/traits/trait-alias-wf.stderr
index e8c81c8..cae571c 100644
--- a/src/test/ui/traits/trait-alias-wf.stderr
+++ b/src/test/ui/traits/trait-alias-wf.stderr
@@ -1,7 +1,7 @@
 error[E0277]: the trait bound `T: Foo` is not satisfied
   --> $DIR/trait-alias-wf.rs:15:1
    |
-LL | trait B<T> = A<T>; // T cannot be unbounded
+LL | trait B<T> = A<T>; //~ ERROR `T: Foo` is not satisfied
    | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `T`
    |
    = help: consider adding a `where T: Foo` bound
diff --git a/src/test/ui/underscore-lifetime/underscore-outlives-bounds.rs b/src/test/ui/underscore-lifetime/underscore-outlives-bounds.rs
index b514ff4..567cc7a 100644
--- a/src/test/ui/underscore-lifetime/underscore-outlives-bounds.rs
+++ b/src/test/ui/underscore-lifetime/underscore-outlives-bounds.rs
@@ -4,5 +4,5 @@
 // #54902
 
 trait Foo<'a> {}
-impl<'b: '_> Foo<'b> for i32 {}
+impl<'b: '_> Foo<'b> for i32 {} //~ ERROR `'_` cannot be used here
 fn main() { }
diff --git a/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr b/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr
index 4b38a26..e4ff653 100644
--- a/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr
+++ b/src/test/ui/underscore-lifetime/underscore-outlives-bounds.stderr
@@ -1,7 +1,7 @@
 error[E0637]: `'_` cannot be used here
   --> $DIR/underscore-outlives-bounds.rs:7:10
    |
-LL | impl<'b: '_> Foo<'b> for i32 {}
+LL | impl<'b: '_> Foo<'b> for i32 {} //~ ERROR `'_` cannot be used here
    |          ^^ `'_` is a reserved lifetime name
 
 error: aborting due to previous error
diff --git a/src/test/ui/underscore_const_names_feature_gate.stderr b/src/test/ui/underscore_const_names_feature_gate.stderr
deleted file mode 100644
index c97b3f8..0000000
--- a/src/test/ui/underscore_const_names_feature_gate.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0658]: naming constants with `_` is unstable (see issue #54912)
-  --> $DIR/underscore_const_names_feature_gate.rs:11:1
-   |
-LL | const _: () = (); //~ ERROR is unstable
-   | ^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(underscore_const_names)] to the crate attributes to enable
-
-error[E0658]: naming constants with `_` is unstable (see issue #54912)
-  --> $DIR/underscore_const_names_feature_gate.rs:12:1
-   |
-LL | static _: () = (); //~ ERROR is unstable
-   | ^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(underscore_const_names)] 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/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
index 83fd736..f4974b8 100644
--- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
+++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
@@ -4,7 +4,7 @@
 LL |     let _ = match x {   //~ ERROR non-exhaustive
    |                   ^ pattern `Err(_)` not covered
 
-error[E0004]: non-exhaustive patterns: type &Void is non-empty
+error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:20:19
    |
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
@@ -16,7 +16,7 @@
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
    |                   ^
 
-error[E0004]: non-exhaustive patterns: type (Void,) is non-empty
+error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:23:19
    |
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
@@ -28,7 +28,7 @@
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
    |                   ^
 
-error[E0004]: non-exhaustive patterns: type [Void; 1] is non-empty
+error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:26:19
    |
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
diff --git a/src/test/ui-fulldeps/unnecessary-extern-crate.rs b/src/test/ui/unnecessary-extern-crate.rs
similarity index 67%
rename from src/test/ui-fulldeps/unnecessary-extern-crate.rs
rename to src/test/ui/unnecessary-extern-crate.rs
index 1cdc922..110cfef 100644
--- a/src/test/ui-fulldeps/unnecessary-extern-crate.rs
+++ b/src/test/ui/unnecessary-extern-crate.rs
@@ -13,10 +13,10 @@
 #![deny(unused_extern_crates)]
 #![feature(alloc, test, libc, crate_visibility_modifier)]
 
-extern crate alloc;
+extern crate libc;
 //~^ ERROR unused extern crate
 //~| HELP remove
-extern crate alloc as x;
+extern crate libc as x;
 //~^ ERROR unused extern crate
 //~| HELP remove
 
@@ -27,22 +27,22 @@
 
 pub extern crate test as y;
 
-pub extern crate libc;
+pub extern crate alloc;
 
-pub(crate) extern crate libc as a;
+pub(crate) extern crate alloc as a;
 
-crate extern crate libc as b;
+crate extern crate alloc as b;
 
 mod foo {
-    pub(in crate::foo) extern crate libc as c;
+    pub(in crate::foo) extern crate alloc as c;
 
-    pub(super) extern crate libc as d;
+    pub(super) extern crate alloc as d;
 
-    extern crate alloc;
+    extern crate libc;
     //~^ ERROR unused extern crate
     //~| HELP remove
 
-    extern crate alloc as x;
+    extern crate libc as x;
     //~^ ERROR unused extern crate
     //~| HELP remove
 
@@ -51,35 +51,31 @@
     pub extern crate test as y;
 
     mod bar {
-        extern crate alloc;
+        extern crate libc;
         //~^ ERROR unused extern crate
         //~| HELP remove
 
-        extern crate alloc as x;
+        extern crate libc as x;
         //~^ ERROR unused extern crate
         //~| HELP remove
 
-        pub(in crate::foo::bar) extern crate libc as e;
+        pub(in crate::foo::bar) extern crate alloc as e;
 
         fn dummy() {
-            unsafe {
-                e::getpid();
-            }
+            e::string::String::new();
         }
     }
 
     fn dummy() {
-        unsafe {
-            c::getpid();
-            d::getpid();
-        }
+        c::string::String::new();
+        d::string::String::new();
     }
 }
 
 
 fn main() {
-    unsafe { a::getpid(); }
-    unsafe { b::getpid(); }
+    a::string::String::new();
+    b::string::String::new();
 
     proc_macro::TokenStream::new();
 }
diff --git a/src/test/ui/unnecessary-extern-crate.stderr b/src/test/ui/unnecessary-extern-crate.stderr
new file mode 100644
index 0000000..1315bff
--- /dev/null
+++ b/src/test/ui/unnecessary-extern-crate.stderr
@@ -0,0 +1,44 @@
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:16:1
+   |
+LL | extern crate libc;
+   | ^^^^^^^^^^^^^^^^^^ help: remove it
+   |
+note: lint level defined here
+  --> $DIR/unnecessary-extern-crate.rs:13:9
+   |
+LL | #![deny(unused_extern_crates)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:19:1
+   |
+LL | extern crate libc as x;
+   | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:41:5
+   |
+LL |     extern crate libc;
+   |     ^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:45:5
+   |
+LL |     extern crate libc as x;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:54:9
+   |
+LL |         extern crate libc;
+   |         ^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:58:9
+   |
+LL |         extern crate libc as x;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/unreachable/unreachable-loop-patterns.rs b/src/test/ui/unreachable/unreachable-loop-patterns.rs
index cfd829e..eae630f 100644
--- a/src/test/ui/unreachable/unreachable-loop-patterns.rs
+++ b/src/test/ui/unreachable/unreachable-loop-patterns.rs
@@ -8,14 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// compile-fail
+
 #![feature(never_type)]
 #![feature(exhaustive_patterns)]
+
+#![allow(unreachable_code)]
 #![deny(unreachable_patterns)]
 
-fn main() {
-    let x: &[!] = &[];
+enum Void {}
 
-    for _ in x {}
+impl Iterator for Void {
+    type Item = Void;
+
+    fn next(&mut self) -> Option<Void> {
+        None
+    }
+}
+
+fn main() {
+    for _ in unimplemented!() as Void {}
     //~^ ERROR unreachable pattern
 }
 
diff --git a/src/test/ui/unreachable/unreachable-loop-patterns.stderr b/src/test/ui/unreachable/unreachable-loop-patterns.stderr
index 724a92b..6cf8757 100644
--- a/src/test/ui/unreachable/unreachable-loop-patterns.stderr
+++ b/src/test/ui/unreachable/unreachable-loop-patterns.stderr
@@ -1,11 +1,11 @@
 error: unreachable pattern
-  --> $DIR/unreachable-loop-patterns.rs:18:9
+  --> $DIR/unreachable-loop-patterns.rs:30:9
    |
-LL |     for _ in x {}
+LL |     for _ in unimplemented!() as Void {}
    |         ^
    |
 note: lint level defined here
-  --> $DIR/unreachable-loop-patterns.rs:13:9
+  --> $DIR/unreachable-loop-patterns.rs:17:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/unsafe/ranged_ints.rs b/src/test/ui/unsafe/ranged_ints.rs
new file mode 100644
index 0000000..0fa2da9
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints.rs
@@ -0,0 +1,8 @@
+#![feature(rustc_attrs)]
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {
+    let _x = NonZero(0); //~ ERROR initializing type with `rustc_layout_scalar_valid_range` attr
+}
diff --git a/src/test/ui/unsafe/ranged_ints.stderr b/src/test/ui/unsafe/ranged_ints.stderr
new file mode 100644
index 0000000..f59a930
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints.stderr
@@ -0,0 +1,11 @@
+error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints.rs:7:14
+   |
+LL |     let _x = NonZero(0); //~ ERROR initializing type with `rustc_layout_scalar_valid_range` attr
+   |              ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr
+   |
+   = note: initializing a layout restricted type's field with a value outside the valid range is undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints2.rs b/src/test/ui/unsafe/ranged_ints2.rs
new file mode 100644
index 0000000..68ba120
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints2.rs
@@ -0,0 +1,9 @@
+#![feature(rustc_attrs)]
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {
+    let mut x = unsafe { NonZero(1) };
+    let y = &mut x.0; //~ ERROR mutation of layout constrained field is unsafe
+}
diff --git a/src/test/ui/unsafe/ranged_ints2.stderr b/src/test/ui/unsafe/ranged_ints2.stderr
new file mode 100644
index 0000000..ae63f47
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints2.stderr
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints2.rs:8:13
+   |
+LL |     let y = &mut x.0; //~ ERROR mutation of layout constrained field is unsafe
+   |             ^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints2_const.rs b/src/test/ui/unsafe/ranged_ints2_const.rs
new file mode 100644
index 0000000..a61e332
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints2_const.rs
@@ -0,0 +1,20 @@
+#![feature(rustc_attrs, const_let, const_fn)]
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {
+}
+
+const fn foo() -> NonZero<u32> {
+    let mut x = unsafe { NonZero(1) };
+    let y = &mut x.0; //~ ERROR references in constant functions may only refer to immutable
+    //~^ ERROR mutation of layout constrained field is unsafe
+    unsafe { NonZero(1) }
+}
+
+const fn bar() -> NonZero<u32> {
+    let mut x = unsafe { NonZero(1) };
+    let y = unsafe { &mut x.0 }; //~ ERROR references in constant functions may only refer to immut
+    unsafe { NonZero(1) }
+}
diff --git a/src/test/ui/unsafe/ranged_ints2_const.stderr b/src/test/ui/unsafe/ranged_ints2_const.stderr
new file mode 100644
index 0000000..f79792f
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints2_const.stderr
@@ -0,0 +1,24 @@
+error[E0017]: references in constant functions may only refer to immutable values
+  --> $DIR/ranged_ints2_const.rs:11:13
+   |
+LL |     let y = &mut x.0; //~ ERROR references in constant functions may only refer to immutable
+   |             ^^^^^^^^ constant functions require immutable values
+
+error[E0017]: references in constant functions may only refer to immutable values
+  --> $DIR/ranged_ints2_const.rs:18:22
+   |
+LL |     let y = unsafe { &mut x.0 }; //~ ERROR references in constant functions may only refer to immut
+   |                      ^^^^^^^^ constant functions require immutable values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints2_const.rs:11:13
+   |
+LL |     let y = &mut x.0; //~ ERROR references in constant functions may only refer to immutable
+   |             ^^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0017, E0133.
+For more information about an error, try `rustc --explain E0017`.
diff --git a/src/test/ui/unsafe/ranged_ints3.rs b/src/test/ui/unsafe/ranged_ints3.rs
new file mode 100644
index 0000000..47d67fa
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints3.rs
@@ -0,0 +1,11 @@
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {
+    let mut x = unsafe { NonZero(Cell::new(1)) };
+    let y = &x.0; //~ ERROR borrow of layout constrained field with interior mutability
+}
diff --git a/src/test/ui/unsafe/ranged_ints3.stderr b/src/test/ui/unsafe/ranged_ints3.stderr
new file mode 100644
index 0000000..311a058
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints3.stderr
@@ -0,0 +1,11 @@
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints3.rs:10:13
+   |
+LL |     let y = &x.0; //~ ERROR borrow of layout constrained field with interior mutability
+   |             ^^^^ borrow of layout constrained field with interior mutability
+   |
+   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints3_const.rs b/src/test/ui/unsafe/ranged_ints3_const.rs
new file mode 100644
index 0000000..6497b61
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints3_const.rs
@@ -0,0 +1,21 @@
+#![feature(rustc_attrs, const_let, const_fn)]
+
+use std::cell::Cell;
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {}
+
+const fn foo() -> NonZero<Cell<u32>> {
+    let mut x = unsafe { NonZero(Cell::new(1)) };
+    let y = &x.0; //~ ERROR cannot borrow a constant which may contain interior mutability
+    //~^ ERROR borrow of layout constrained field with interior mutability
+    unsafe { NonZero(Cell::new(1)) }
+}
+
+const fn bar() -> NonZero<Cell<u32>> {
+    let mut x = unsafe { NonZero(Cell::new(1)) };
+    let y = unsafe { &x.0 }; //~ ERROR cannot borrow a constant which may contain interior mut
+    unsafe { NonZero(Cell::new(1)) }
+}
diff --git a/src/test/ui/unsafe/ranged_ints3_const.stderr b/src/test/ui/unsafe/ranged_ints3_const.stderr
new file mode 100644
index 0000000..d83d757
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints3_const.stderr
@@ -0,0 +1,24 @@
+error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
+  --> $DIR/ranged_ints3_const.rs:12:13
+   |
+LL |     let y = &x.0; //~ ERROR cannot borrow a constant which may contain interior mutability
+   |             ^^^^
+
+error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
+  --> $DIR/ranged_ints3_const.rs:19:22
+   |
+LL |     let y = unsafe { &x.0 }; //~ ERROR cannot borrow a constant which may contain interior mut
+   |                      ^^^^
+
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints3_const.rs:12:13
+   |
+LL |     let y = &x.0; //~ ERROR cannot borrow a constant which may contain interior mutability
+   |             ^^^^ borrow of layout constrained field with interior mutability
+   |
+   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0133, E0492.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints4.rs b/src/test/ui/unsafe/ranged_ints4.rs
new file mode 100644
index 0000000..d8632c4
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints4.rs
@@ -0,0 +1,9 @@
+#![feature(rustc_attrs)]
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {
+    let mut x = unsafe { NonZero(1) };
+    x.0 = 0; //~ ERROR mutation of layout constrained field is unsafe
+}
diff --git a/src/test/ui/unsafe/ranged_ints4.stderr b/src/test/ui/unsafe/ranged_ints4.stderr
new file mode 100644
index 0000000..c6468b6
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints4.stderr
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints4.rs:8:5
+   |
+LL |     x.0 = 0; //~ ERROR mutation of layout constrained field is unsafe
+   |     ^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints4_const.rs b/src/test/ui/unsafe/ranged_ints4_const.rs
new file mode 100644
index 0000000..f589e47
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints4_const.rs
@@ -0,0 +1,19 @@
+#![feature(rustc_attrs, const_let, const_fn)]
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {}
+
+const fn foo() -> NonZero<u32> {
+    let mut x = unsafe { NonZero(1) };
+    x.0 = 0;
+    //~^ ERROR mutation of layout constrained field is unsafe
+    x
+}
+
+const fn bar() -> NonZero<u32> {
+    let mut x = unsafe { NonZero(1) };
+    unsafe { x.0 = 0 }; // this is UB
+    x
+}
diff --git a/src/test/ui/unsafe/ranged_ints4_const.stderr b/src/test/ui/unsafe/ranged_ints4_const.stderr
new file mode 100644
index 0000000..fe83b15
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints4_const.stderr
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints4_const.rs:10:5
+   |
+LL |     x.0 = 0;
+   |     ^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/ranged_ints_const.rs b/src/test/ui/unsafe/ranged_ints_const.rs
new file mode 100644
index 0000000..8477772
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints_const.rs
@@ -0,0 +1,11 @@
+#![feature(rustc_attrs)]
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {}
+
+const fn foo() -> NonZero<u32> { NonZero(0) }
+//~^ ERROR initializing type with `rustc_layout_scalar_valid_range` attr is unsafe
+
+const fn bar() -> NonZero<u32> { unsafe { NonZero(0) } }
diff --git a/src/test/ui/unsafe/ranged_ints_const.stderr b/src/test/ui/unsafe/ranged_ints_const.stderr
new file mode 100644
index 0000000..584ad40
--- /dev/null
+++ b/src/test/ui/unsafe/ranged_ints_const.stderr
@@ -0,0 +1,11 @@
+error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints_const.rs:8:34
+   |
+LL | const fn foo() -> NonZero<u32> { NonZero(0) }
+   |                                  ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr
+   |
+   = note: initializing a layout restricted type's field with a value outside the valid range is undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs
index afdf59d..7c6fb8c 100644
--- a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs
+++ b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.rs
@@ -16,7 +16,7 @@
 }
 
 impl<'a, T> Trait<'a, T> for usize {
-    type Out = &'a fn(T);
+    type Out = &'a fn(T); //~ ERROR `T` may not live long enough
 }
 
 struct Foo<'a,T> {
@@ -26,7 +26,7 @@
 trait Baz<T> { }
 
 impl<'a, T> Trait<'a, T> for u32 {
-    type Out = &'a Baz<T>;
+    type Out = &'a Baz<T>; //~ ERROR `T` may not live long enough
 }
 
 fn main() { }
diff --git a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
index 26a2138..0454215 100644
--- a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
+++ b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
@@ -3,13 +3,13 @@
    |
 LL | impl<'a, T> Trait<'a, T> for usize {
    |          - help: consider adding an explicit lifetime bound `T: 'a`...
-LL |     type Out = &'a fn(T);
+LL |     type Out = &'a fn(T); //~ ERROR `T` may not live long enough
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
 note: ...so that the reference type `&'a fn(T)` does not outlive the data it points at
   --> $DIR/wf-outlives-ty-in-fn-or-trait.rs:19:5
    |
-LL |     type Out = &'a fn(T);
+LL |     type Out = &'a fn(T); //~ ERROR `T` may not live long enough
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0309]: the parameter type `T` may not live long enough
@@ -17,13 +17,13 @@
    |
 LL | impl<'a, T> Trait<'a, T> for u32 {
    |          - help: consider adding an explicit lifetime bound `T: 'a`...
-LL |     type Out = &'a Baz<T>;
+LL |     type Out = &'a Baz<T>; //~ ERROR `T` may not live long enough
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: ...so that the reference type `&'a (dyn Baz<T> + 'a)` does not outlive the data it points at
   --> $DIR/wf-outlives-ty-in-fn-or-trait.rs:29:5
    |
-LL |     type Out = &'a Baz<T>;
+LL |     type Out = &'a Baz<T>; //~ ERROR `T` may not live long enough
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
diff --git a/src/tools/cargo b/src/tools/cargo
index b3d0b2e..5e85ba1 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit b3d0b2e545b61d4cd08096911724b7d49d213f73
+Subproject commit 5e85ba14aaa20f8133863373404cb0af69eeef2c
diff --git a/src/tools/clang b/src/tools/clang
index d0fc178..032312d 160000
--- a/src/tools/clang
+++ b/src/tools/clang
@@ -1 +1 @@
-Subproject commit d0fc1788123de9844c8088b977cd142021cea1f2
+Subproject commit 032312dd0140a7074c9b89d305fe44eb0e44e407
diff --git a/src/tools/clippy b/src/tools/clippy
index b2601be..1df5766 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit b2601beb35b56fd33bd387a1faeccd3ae02352ed
+Subproject commit 1df5766cbb559aab0ad5c2296d8b768182b5186c
diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs
index dd2e555..8d20a9e 100644
--- a/src/tools/compiletest/src/errors.rs
+++ b/src/tools/compiletest/src/errors.rs
@@ -119,10 +119,7 @@
     line: &str,
     tag: &str,
 ) -> Option<(WhichLine, Error)> {
-    let start = match line.find(tag) {
-        Some(i) => i,
-        None => return None,
-    };
+    let start = line.find(tag)?;
     let (follow, adjusts) = if line[start + tag.len()..].chars().next().unwrap() == '|' {
         (true, 0)
     } else {
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index ed2114b..f4a82ae 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -707,14 +707,8 @@
 
     fn parse_custom_normalization(&self, mut line: &str, prefix: &str) -> Option<(String, String)> {
         if self.parse_cfg_name_directive(line, prefix) == ParsedNameDirective::Match {
-            let from = match parse_normalization_string(&mut line) {
-                Some(s) => s,
-                None => return None,
-            };
-            let to = match parse_normalization_string(&mut line) {
-                Some(s) => s,
-                None => return None,
-            };
+            let from = parse_normalization_string(&mut line)?;
+            let to = parse_normalization_string(&mut line)?;
             Some((from, to))
         } else {
             None
@@ -873,14 +867,8 @@
 /// ```
 fn parse_normalization_string(line: &mut &str) -> Option<String> {
     // FIXME support escapes in strings.
-    let begin = match line.find('"') {
-        Some(i) => i + 1,
-        None => return None,
-    };
-    let end = match line[begin..].find('"') {
-        Some(i) => i + begin,
-        None => return None,
-    };
+    let begin = line.find('"')? + 1;
+    let end = line[begin..].find('"')? + begin;
     let result = line[begin..end].to_owned();
     *line = &line[end + 1..];
     Some(result)
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 399f9f5..c654230 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1829,10 +1829,10 @@
             rustc.args(self.split_maybe_args(&self.config.host_rustcflags));
         } else {
             rustc.args(self.split_maybe_args(&self.config.target_rustcflags));
-        }
-        if !is_rustdoc {
-            if let Some(ref linker) = self.config.linker {
-                rustc.arg(format!("-Clinker={}", linker));
+            if !is_rustdoc {
+                if let Some(ref linker) = self.config.linker {
+                    rustc.arg(format!("-Clinker={}", linker));
+                }
             }
         }
 
@@ -2781,12 +2781,14 @@
                explicit, self.config.compare_mode, expected_errors, proc_res.status,
                self.props.error_patterns);
         if !explicit && self.config.compare_mode.is_none() {
-            if !expected_errors.is_empty() && !proc_res.status.success() {
-                // "//~ERROR comments"
-                self.check_expected_errors(expected_errors, &proc_res);
-            } else if !self.props.error_patterns.is_empty() && !proc_res.status.success() {
-                // "// error-pattern" comments
-                self.check_error_patterns(&proc_res.stderr, &proc_res);
+            if !proc_res.status.success() {
+                if !self.props.error_patterns.is_empty() {
+                    // "// error-pattern" comments
+                    self.check_error_patterns(&proc_res.stderr, &proc_res);
+                } else {
+                    // "//~ERROR comments"
+                    self.check_expected_errors(expected_errors, &proc_res);
+                }
             }
         }
 
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index ca7e022..e6bf9a2 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -24,12 +24,12 @@
 //! A few whitelisted exceptions are allowed as there's known bugs in rustdoc,
 //! but this should catch the majority of "broken link" cases.
 
-use std::env;
-use std::fs::File;
-use std::io::prelude::*;
-use std::path::{Path, PathBuf, Component};
-use std::collections::{HashMap, HashSet};
 use std::collections::hash_map::Entry;
+use std::collections::{HashMap, HashSet};
+use std::env;
+use std::fs;
+use std::path::{Path, PathBuf, Component};
+use std::rc::Rc;
 
 use Redirect::*;
 
@@ -63,7 +63,7 @@
 }
 
 struct FileEntry {
-    source: String,
+    source: Rc<String>,
     ids: HashSet<String>,
 }
 
@@ -113,7 +113,7 @@
                 let entry = cache.get_mut(&pretty_path).unwrap();
                 // we don't need the source anymore,
                 // so drop to reduce memory-usage
-                entry.source = String::new();
+                entry.source = Rc::new(String::new());
             }
         }
     }
@@ -287,24 +287,24 @@
              root: &Path,
              file: &Path,
              redirect: Redirect)
-             -> Result<(PathBuf, String), LoadError> {
-    let mut contents = String::new();
+             -> Result<(PathBuf, Rc<String>), LoadError> {
     let pretty_file = PathBuf::from(file.strip_prefix(root).unwrap_or(&file));
 
-    let maybe_redirect = match cache.entry(pretty_file.clone()) {
+    let (maybe_redirect, contents) = match cache.entry(pretty_file.clone()) {
         Entry::Occupied(entry) => {
-            contents = entry.get().source.clone();
-            None
+            (None, entry.get().source.clone())
         }
         Entry::Vacant(entry) => {
-            let mut fp = File::open(file).map_err(|err| {
-                if let FromRedirect(true) = redirect {
-                    LoadError::BrokenRedirect(file.to_path_buf(), err)
-                } else {
-                    LoadError::IOError(err)
+            let contents = match fs::read_to_string(file) {
+                Ok(s) => Rc::new(s),
+                Err(err) => {
+                    return Err(if let FromRedirect(true) = redirect {
+                        LoadError::BrokenRedirect(file.to_path_buf(), err)
+                    } else {
+                        LoadError::IOError(err)
+                    })
                 }
-            })?;
-            fp.read_to_string(&mut contents).map_err(|err| LoadError::IOError(err))?;
+            };
 
             let maybe = maybe_redirect(&contents);
             if maybe.is_some() {
@@ -317,7 +317,7 @@
                     ids: HashSet::new(),
                 });
             }
-            maybe
+            (maybe, contents)
         }
     };
     match maybe_redirect.map(|url| file.parent().unwrap().join(url)) {
@@ -332,10 +332,7 @@
     const REDIRECT: &'static str = "<p>Redirecting to <a href=";
 
     let mut lines = source.lines();
-    let redirect_line = match lines.nth(6) {
-        Some(l) => l,
-        None => return None,
-    };
+    let redirect_line = lines.nth(6)?;
 
     redirect_line.find(REDIRECT).map(|i| {
         let rest = &redirect_line[(i + REDIRECT.len() + 1)..];
diff --git a/src/tools/lldb b/src/tools/lldb
index fdea743..8ad0817 160000
--- a/src/tools/lldb
+++ b/src/tools/lldb
@@ -1 +1 @@
-Subproject commit fdea743be550ed8d7b61b2c908944cdd1290a6ad
+Subproject commit 8ad0817ce45b0eef9d374691b23f2bd69c164254
diff --git a/src/tools/miri b/src/tools/miri
index 32e93ed..61f2076 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 32e93ed7762e5aa1a721636096848fc3c7bc7218
+Subproject commit 61f20761d3124f5a1b1caee8aa15637cc7f92d8e
diff --git a/src/tools/rls b/src/tools/rls
index daa138c..cfd8449 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit daa138ce7f222559e9a339600b44a715101a3f4d
+Subproject commit cfd8449bd6fcfc6a0b53889c616faa4de4513636
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index c8ce4cf..f7c30df 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -259,6 +259,7 @@
                                'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
         const expected = loadedFile.EXPECTED;
         const query = loadedFile.QUERY;
+        const filter_crate = loadedFile.FILTER_CRATE;
         const ignore_order = loadedFile.ignore_order;
         const exact_check = loadedFile.exact_check;
         const should_fail = loadedFile.should_fail;
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
index 1cc61cf..43206f4 160000
--- a/src/tools/rustfmt
+++ b/src/tools/rustfmt
@@ -1 +1 @@
-Subproject commit 1cc61cfc2b29ae3f29a924b4c8feb1bcb09aa5fc
+Subproject commit 43206f41625b8ad670d65bcad37686b40a1c7c48
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index a40ae88..3e27c3d 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -52,6 +52,7 @@
     "cloudabi",           // BSD-2-Clause, (rls -> crossbeam-channel 0.2 -> rand 0.5)
     "ryu",                // Apache-2.0, rls/cargo/... (b/c of serde)
     "bytesize",           // Apache-2.0, cargo
+    "im-rc",              // MPL-2.0+, cargo
 ];
 
 /// Which crates to check against the whitelist?
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 12e9a54..822db25 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -74,6 +74,13 @@
     "src/libcore/tests",
     "src/liballoc/tests/lib.rs",
 
+    // The `VaList` implementation must have platform specific code.
+    // The Windows implementation of a `va_list` is always a character
+    // pointer regardless of the target architecture. As a result,
+    // we must use `#[cfg(windows)]` to conditionally compile the
+    // correct `VaList` structure for windows.
+    "src/libcore/ffi.rs",
+
     // non-std crates
     "src/test",
     "src/tools",