Rollup merge of #56713 - xfix:vec-test-zst-capacity, r=TimNN

Test capacity of ZST vector

Initially, #50233 accidentally changed the capacity of empty ZST. This was pointed out during code review. This commit adds a test to prevent capacity of ZST vectors from accidentally changing to prevent that from happening again.
diff --git a/.gitmodules b/.gitmodules
index 4a136cf..70164d4 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -5,9 +5,6 @@
 [submodule "src/rust-installer"]
 	path = src/tools/rust-installer
 	url = https://github.com/rust-lang/rust-installer.git
-[submodule "src/liblibc"]
-	path = src/liblibc
-	url = https://github.com/rust-lang/libc.git
 [submodule "src/doc/nomicon"]
 	path = src/doc/nomicon
 	url = https://github.com/rust-lang-nursery/nomicon.git
@@ -23,9 +20,6 @@
 [submodule "src/tools/rls"]
 	path = src/tools/rls
 	url = https://github.com/rust-lang-nursery/rls.git
-[submodule "src/libcompiler_builtins"]
-	path = src/libcompiler_builtins
-	url = https://github.com/rust-lang-nursery/compiler-builtins.git
 [submodule "src/tools/clippy"]
 	path = src/tools/clippy
 	url = https://github.com/rust-lang-nursery/rust-clippy.git
@@ -35,9 +29,6 @@
 [submodule "src/tools/miri"]
 	path = src/tools/miri
 	url = https://github.com/solson/miri.git
-[submodule "src/dlmalloc"]
-	path = src/dlmalloc
-	url = https://github.com/alexcrichton/dlmalloc-rs.git
 [submodule "src/doc/rust-by-example"]
 	path = src/doc/rust-by-example
 	url = https://github.com/rust-lang/rust-by-example.git
@@ -61,7 +52,6 @@
 	path = src/tools/clang
 	url = https://github.com/rust-lang-nursery/clang.git
 	branch = rust-release-80-v2
-
 [submodule "src/doc/rustc-guide"]
 	path = src/doc/rustc-guide
 	url = https://github.com/rust-lang/rustc-guide.git
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 137fe61..65cdfe6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -39,7 +39,7 @@
 is a bug or not, feel free to file a bug anyway.
 
 **If you believe reporting your bug publicly represents a security risk to Rust users,
-please follow our [instructions for reporting security vulnerabilities](https://www.rust-lang.org/security.html)**.
+please follow our [instructions for reporting security vulnerabilities](https://www.rust-lang.org/policies/security)**.
 
 If you have the chance, before reporting a bug, please [search existing
 issues](https://github.com/rust-lang/rust/search?q=&type=Issues&utf8=%E2%9C%93),
diff --git a/Cargo.lock b/Cargo.lock
index 69d929e..be4a1c2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,18 +1,23 @@
 [[package]]
+name = "adler32"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "aho-corasick"
-version = "0.6.7"
+version = "0.6.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "alloc"
 version = "0.0.0"
 dependencies = [
- "compiler_builtins 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
- "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -20,12 +25,12 @@
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "html5ever 0.22.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -59,9 +64,9 @@
  "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -69,19 +74,19 @@
 version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "backtrace"
-version = "0.3.9"
+version = "0.3.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -92,7 +97,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -125,35 +130,40 @@
  "build_helper 0.1.0",
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bufstream"
-version = "0.1.3"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "build-manifest"
 version = "0.1.0"
 dependencies = [
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "build_const"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "build_helper"
 version = "0.1.0"
 
@@ -167,7 +177,7 @@
 
 [[package]]
 name = "byteorder"
-version = "1.2.3"
+version = "1.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -177,22 +187,22 @@
 
 [[package]]
 name = "cargo"
-version = "0.33.0"
+version = "0.34.0"
 dependencies = [
  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "core-foundation 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "crates-io 0.21.0",
- "crossbeam-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crates-io 0.22.0",
+ "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -200,35 +210,35 @@
  "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
+ "ignore 0.4.4 (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)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
+ "opener 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pretty_env_logger 0.3.0 (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)",
- "same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -239,9 +249,9 @@
 dependencies = [
  "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -255,7 +265,7 @@
 
 [[package]]
 name = "cfg-if"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -277,11 +287,11 @@
 
 [[package]]
 name = "chrono"
-version = "0.4.4"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -309,14 +319,14 @@
  "clippy_dev 0.0.1",
  "clippy_lints 0.0.212",
  "compiletest_rs 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-workspace-hack 1.0.0",
  "rustc_tools_util 0.1.0",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -329,9 +339,9 @@
 dependencies = [
  "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -341,18 +351,18 @@
  "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -392,15 +402,16 @@
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "compiler_builtins"
-version = "0.0.0"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "core 0.0.0",
+ "rustc-std-workspace-core 1.0.0",
 ]
 
 [[package]]
@@ -408,18 +419,18 @@
 version = "0.0.0"
 dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustfix 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -429,16 +440,16 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -446,39 +457,50 @@
 name = "core"
 version = "0.0.0"
 dependencies = [
- "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "core-foundation"
-version = "0.6.1"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "core-foundation-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "core-foundation-sys"
-version = "0.6.1"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "crates-io"
-version = "0.21.0"
+version = "0.22.0"
 dependencies = [
  "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
-name = "crossbeam"
-version = "0.3.2"
+name = "crc"
+version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
 
 [[package]]
 name = "crossbeam-channel"
@@ -489,7 +511,7 @@
  "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -507,9 +529,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -521,9 +543,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -533,7 +555,7 @@
 version = "0.2.2"
 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)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -543,10 +565,10 @@
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.6.1"
+version = "0.6.2"
 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)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -556,7 +578,7 @@
 dependencies = [
  "commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -567,9 +589,9 @@
 dependencies = [
  "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -581,10 +603,10 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "libnghttp2-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -597,12 +619,12 @@
 
 [[package]]
 name = "derive-new"
-version = "0.5.4"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -611,9 +633,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -631,16 +653,18 @@
 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)",
+ "libc 0.2.45 (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"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "compiler_builtins 0.0.0",
- "core 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-std-workspace-core 1.0.0",
 ]
 
 [[package]]
@@ -650,24 +674,16 @@
 
 [[package]]
 name = "elasticlunr-rs"
-version = "2.3.3"
+version = "2.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
- "strum 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "strum_macros 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "ena"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "strum 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "strum_macros 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -675,19 +691,19 @@
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "env_logger"
-version = "0.5.12"
+version = "0.5.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -696,10 +712,10 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -712,7 +728,7 @@
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -720,7 +736,7 @@
 version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -732,32 +748,32 @@
 
 [[package]]
 name = "failure"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "failure_derive"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "filetime"
-version = "0.2.1"
+version = "0.2.4"
 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)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -767,12 +783,14 @@
 
 [[package]]
 name = "flate2"
-version = "1.0.3"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -798,11 +816,20 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "fortanix-sgx-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-std-workspace-core 1.0.0",
+]
+
+[[package]]
 name = "fs2"
 version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -816,7 +843,7 @@
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -852,8 +879,8 @@
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -867,12 +894,12 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -882,8 +909,8 @@
 dependencies = [
  "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -893,14 +920,14 @@
 
 [[package]]
 name = "globset"
-version = "0.4.1"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -912,14 +939,22 @@
 version = "0.32.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "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)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "heck"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -938,20 +973,20 @@
 
 [[package]]
 name = "html5ever"
-version = "0.22.3"
+version = "0.22.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "humantime"
-version = "1.1.1"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -974,19 +1009,19 @@
 
 [[package]]
 name = "ignore"
-version = "0.4.3"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "globset 0.4.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)",
- "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -994,7 +1029,7 @@
 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)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1004,11 +1039,11 @@
 dependencies = [
  "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1038,17 +1073,17 @@
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "jobserver"
-version = "0.1.11"
+version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1063,9 +1098,9 @@
 dependencies = [
  "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1083,12 +1118,12 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1099,29 +1134,21 @@
 
 [[package]]
 name = "lazy_static"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "lazycell"
 version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
-name = "libc"
-version = "0.0.0"
-dependencies = [
- "compiler_builtins 0.0.0",
- "core 0.0.0",
-]
+name = "lazycell"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libc"
-version = "0.2.43"
+version = "0.2.45"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc-std-workspace-core 1.0.0",
+]
 
 [[package]]
 name = "libgit2-sys"
@@ -1130,19 +1157,20 @@
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libnghttp2-sys"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1151,20 +1179,20 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libz-sys"
-version = "1.0.24"
+version = "1.0.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1187,15 +1215,15 @@
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.5"
+version = "0.4.6"
 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)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1203,7 +1231,7 @@
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1212,8 +1240,8 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1239,9 +1267,9 @@
 dependencies = [
  "phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1258,34 +1286,36 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "elasticlunr-rs 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "elasticlunr-rs 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.8 (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)",
- "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "memchr"
-version = "2.0.2"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1293,7 +1323,7 @@
 version = "0.6.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)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1312,11 +1342,30 @@
 
 [[package]]
 name = "miniz-sys"
-version = "0.1.10"
+version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "miniz_oxide"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "miniz_oxide_c_api"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1332,14 +1381,14 @@
 name = "miri"
 version = "0.1.0"
 dependencies = [
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
+ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1357,13 +1406,13 @@
 
 [[package]]
 name = "num-derive"
-version = "0.2.2"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1371,12 +1420,12 @@
 version = "0.1.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.2.5"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1384,7 +1433,7 @@
 version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1394,25 +1443,25 @@
 
 [[package]]
 name = "opener"
-version = "0.3.0"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "openssl"
-version = "0.10.13"
+version = "0.10.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1422,7 +1471,7 @@
 
 [[package]]
 name = "openssl-src"
-version = "111.0.1+1.1.1"
+version = "111.1.0+1.1.1a"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1430,12 +1479,12 @@
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.38"
+version = "0.9.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-src 111.0.1+1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-src 111.1.0+1.1.1a (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1463,16 +1512,16 @@
 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)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "panic_abort"
 version = "0.0.0"
 dependencies = [
- "compiler_builtins 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
- "libc 0.0.0",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1480,9 +1529,9 @@
 version = "0.0.0"
 dependencies = [
  "alloc 0.0.0",
- "compiler_builtins 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
- "libc 0.0.0",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "unwind 0.0.0",
 ]
 
@@ -1497,23 +1546,12 @@
 
 [[package]]
 name = "parking_lot_core"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "parking_lot_core"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1529,7 +1567,7 @@
 
 [[package]]
 name = "pest_derive"
-version = "1.0.7"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1591,7 +1629,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1611,13 +1649,12 @@
 
 [[package]]
 name = "pretty_env_logger"
-version = "0.2.5"
+version = "0.3.0"
 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)",
+ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1645,7 +1682,7 @@
 version = "0.0.0"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -1656,14 +1693,14 @@
 dependencies = [
  "bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1709,7 +1746,7 @@
 
 [[package]]
 name = "quote"
-version = "0.6.8"
+version = "0.6.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1717,18 +1754,18 @@
 
 [[package]]
 name = "racer"
-version = "2.1.13"
+version = "2.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "humantime 1.1.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)",
+ "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1737,7 +1774,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1748,15 +1785,83 @@
 dependencies = [
  "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
-name = "rand_core"
-version = "0.2.1"
+name = "rand"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rand_hc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_isaac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_xorshift"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
 
 [[package]]
 name = "rayon"
@@ -1773,15 +1878,15 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "redox_syscall"
-version = "0.1.40"
+version = "0.1.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1789,7 +1894,7 @@
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1797,23 +1902,23 @@
 version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex"
-version = "1.0.4"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1821,15 +1926,15 @@
 version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.2"
+version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1852,23 +1957,23 @@
 name = "rls"
 version = "1.31.6"
 dependencies = [
- "cargo 0.33.0",
+ "cargo 0.34.0",
  "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "clippy_lints 0.0.212",
  "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.3 (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.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)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "racer 2.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "racer 2.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
+ "regex 1.1.0 (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)",
@@ -1878,13 +1983,13 @@
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-workspace-hack 1.0.0",
  "rustc_tools_util 0.1.0",
- "rustfmt-nightly 1.0.0",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustfmt-nightly 1.0.1",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1892,11 +1997,11 @@
 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)",
+ "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "fst 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-data 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1914,8 +2019,8 @@
 dependencies = [
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1929,8 +2034,8 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1938,7 +2043,7 @@
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1955,16 +2060,16 @@
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "fmt_macros 0.0.0",
  "graphviz 0.0.0",
- "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)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (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)",
  "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1976,115 +2081,114 @@
  "rustc_target 0.0.0",
  "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
- "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-arena"
-version = "297.0.0"
+version = "306.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-graphviz"
-version = "297.0.0"
+version = "306.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc-ap-rustc_cratesio_shim"
-version = "297.0.0"
+version = "306.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "297.0.0"
+version = "306.0.0"
 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)",
- "ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-graphviz 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-graphviz 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "297.0.0"
+version = "306.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_target"
-version = "297.0.0"
+version = "306.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "297.0.0"
+version = "306.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-syntax"
-version = "297.0.0"
+version = "306.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_target 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-syntax_pos"
-version = "297.0.0"
+version = "306.0.0"
 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)",
- "rustc-ap-arena 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-arena 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2099,7 +2203,7 @@
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2126,8 +2230,8 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2138,12 +2242,21 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "rustc-std-workspace-core"
+version = "1.0.0"
+dependencies = [
+ "core 0.0.0",
+]
+
+[[package]]
 name = "rustc-workspace-hack"
 version = "1.0.0"
 dependencies = [
+ "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2151,12 +2264,12 @@
 name = "rustc_allocator"
 version = "0.0.0"
 dependencies = [
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
 ]
@@ -2167,7 +2280,7 @@
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2177,7 +2290,7 @@
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -2186,7 +2299,7 @@
 version = "0.0.0"
 dependencies = [
  "graphviz 0.0.0",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -2212,9 +2325,9 @@
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -2237,8 +2350,8 @@
 name = "rustc_codegen_utils"
 version = "0.0.0"
 dependencies = [
- "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)",
+ "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_incremental 0.0.0",
@@ -2254,7 +2367,7 @@
 version = "0.0.0"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2262,17 +2375,17 @@
 name = "rustc_data_structures"
 version = "0.0.0"
 dependencies = [
- "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "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_cratesio_shim 0.0.0",
  "serialize 0.0.0",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2281,10 +2394,10 @@
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
  "jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_allocator 0.0.0",
@@ -2306,7 +2419,7 @@
  "rustc_typeck 0.0.0",
  "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax 0.0.0",
  "syntax_ext 0.0.0",
  "syntax_pos 0.0.0",
@@ -2317,12 +2430,12 @@
 version = "0.0.0"
 dependencies = [
  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
  "rustc_data_structures 0.0.0",
  "serialize 0.0.0",
  "syntax_pos 0.0.0",
- "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2335,7 +2448,7 @@
 version = "0.0.0"
 dependencies = [
  "graphviz 0.0.0",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -2349,10 +2462,9 @@
 name = "rustc_lint"
 version = "0.0.0"
 dependencies = [
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (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",
@@ -2373,7 +2485,7 @@
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -2381,8 +2493,8 @@
 name = "rustc_metadata"
 version = "0.0.0"
 dependencies = [
- "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)",
+ "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -2401,10 +2513,10 @@
 dependencies = [
  "arena 0.0.0",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -2413,7 +2525,7 @@
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
  "serialize 0.0.0",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
 ]
@@ -2425,7 +2537,7 @@
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -2433,7 +2545,7 @@
 name = "rustc_passes"
 version = "0.0.0"
 dependencies = [
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -2474,7 +2586,7 @@
 dependencies = [
  "arena 0.0.0",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -2487,7 +2599,7 @@
 name = "rustc_save_analysis"
 version = "0.0.0"
 dependencies = [
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-data 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -2505,7 +2617,7 @@
 version = "0.0.0"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
  "rustc_data_structures 0.0.0",
  "serialize 0.0.0",
@@ -2522,11 +2634,11 @@
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_target 0.0.0",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
 ]
@@ -2538,7 +2650,7 @@
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -2547,20 +2659,20 @@
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_platform_intrinsics 0.0.0",
  "rustc_target 0.0.0",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
 ]
 
 [[package]]
 name = "rustc_version"
-version = "0.2.2"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2573,7 +2685,7 @@
  "minifier 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2592,39 +2704,39 @@
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.0.0"
+version = "1.0.1"
 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.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)",
+ "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.8 (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)",
- "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_target 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-workspace-hack 1.0.0",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2635,18 +2747,18 @@
 dependencies = [
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "ryu"
-version = "0.2.6"
+version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "same-file"
-version = "1.0.3"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2657,7 +2769,7 @@
 version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2677,7 +2789,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2687,17 +2799,17 @@
 
 [[package]]
 name = "serde"
-version = "1.0.75"
+version = "1.0.81"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde_derive"
-version = "1.0.75"
+version = "1.0.81"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2705,24 +2817,24 @@
 version = "0.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.31"
+version = "1.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serialize"
 version = "0.0.0"
 dependencies = [
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2742,7 +2854,7 @@
 
 [[package]]
 name = "smallvec"
-version = "0.6.5"
+version = "0.6.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2753,9 +2865,9 @@
 version = "0.3.8"
 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)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2771,14 +2883,15 @@
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
- "dlmalloc 0.0.0",
- "libc 0.0.0",
+ "dlmalloc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fortanix-sgx-abi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "panic_abort 0.0.0",
  "panic_unwind 0.0.0",
  "profiler_builtins 0.0.0",
- "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_asan 0.0.0",
  "rustc_lsan 0.0.0",
  "rustc_msan 0.0.0",
@@ -2791,11 +2904,11 @@
 version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2824,17 +2937,18 @@
 
 [[package]]
 name = "strum"
-version = "0.9.0"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "strum_macros"
-version = "0.9.1"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
+ "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2849,31 +2963,11 @@
 
 [[package]]
 name = "syn"
-version = "0.13.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "syn"
-version = "0.14.9"
+version = "0.15.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "syn"
-version = "0.15.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2887,12 +2981,12 @@
 
 [[package]]
 name = "synstructure"
-version = "0.9.0"
+version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2901,13 +2995,13 @@
 version = "0.0.0"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
  "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax_pos 0.0.0",
 ]
 
@@ -2916,11 +3010,11 @@
 version = "0.0.0"
 dependencies = [
  "fmt_macros 0.0.0",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
- "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
 ]
@@ -2930,7 +3024,7 @@
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
  "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
@@ -2939,23 +3033,24 @@
 
 [[package]]
 name = "tar"
-version = "0.4.19"
+version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "tempfile"
-version = "3.0.3"
+version = "3.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2979,13 +3074,13 @@
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "termcolor"
-version = "1.0.2"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2996,8 +3091,8 @@
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -3023,16 +3118,16 @@
 version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "tidy"
 version = "0.1.0"
 dependencies = [
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3040,17 +3135,17 @@
 version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.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 = "toml"
-version = "0.4.6"
+version = "0.4.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3060,9 +3155,9 @@
 dependencies = [
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3072,7 +3167,7 @@
 
 [[package]]
 name = "ucd-util"
-version = "0.1.1"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -3120,7 +3215,7 @@
 name = "unstable-book-gen"
 version = "0.1.0"
 dependencies = [
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "tidy 0.1.0",
 ]
 
@@ -3128,14 +3223,14 @@
 name = "unwind"
 version = "0.0.0"
 dependencies = [
- "compiler_builtins 0.0.0",
+ "compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
- "libc 0.0.0",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "url"
-version = "1.7.1"
+version = "1.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3148,8 +3243,8 @@
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3159,7 +3254,7 @@
 
 [[package]]
 name = "utf8-ranges"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -3174,12 +3269,12 @@
 
 [[package]]
 name = "vergen"
-version = "3.0.3"
+version = "3.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3197,15 +3292,15 @@
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "walkdir"
-version = "2.2.5"
+version = "2.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -3261,7 +3356,7 @@
 version = "0.2.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)",
+ "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3278,71 +3373,76 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
-"checksum aho-corasick 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee94e9463ccb9d681e7b708082687b2c56d2bd420ca8a3d3157d27d59508ec0"
+"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
+"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
 "checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477"
 "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
 "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
 "checksum assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98589b0e465a6c510d95fceebd365bb79bedece7f6e18a480897f2015f85ec51"
 "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
-"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
+"checksum backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "18b65ea1161bfb2dd6da6fade5edd4dbd08fba85012123dd333d2fd1b90b2782"
 "checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
 "checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a"
 "checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf"
 "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 bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8"
+"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
 "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 byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
 "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"
 "checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
-"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
+"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
 "checksum chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6749eb72e7d4355d944a99f15fbaea701b978c18c5e184a025fcde942b0c9779"
 "checksum chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "295635afd6853aa9f20baeb7f0204862440c0fe994c5a253d5f479dac41d047e"
-"checksum chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37"
+"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
 "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
 "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
 "checksum cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "704fbf3bb5149daab0afb255dbea24a1f08d2f4099cedb9baab6d470d4c5eefb"
 "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
 "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007"
 "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2"
+"checksum compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8ad611263b9f31bdb66e66227d3b781600fd1e68d5deee29b23f5e2ac9cb4892"
 "checksum compiletest_rs 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "89747fe073b7838343bd2c2445e7a7c2e0d415598f8925f0fa9205b9cdfc48cb"
-"checksum core-foundation 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cc3532ec724375c7cb7ff0a097b714fde180bb1f6ed2ab27cfcd99ffca873cd2"
-"checksum core-foundation-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a3fb15cdbdd9cf8b82d97d0296bb5cd3631bba58d6e31650a002a8e7fb5721f9"
-"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
+"checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"
+"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
+"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
+"checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192"
 "checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827"
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
 "checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
-"checksum crossbeam-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c55913cc2799171a550e307918c0a360e8c16004820291bf3b638969b4a01816"
+"checksum crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e07fc155212827475223f0bcfae57e945e694fc90950ddf3f6695bbfd5555c72"
 "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4"
 "checksum curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c7c9d851c825e0c033979d4516c9173bc19a78a96eb4d6ae51d4045440eafa16"
 "checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870"
 "checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142"
-"checksum derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ceed73957c449214f8440eec8ad7fa282b67dc9eacbb24a3085b15d60397a17a"
+"checksum derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c"
 "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 dlmalloc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c46c65de42b063004b31c67a98abe071089b289ff0919c660ed7ff4f59317f8"
 "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 elasticlunr-rs 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a99a310cd1f9770e7bf8e48810c7bcbb0e078c8fb23a8c7bcf0da4c2bf61a455"
 "checksum ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f56c93cc076508c549d9bb747f79aa9b4eb098be7b8cad8830c3137ef52d1e00"
-"checksum ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc8393b3c7352f94092497f6b52019643e493b6b890eb417cdb7c46117e621"
-"checksum env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "f4d7e69c283751083d53d01eac767407343b8b69c4bd70058e08adc2637cb257"
+"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
 "checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e"
 "checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee"
 "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
 "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
-"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9"
-"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426"
-"checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f"
+"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
+"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
+"checksum filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a2df5c1a8c4be27e7707789dc42ae65976e60b394afd293d1419ab915833e646"
 "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
-"checksum flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4af030962d89d62aa52cd9492083b1cd9b2d1a77764878102a6c0f86b4d5444d"
+"checksum flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2291c165c8e703ee54ef3055ad6188e3d51108e2ded18e9f2476e774fc5ad3d4"
 "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
 "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
 "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+"checksum fortanix-sgx-abi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "26105e20b4c3f7a319db1376b54ac9a46e5761e949405553375095d05a0cee4d"
 "checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
 "checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
 "checksum fst 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d94485a00b1827b861dd9d1a2cc9764f9044d4c535514c0760a5a2012ef3399f"
@@ -3355,36 +3455,37 @@
 "checksum git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "591f8be1674b421644b6c030969520bc3fa12114d2eb467471982ed3e9584e71"
 "checksum git2-curl 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0173e317f8ba21f3fff0f71549fead5e42e67961dbd402bf69f42775f3cc78b4"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
-"checksum globset 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8e49edbcc9c7fc5beb8c0a54e7319ff8bed353a2b55e85811c6281188c2a6c84"
+"checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865"
 "checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd"
+"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
 "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
 "checksum home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "80dff82fb58cfbbc617fb9a9184b010be0529201553cda50ad04372bc2333aff"
-"checksum html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b04478cf718862650a0bf66acaf8f2f8c906fbc703f35c916c1f4211b069a364"
-"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
+"checksum html5ever 0.22.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c213fa6a618dc1da552f54f85cba74b05d8e883c92ec4e89067736938084c26e"
+"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
 "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 ignore 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36ecfc5ad80f0b1226df948c562e2cddd446096be3f644c95106400eae8a5e01"
 "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"
 "checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae"
-"checksum jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "60af5f849e1981434e4a31d3d782c4774ae9b434ce55b101a96ecfd09147e8be"
+"checksum jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "dd80e58f77e0cdea53ba96acc5e04479e5ffc5d869626a6beafe50fed867eace"
 "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.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"
-"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
+"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
+"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
+"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74"
 "checksum libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4916b5addc78ec36cc309acfcdf0b9f9d97ab7b84083118b248709c5b7029356"
-"checksum libnghttp2-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ffbfb81475cc9f625e44f3a8f8b9cf7173815ae1c7cc2fa91853ec009e38198"
+"checksum libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d75d7966bda4730b722d1eab8e668df445368a24394bae9fc1e8dc0ab3dbe4f4"
 "checksum libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d"
-"checksum libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "4401fe74560a0d46fce3464625ac8aa7a79d291dd28cee021d18852d5191c280"
+"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
 "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
-"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
+"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
 "checksum log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd"
 "checksum lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d1eaa027402541975218bb0eec67d6b0412f6233af96e0d096d31dbdfd22e614"
 "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
@@ -3393,34 +3494,35 @@
 "checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475"
 "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
 "checksum mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "90b5a8d7e341ceee5db3882a06078d42661ddcfa2b3687319cc5da76ec4e782f"
-"checksum memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a3b4142ab8738a78c51896f704f83c11df047ff1bda9a92a661aa6361552d93d"
+"checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16"
 "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
 "checksum minifier 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "96c269bb45c39b333392b2b18ad71760b34ac65666591386b0e959ed58b3f474"
-"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
+"checksum miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0300eafb20369952951699b68243ab4334f4b10a88f411c221d444b36c40e649"
+"checksum miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c"
+"checksum miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e"
 "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226"
 "checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
 "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
-"checksum num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2c31b75c36a993d30c7a13d70513cb93f02acafdd5b7ba250f9b0e18615de7"
+"checksum num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d"
 "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
-"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
+"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
 "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
 "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113"
-"checksum opener 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "176cd8eadff5ef9fa5c6d19452535662c02c6bf29b3d594a3fc01f749bb24c94"
-"checksum openssl 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5af9e83eb3c51ee806387d26a43056f3246d865844caa6dd704d2ba7e831c264"
+"checksum opener 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "04b1d6b086d9b3009550f9b6f81b10ad9428cf14f404b8e1a3a06f6f012c8ec9"
+"checksum openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "5e1309181cdcbdb51bc3b6bedb33dfac2a83b3d585033d3f6d9e22e8c1928613"
 "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
-"checksum openssl-src 111.0.1+1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d1edaed888fd85a54a2646bf02992931ddefdda3b1a748fc79f088a8db27fcbe"
-"checksum openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)" = "ff3d1b390ab1b9700f682ad95a30dc9c0f40dd212ca57266012cfc678b0e365a"
+"checksum openssl-src 111.1.0+1.1.1a (registry+https://github.com/rust-lang/crates.io-index)" = "26bb632127731bf4ac49bf86a5dde12d2ca0918c2234fc39d79d4da2ccbc6da7"
+"checksum openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)" = "278c1ad40a89aa1e741a1eed089a2f60b18fab8089c3139b542140fc7d674106"
 "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"
 "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 "checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc"
-"checksum pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ab94faafeb93f4c5e3ce81ca0e5a779529a602ad5d09ae6d21996bfb8b6a52bf"
+"checksum pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3294f437119209b084c797604295f40227cffa35c57220b1e99a6ff3bf8ee4"
 "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
 "checksum phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "7d37a244c75a9748e049225155f56dbcb98fe71b192fd25fd23cb914b5ad62f2"
 "checksum phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4048fe7dd7a06b8127ecd6d3803149126e9b33c7558879846da3a63f734f2b"
@@ -3430,7 +3532,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 pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
 "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"
@@ -3440,19 +3542,26 @@
 "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
-"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
-"checksum racer 2.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "344a53b68d889ab5f44d0617f2bbe1f696abe6a730bd41fa619cfc6fa83a6078"
+"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
+"checksum racer 2.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fbfcf2686b50f75a279cb42d9c6d253a1e68a475b415ea4baf7fb177ce94839a"
 "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
 "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
-"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
+"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a"
+"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a"
+"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
+"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
+"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
+"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
+"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05"
+"checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3"
 "checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1"
 "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
-"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
+"checksum redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "679da7508e9a6390aeaf7fbd02a800fdc64b73fe2204dd2c8ae66d22d9d5ad5d"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
 "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
-"checksum regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "67d0301b0c6804eca7e3c275119d0b01ff3b7ab9258a65709e608a66312a1025"
+"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
 "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 regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
 "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
 "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"
@@ -3460,65 +3569,63 @@
 "checksum rls-rustc 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9dba7390427aefa953608429701e3665192ca810ba8ae09301e001b7c7bed0"
 "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a"
 "checksum rls-vfs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "72d56425bd5aa86d9d4372b76f0381d3b4bda9c0220e71956c9fcc929f45c1f1"
-"checksum rustc-ap-arena 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b69fd4a0e8a3ecd99b497965d05f6f04dd2e4601a6146a841dbe4c8e77c2b30c"
-"checksum rustc-ap-graphviz 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8136418dbc491bab74aa0565eaa2086754a7a81a5e74a1d84d6168d18e889e7"
-"checksum rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a972feda82332d1d05b1ba5a097e915cd9c9c8f1af2bd7b08af09fb88c753d5f"
-"checksum rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "582584c6c48b0ece4b8aef3f9bb59d94d17c5665612bc87a71f509e45a3113b5"
-"checksum rustc-ap-rustc_errors 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd852096944d0ac6af1aefa9639a2ae6dede217606ce97f88ff0dcc8c86d6ff6"
-"checksum rustc-ap-rustc_target 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98301a272ecfeec29d2d4e97b07238707c2b89d86fc3a4a5f31a00728f14e288"
-"checksum rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f13510e617e2e322e3297038fd6a7346f2297124af9e10e33a627c5d544e9d"
-"checksum rustc-ap-syntax 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0792f5a9ccfc5ec13bb5b0472fa49e145481029c39f6bf5b1a36decc99c3328f"
-"checksum rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0df9f97f41650d23b14f92f7267f8c61089655efb4533d82bf8991f99245198d"
+"checksum rustc-ap-arena 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbfb540c1347a3993060896b18e0d64084203fa37aaffdc5e5c31264f275d476"
+"checksum rustc-ap-graphviz 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "790ac657d5bf69be9ef56f6810e8a0238b07e8460a88526e11d41f8214eb6c4e"
+"checksum rustc-ap-rustc_cratesio_shim 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b721cf32b543f3ee90240d7b757ca4a45930fe9981458a50678b4ccd75c472e2"
+"checksum rustc-ap-rustc_data_structures 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4fa11df199d45ce948b07792ca593f59c1d19d2cb05d35c6b0a02271e772a416"
+"checksum rustc-ap-rustc_errors 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b7ead3163ef995bbba520b88739e1d60f9ccf74fdacdda985067644c8134e827"
+"checksum rustc-ap-rustc_target 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "688fef9cc27837755019b72b4f13e7a3d3e5012473475f377b75dbb1f07beb5f"
+"checksum rustc-ap-serialize 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b2c0e8161e956647592a737074736e6ce05ea36b70c770ea8cca3eb9cb33737"
+"checksum rustc-ap-syntax 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1adc189e5e4500a4167b9afa04e67067f40d0039e0e05870c977bebb561f065a"
+"checksum rustc-ap-syntax_pos 306.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4d42c430dbb0be4377bfe6aa5099074c63ac8796b24098562c2e2154aecc5652"
 "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
 "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
 "checksum rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6d5a683c6ba4ed37959097e88d71c9e8e26659a3cb5be8b389078e7ad45306"
 "checksum rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40f06724db71e18d68b3b946fdf890ca8c921d9edccc1404fdfdb537b0d12649"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
-"checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a"
+"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
 "checksum rustfix 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "756567f00f7d89c9f89a5c401b8b1caaa122e27240b9eaadd0bb52ee0b680b1b"
 "checksum rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9591f190d2852720b679c21f66ad929f9f1d7bb09d1193c26167586029d8489c"
-"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7"
-"checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c"
+"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
+"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
 "checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56"
 "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)" = "22d340507cea0b7e6632900a176101fea959c7065d93ba555072da90aaaafc87"
-"checksum serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)" = "234fc8b737737b148ccd625175fc6390f5e4dacfdaa543cb93a3430d984a9119"
+"checksum serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)" = "c91eb5b0190ae87b4e2e39cbba6e3bed3ac6186935fe265f0426156c4c49961b"
+"checksum serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)" = "477b13b646f5b5b56fc95bedfc3b550d12141ce84f466f6c44b9a17589923885"
 "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142"
-"checksum serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "bb47a3d5c84320222f66d7db21157c4a7407755de41798f9b4c1c40593397b1a"
+"checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811"
 "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 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 smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db"
 "checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
 "checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa"
 "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
 "checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191"
 "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
-"checksum strum 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "099e21b5dd6dd07b5adcf8c4b723a7c0b7efd7a9359bf963d58c0caae8532545"
-"checksum strum_macros 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1292d85e688e4696ecb69b2db2648994fb8af266974e89be53cefdf003861a5d"
+"checksum strum 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c3a2071519ab6a48f465808c4c1ffdd00dfc8e93111d02b4fc5abab177676e"
+"checksum strum_macros 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8baacebd7b7c9b864d83a6ba7a246232983e277b86fa5cdec77f565715a4b136"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
-"checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b"
-"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
-"checksum syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)" = "816b7af21405b011a23554ea2dc3f6576dc86ca557047c34098c1d741f10f823"
+"checksum syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)" = "ae8b29eb5210bc5cf63ed6149cbf9adfc82ac0be023d8735c176ee74a2db4da7"
 "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
-"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
-"checksum tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "69e16840a1e0a1f1a880b739ef1cc6a4b85496c99b8aa786ccffce6e0c15624c"
-"checksum tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b103c6d08d323b92ff42c8ce62abcd83ca8efa7fd5bf7927efefec75f58c76"
+"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
+"checksum tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "a303ba60a099fcd2aaa646b14d2724591a96a75283e4b7ed3d1a1658909d9ae2"
+"checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2"
 "checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
 "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
-"checksum termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3390f44f1f706d8870297b6a2c4f92d9ab65a37c265fbbc6ac4ee72bcc2f3698"
+"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
 "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
 "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
 "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 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
 "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 ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
 "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"
 "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
@@ -3526,17 +3633,17 @@
 "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
 "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
-"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
+"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
 "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"
 "checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c"
-"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
+"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
 "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
 "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
-"checksum vergen 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9696d96ec5d68984d060af80d7ba0ed4eb533978a0efb05ed4b8465f20d04f"
+"checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba"
 "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9f3bf741a801531993db6478b95682117471f76916f5e690dd8d45395b09349"
-"checksum walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "af464bc7be7b785c7ac72e266a6b67c4c9070155606f51655a650a6686204e35"
+"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
diff --git a/Cargo.toml b/Cargo.toml
index b763caa..667c557 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -65,6 +65,10 @@
 # here
 rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' }
 
+# See comments in `tools/rustc-std-workspace-core/README.md` for what's going on
+# here
+rustc-std-workspace-core = { path = 'src/tools/rustc-std-workspace-core' }
+
 [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 3744266..dc013a1 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
 
 Read ["Installation"] from [The Book].
 
-["Installation"]: https://doc.rust-lang.org/book/second-edition/ch01-01-installation.html
+["Installation"]: https://doc.rust-lang.org/book/ch01-01-installation.html
 [The Book]: https://doc.rust-lang.org/book/index.html
 
 ## Building from Source
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 98005f9..c1d5686 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -389,7 +389,6 @@
                 test::UiFullDeps,
                 test::RunPassFullDeps,
                 test::RunFailFullDeps,
-                test::CompileFailFullDeps,
                 test::Rustdoc,
                 test::Pretty,
                 test::RunPassPretty,
@@ -417,6 +416,7 @@
                 test::Rustfmt,
                 test::Miri,
                 test::Clippy,
+                test::CompiletestTest,
                 test::RustdocJS,
                 test::RustdocTheme,
                 // Run bootstrap close to the end as it's unlikely to fail
@@ -685,6 +685,11 @@
             .env("RUSTDOC_REAL", self.rustdoc(host))
             .env("RUSTDOC_CRATE_VERSION", self.rust_version())
             .env("RUSTC_BOOTSTRAP", "1");
+
+        // Remove make-related flags that can cause jobserver problems.
+        cmd.env_remove("MAKEFLAGS");
+        cmd.env_remove("MFLAGS");
+
         if let Some(linker) = self.linker(host) {
             cmd.env("RUSTC_TARGET_LINKER", linker);
         }
@@ -793,7 +798,7 @@
         }
 
         // Set a flag for `check` so that certain build scripts can do less work
-        // (e.g. not building/requiring LLVM).
+        // (e.g., not building/requiring LLVM).
         if cmd == "check" {
             cargo.env("RUST_CHECK", "1");
         }
@@ -923,12 +928,12 @@
             cargo.env("RUSTC_FORCE_UNSTABLE", "1");
 
             // Currently the compiler depends on crates from crates.io, and
-            // then other crates can depend on the compiler (e.g. proc-macro
+            // then other crates can depend on the compiler (e.g., proc-macro
             // crates). Let's say, for example that rustc itself depends on the
             // bitflags crate. If an external crate then depends on the
             // bitflags crate as well, we need to make sure they don't
             // conflict, even if they pick the same version of bitflags. We'll
-            // want to make sure that e.g. a plugin and rustc each get their
+            // want to make sure that e.g., a plugin and rustc each get their
             // own copy of bitflags.
 
             // Cargo ensures that this works in general through the -C metadata
diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs
index 88b6925..878b6ed 100644
--- a/src/bootstrap/channel.rs
+++ b/src/bootstrap/channel.rs
@@ -24,7 +24,7 @@
 use config::Config;
 
 // The version number
-pub const CFG_RELEASE_NUM: &str = "1.32.0";
+pub const CFG_RELEASE_NUM: &str = "1.33.0";
 
 pub struct GitInfo {
     inner: Option<Info>,
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index b6bb11d..689d053 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -18,7 +18,7 @@
 
 use std::borrow::Cow;
 use std::env;
-use std::fs::{self, File};
+use std::fs;
 use std::io::BufReader;
 use std::io::prelude::*;
 use std::path::{Path, PathBuf};
@@ -152,11 +152,12 @@
 
     if builder.no_std(target) == Some(true) {
         // for no-std targets we only compile a few no_std crates
-        cargo.arg("--features").arg("c mem")
+        cargo
             .args(&["-p", "alloc"])
-            .args(&["-p", "compiler_builtins"])
             .arg("--manifest-path")
-            .arg(builder.src.join("src/rustc/compiler_builtins_shim/Cargo.toml"));
+            .arg(builder.src.join("src/liballoc/Cargo.toml"))
+            .arg("--features")
+            .arg("compiler-builtins-mem");
     } else {
         let features = builder.std_features();
 
@@ -707,7 +708,7 @@
         }
         let stamp = codegen_backend_stamp(builder, compiler, target, backend);
         let codegen_backend = codegen_backend.to_str().unwrap();
-        t!(t!(File::create(&stamp)).write_all(codegen_backend.as_bytes()));
+        t!(fs::write(&stamp, &codegen_backend));
     }
 }
 
@@ -796,8 +797,7 @@
 
     for backend in builder.config.rust_codegen_backends.iter() {
         let stamp = codegen_backend_stamp(builder, compiler, target, *backend);
-        let mut dylib = String::new();
-        t!(t!(File::open(&stamp)).read_to_string(&mut dylib));
+        let dylib = t!(fs::read_to_string(&stamp));
         let file = Path::new(&dylib);
         let filename = file.file_name().unwrap().to_str().unwrap();
         // change `librustc_codegen_llvm-xxxxxx.so` to `librustc_codegen_llvm-llvm.so`
@@ -1137,10 +1137,7 @@
     // contents (the list of files to copy) is different or if any dep's mtime
     // is newer then we rewrite the stamp file.
     deps.sort();
-    let mut stamp_contents = Vec::new();
-    if let Ok(mut f) = File::open(stamp) {
-        t!(f.read_to_end(&mut stamp_contents));
-    }
+    let stamp_contents = fs::read(stamp);
     let stamp_mtime = mtime(&stamp);
     let mut new_contents = Vec::new();
     let mut max = None;
@@ -1156,7 +1153,10 @@
     }
     let max = max.unwrap();
     let max_path = max_path.unwrap();
-    if stamp_contents == new_contents && max <= stamp_mtime {
+    let contents_equal = stamp_contents
+        .map(|contents| contents == new_contents)
+        .unwrap_or_default();
+    if contents_equal && max <= stamp_mtime {
         builder.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}",
                 stamp, max, stamp_mtime));
         return deps
@@ -1166,7 +1166,7 @@
     } else {
         builder.verbose(&format!("updating {:?} as deps changed", stamp));
     }
-    t!(t!(File::create(stamp)).write_all(&new_contents));
+    t!(fs::write(&stamp, &new_contents));
     deps
 }
 
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 8fc2d57..1dafbe1 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -15,8 +15,7 @@
 
 use std::collections::{HashMap, HashSet};
 use std::env;
-use std::fs::{self, File};
-use std::io::prelude::*;
+use std::fs;
 use std::path::{Path, PathBuf};
 use std::process;
 use std::cmp;
@@ -416,9 +415,7 @@
         config.run_host_only = !(flags.host.is_empty() && !flags.target.is_empty());
 
         let toml = file.map(|file| {
-            let mut f = t!(File::open(&file));
-            let mut contents = String::new();
-            t!(f.read_to_string(&mut contents));
+            let contents = t!(fs::read_to_string(&file));
             match toml::from_str(&contents) {
                 Ok(table) => table,
                 Err(err) => {
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index cd8d564..f03eefb 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -19,8 +19,8 @@
 //! pieces of `rustup.rs`!
 
 use std::env;
-use std::fs::{self, File};
-use std::io::{Read, Write};
+use std::fs;
+use std::io::Write;
 use std::path::{PathBuf, Path};
 use std::process::{Command, Stdio};
 
@@ -353,7 +353,7 @@
     /// Build the `rust-mingw` installer component.
     ///
     /// This contains all the bits and pieces to run the MinGW Windows targets
-    /// without any extra installed software (e.g. we bundle gcc, libraries, etc).
+    /// without any extra installed software (e.g., we bundle gcc, libraries, etc).
     fn run(self, builder: &Builder) -> Option<PathBuf> {
         let host = self.host;
 
@@ -857,12 +857,9 @@
         // (essentially libstd and all of its path dependencies)
         let std_src_dirs = [
             "src/build_helper",
-            "src/dlmalloc",
             "src/liballoc",
             "src/libbacktrace",
-            "src/libcompiler_builtins",
             "src/libcore",
-            "src/liblibc",
             "src/libpanic_abort",
             "src/libpanic_unwind",
             "src/librustc_asan",
@@ -871,20 +868,15 @@
             "src/librustc_tsan",
             "src/libstd",
             "src/libunwind",
-            "src/rustc/compiler_builtins_shim",
-            "src/rustc/libc_shim",
-            "src/rustc/dlmalloc_shim",
             "src/libtest",
             "src/libterm",
             "src/libprofiler_builtins",
             "src/stdsimd",
             "src/libproc_macro",
-        ];
-        let std_src_dirs_exclude = [
-            "src/libcompiler_builtins/compiler-rt/test",
+            "src/tools/rustc-std-workspace-core",
         ];
 
-        copy_src_dirs(builder, &std_src_dirs[..], &std_src_dirs_exclude[..], &dst_src);
+        copy_src_dirs(builder, &std_src_dirs[..], &[], &dst_src);
         for file in src_files.iter() {
             builder.copy(&builder.src.join(file), &dst_src.join(file));
         }
@@ -908,7 +900,7 @@
     }
 }
 
-const CARGO_VENDOR_VERSION: &str = "0.1.19";
+const CARGO_VENDOR_VERSION: &str = "0.1.22";
 
 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct PlainSourceTarball;
@@ -1510,8 +1502,7 @@
         }
 
         let xform = |p: &Path| {
-            let mut contents = String::new();
-            t!(t!(File::open(p)).read_to_string(&mut contents));
+            let mut contents = t!(fs::read_to_string(p));
             if rls_installer.is_none() {
                 contents = filter(&contents, "rls");
             }
@@ -1522,8 +1513,8 @@
                 contents = filter(&contents, "rustfmt");
             }
             let ret = tmp.join(p.file_name().unwrap());
-            t!(t!(File::create(&ret)).write_all(contents.as_bytes()));
-            return ret
+            t!(fs::write(&ret, &contents));
+            ret
         };
 
         if target.contains("apple-darwin") {
@@ -1868,8 +1859,7 @@
         let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
             panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
         });
-        let mut pass = String::new();
-        t!(t!(File::open(&file)).read_to_string(&mut pass));
+        let pass = t!(fs::read_to_string(&file));
 
         let today = output(Command::new("date").arg("+%Y-%m-%d"));
 
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 201129b..2d0625b 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -18,8 +18,7 @@
 //! `rustdoc`.
 
 use std::collections::HashSet;
-use std::fs::{self, File};
-use std::io::prelude::*;
+use std::fs;
 use std::io;
 use std::path::{PathBuf, Path};
 
@@ -379,12 +378,11 @@
         let version_info = out.join("version_info.html");
 
         if !builder.config.dry_run && !up_to_date(&version_input, &version_info) {
-            let mut info = String::new();
-            t!(t!(File::open(&version_input)).read_to_string(&mut info));
-            let info = info.replace("VERSION", &builder.rust_release())
-                           .replace("SHORT_HASH", builder.rust_info.sha_short().unwrap_or(""))
-                           .replace("STAMP", builder.rust_info.sha().unwrap_or(""));
-            t!(t!(File::create(&version_info)).write_all(info.as_bytes()));
+            let info = t!(fs::read_to_string(&version_input))
+                .replace("VERSION", &builder.rust_release())
+                .replace("SHORT_HASH", builder.rust_info.sha_short().unwrap_or(""))
+                .replace("STAMP", builder.rust_info.sha().unwrap_or(""));
+            t!(fs::write(&version_info, &info));
         }
 
         for file in t!(fs::read_dir(builder.src.join("src/doc"))) {
@@ -697,9 +695,6 @@
             return;
         }
 
-        // Build libstd docs so that we generate relative links.
-        builder.ensure(Std { stage, target });
-
         // Build rustc.
         builder.ensure(compile::Rustc { compiler, target });
 
@@ -718,12 +713,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);
         }
 
@@ -797,8 +796,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 });
@@ -822,6 +821,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);
     }
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 1211d48..c49da8f 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -121,11 +121,11 @@
         opts.optopt("", "on-fail", "command to run on failure", "CMD");
         opts.optflag("", "dry-run", "dry run; don't build anything");
         opts.optopt("", "stage",
-            "stage to build (indicates compiler to use/test, e.g. stage 0 uses the \
+            "stage to build (indicates compiler to use/test, e.g., stage 0 uses the \
              bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)",
             "N");
         opts.optmulti("", "keep-stage", "stage(s) to keep without recompiling \
-            (pass multiple times to keep e.g. both stages 0 and 1)", "N");
+            (pass multiple times to keep e.g., both stages 0 and 1)", "N");
         opts.optopt("", "src", "path to the root of the rust checkout", "DIR");
         opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
         opts.optflag("h", "help", "print this help message");
diff --git a/src/bootstrap/job.rs b/src/bootstrap/job.rs
index e6ee525..f7b1c50 100644
--- a/src/bootstrap/job.rs
+++ b/src/bootstrap/job.rs
@@ -10,7 +10,7 @@
 
 //! Job management on Windows for bootstrapping
 //!
-//! Most of the time when you're running a build system (e.g. make) you expect
+//! Most of the time when you're running a build system (e.g., make) you expect
 //! Ctrl-C or abnormal termination to actually terminate the entire tree of
 //! process in play, not just the one at the top. This currently works "by
 //! default" on Unix platforms because Ctrl-C actually sends a signal to the
@@ -162,11 +162,11 @@
         return
     }
 
-    // If we've got a parent process (e.g. the python script that called us)
+    // If we've got a parent process (e.g., the python script that called us)
     // then move ownership of this job object up to them. That way if the python
-    // script is killed (e.g. via ctrl-c) then we'll all be torn down.
+    // script is killed (e.g., via ctrl-c) then we'll all be torn down.
     //
-    // If we don't have a parent (e.g. this was run directly) then we
+    // If we don't have a parent (e.g., this was run directly) then we
     // intentionally leak the job object handle. When our process exits
     // (normally or abnormally) it will close the handle implicitly, causing all
     // processes in the job to be cleaned up.
@@ -184,7 +184,7 @@
 
     // If this failed, well at least we tried! An example of DuplicateHandle
     // failing in the past has been when the wrong python2 package spawned this
-    // build system (e.g. the `python2` package in MSYS instead of
+    // build system (e.g., the `python2` package in MSYS instead of
     // `mingw-w64-x86_64-python2`. Not sure why it failed, but the "failure
     // mode" here is that we only clean everything up when the build system
     // dies, not when the python parent does, so not too bad.
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 2832f5b..c879291 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -38,7 +38,7 @@
 //! However, compiletest itself tries to avoid running tests when the artifacts
 //! that are involved (mainly the compiler) haven't changed.
 //!
-//! When you execute `x.py build`, the steps which are executed are:
+//! When you execute `x.py build`, the steps executed are:
 //!
 //! * First, the python script is run. This will automatically download the
 //!   stage0 rustc and cargo according to `src/stage0.txt`, or use the cached
@@ -1067,9 +1067,8 @@
 
     /// Returns the `a.b.c` version that the given package is at.
     fn release_num(&self, package: &str) -> String {
-        let mut toml = String::new();
         let toml_file_name = self.src.join(&format!("src/tools/{}/Cargo.toml", package));
-        t!(t!(File::open(toml_file_name)).read_to_string(&mut toml));
+        let toml = t!(fs::read_to_string(&toml_file_name));
         for line in toml.lines() {
             let prefix = "version = \"";
             let suffix = "\"";
@@ -1135,10 +1134,10 @@
             let krate = &self.crates[&krate];
             if krate.is_local(self) {
                 ret.push(krate);
-                for dep in &krate.deps {
-                    if visited.insert(dep) && dep != "build_helper" {
-                        list.push(*dep);
-                    }
+            }
+            for dep in &krate.deps {
+                if visited.insert(dep) && dep != "build_helper" {
+                    list.push(*dep);
                 }
             }
         }
@@ -1151,8 +1150,7 @@
         }
 
         let mut paths = Vec::new();
-        let mut contents = Vec::new();
-        t!(t!(File::open(stamp)).read_to_end(&mut contents));
+        let contents = t!(fs::read(stamp));
         // This is the method we use for extracting paths from the stamp file passed to us. See
         // run_cargo for more information (in compile.rs).
         for part in contents.split(|b| *b == 0) {
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 448967e..8ff175b 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -21,7 +21,6 @@
 use std::env;
 use std::ffi::OsString;
 use std::fs::{self, File};
-use std::io::{Read, Write};
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
@@ -75,8 +74,7 @@
         }
 
         let rebuild_trigger = builder.src.join("src/rustllvm/llvm-rebuild-trigger");
-        let mut rebuild_trigger_contents = String::new();
-        t!(t!(File::open(&rebuild_trigger)).read_to_string(&mut rebuild_trigger_contents));
+        let rebuild_trigger_contents = t!(fs::read_to_string(&rebuild_trigger));
 
         let (out_dir, llvm_config_ret_dir) = if emscripten {
             let dir = builder.emscripten_llvm_out(target);
@@ -93,8 +91,7 @@
         let build_llvm_config = llvm_config_ret_dir
             .join(exe("llvm-config", &*builder.config.build));
         if done_stamp.exists() {
-            let mut done_contents = String::new();
-            t!(t!(File::open(&done_stamp)).read_to_string(&mut done_contents));
+            let done_contents = t!(fs::read_to_string(&done_stamp));
 
             // If LLVM was already built previously and contents of the rebuild-trigger file
             // didn't change from the previous build, then no action is required.
@@ -251,7 +248,7 @@
         configure_cmake(builder, target, &mut cfg, false);
 
         // FIXME: we don't actually need to build all LLVM tools and all LLVM
-        //        libraries here, e.g. we just want a few components and a few
+        //        libraries here, e.g., we just want a few components and a few
         //        tools. Figure out how to filter them down and only build the right
         //        tools and libs on all platforms.
 
@@ -261,7 +258,7 @@
 
         cfg.build();
 
-        t!(t!(File::create(&done_stamp)).write_all(rebuild_trigger_contents.as_bytes()));
+        t!(fs::write(&done_stamp, &rebuild_trigger_contents));
 
         build_llvm_config
     }
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 15d3bcc..7a9e6d4 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -21,8 +21,7 @@
 use std::collections::HashMap;
 use std::env;
 use std::ffi::{OsString, OsStr};
-use std::fs::{self, File};
-use std::io::Read;
+use std::fs;
 use std::path::PathBuf;
 use std::process::Command;
 
@@ -235,9 +234,7 @@
     }
 
     if build.config.channel == "stable" {
-        let mut stage0 = String::new();
-        t!(t!(File::open(build.src.join("src/stage0.txt")))
-            .read_to_string(&mut stage0));
+        let stage0 = t!(fs::read_to_string(build.src.join("src/stage0.txt")));
         if stage0.contains("\ndev:") {
             panic!("bootstrapping from a dev compiler in a stable release, but \
                     should only be bootstrapping from a released compiler!");
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index da82735..87d5737 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -16,8 +16,7 @@
 use std::env;
 use std::ffi::OsString;
 use std::fmt;
-use std::fs::{self, File};
-use std::io::Read;
+use std::fs;
 use std::iter;
 use std::path::{Path, PathBuf};
 use std::process::Command;
@@ -431,6 +430,45 @@
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CompiletestTest {
+    stage: u32,
+    host: Interned<String>,
+}
+
+impl Step for CompiletestTest {
+    type Output = ();
+
+    fn should_run(run: ShouldRun) -> ShouldRun {
+        run.path("src/tools/compiletest")
+    }
+
+    fn make_run(run: RunConfig) {
+        run.builder.ensure(CompiletestTest {
+            stage: run.builder.top_stage,
+            host: run.target,
+        });
+    }
+
+    /// Runs `cargo test` for compiletest.
+    fn run(self, builder: &Builder) {
+        let stage = self.stage;
+        let host = self.host;
+        let compiler = builder.compiler(stage, host);
+
+        let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolBootstrap,
+                                                 host,
+                                                 "test",
+                                                 "src/tools/compiletest",
+                                                 SourceType::InTree,
+                                                 &[]);
+
+        try_run(builder, &mut cargo);
+    }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Clippy {
     stage: u32,
     host: Interned<String>,
@@ -833,12 +871,6 @@
     suite: "run-fail-fulldeps"
 });
 
-host_test!(CompileFailFullDeps {
-    path: "src/test/compile-fail-fulldeps",
-    mode: "compile-fail",
-    suite: "compile-fail-fulldeps"
-});
-
 host_test!(Rustdoc {
     path: "src/test/rustdoc",
     mode: "rustdoc",
@@ -971,7 +1003,7 @@
         }
 
         if builder.no_std(target) == Some(true) {
-            // for no_std run-make (e.g. thumb*),
+            // for no_std run-make (e.g., thumb*),
             // we need a host compiler which is called by cargo.
             builder.ensure(compile::Std { compiler, target: compiler.host });
         }
@@ -1277,7 +1309,7 @@
 
     /// Run `rustdoc --test` for all documentation in `src/doc`.
     ///
-    /// This will run all tests in our markdown documentation (e.g. the book)
+    /// This will run all tests in our markdown documentation (e.g., the book)
     /// located in `src/doc`. The `rustdoc` that's run is the one that sits next to
     /// `compiler`.
     fn run(self, builder: &Builder) {
@@ -1427,10 +1459,8 @@
 }
 
 fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) -> bool {
-    match File::open(markdown) {
-        Ok(mut file) => {
-            let mut contents = String::new();
-            t!(file.read_to_string(&mut contents));
+    match fs::read_to_string(markdown) {
+        Ok(contents) => {
             if !contents.contains("```") {
                 return true;
             }
@@ -1567,10 +1597,7 @@
         let builder = run.builder;
         run = run.krate("test");
         for krate in run.builder.in_tree_crates("std") {
-            if krate.is_local(&run.builder)
-                && !(krate.name.starts_with("rustc_") && krate.name.ends_with("san"))
-                && krate.name != "dlmalloc"
-            {
+            if !(krate.name.starts_with("rustc_") && krate.name.ends_with("san")) {
                 run = run.path(krate.local_path(&builder).to_str().unwrap());
             }
         }
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 58c5296..1bd4403 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -646,7 +646,7 @@
             self.cargo_out(compiler, tool.get_mode(), *host).join("deps"),
         ];
 
-        // On MSVC a tool may invoke a C compiler (e.g. compiletest in run-make
+        // On MSVC a tool may invoke a C compiler (e.g., compiletest in run-make
         // mode) and that C compiler may need some extra PATH modification. Do
         // so here.
         if compiler.host.contains("msvc") {
diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index 0cbb080..a580a87 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -224,14 +224,12 @@
 // Timestamps are created automatically when the result of `native_lib_boilerplate` goes out
 // of scope, so all the build actions should be completed until then.
 pub fn native_lib_boilerplate(
-    src_name: &str,
+    src_dir: &Path,
     out_name: &str,
     link_name: &str,
     search_subdir: &str,
 ) -> Result<NativeLibBoilerplate, ()> {
-    let current_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
-    let src_dir = current_dir.join("..").join(src_name);
-    rerun_if_changed_anything_in_dir(&src_dir);
+    rerun_if_changed_anything_in_dir(src_dir);
 
     let out_dir = env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or_else(||
         env::var_os("OUT_DIR").unwrap());
@@ -248,9 +246,9 @@
     );
 
     let timestamp = out_dir.join("rustbuild.timestamp");
-    if !up_to_date(Path::new("build.rs"), &timestamp) || !up_to_date(&src_dir, &timestamp) {
+    if !up_to_date(Path::new("build.rs"), &timestamp) || !up_to_date(src_dir, &timestamp) {
         Ok(NativeLibBoilerplate {
-            src_dir: src_dir,
+            src_dir: src_dir.to_path_buf(),
             out_dir: out_dir,
         })
     } else {
@@ -279,8 +277,11 @@
     } else {
         format!("static={}", link_name)
     };
+    // The source for `compiler-rt` comes from the `compiler-builtins` crate, so
+    // load our env var set by cargo to find the source code.
+    let dir = env::var_os("DEP_COMPILER_RT_COMPILER_RT").unwrap();
     let lib = native_lib_boilerplate(
-        "libcompiler_builtins/compiler-rt",
+        dir.as_ref(),
         sanitizer_name,
         &to_link,
         search_path,
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index c7e6af2..4f8a3c0 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -52,8 +52,8 @@
     CXX=arm-linux-gnueabi-g++ CXXFLAGS="-march=armv6 -marm" \
     bash musl.sh arm && \
     env \
-    CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm" \
-    CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm" \
+    CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm -mfpu=vfp" \
+    CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm -mfpu=vfp" \
     bash musl.sh armhf && \
     env \
     CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv7-a" \
diff --git a/src/ci/docker/mingw-check/Dockerfile b/src/ci/docker/mingw-check/Dockerfile
index aab339f..10aedf6 100644
--- a/src/ci/docker/mingw-check/Dockerfile
+++ b/src/ci/docker/mingw-check/Dockerfile
@@ -20,4 +20,5 @@
 RUN sh /scripts/sccache.sh
 
 ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
-ENV SCRIPT python2.7 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu
+ENV SCRIPT python2.7 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
+           python2.7 ../x.py build --stage 0 src/tools/build-manifest
diff --git a/src/dlmalloc b/src/dlmalloc
deleted file mode 160000
index c99638d..0000000
--- a/src/dlmalloc
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit c99638dc2ecfc750cc1656f6edb2bd062c1e0981
diff --git a/src/doc/book b/src/doc/book
index 616fe41..74d81d8 160000
--- a/src/doc/book
+++ b/src/doc/book
@@ -1 +1 @@
-Subproject commit 616fe4172b688393aeee5f34935cc25733c9c062
+Subproject commit 74d81d80052cb88925f0e73b12fbd0b73ab7b5a0
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 4fc5f42..94f2104 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -22,6 +22,13 @@
 This flag lets you append multiple extra arguments to the linker invocation. The
 options should be separated by spaces.
 
+## linker-flavor
+
+This flag lets you control the linker flavor used by `rustc`. If a linker is given with the
+`-C linker` flag described above then the linker flavor is inferred from the value provided. If no
+linker is given then the linker flavor is used to determine the linker to use. Every `rustc` target
+defaults to some linker flavor.
+
 ## link-dead-code
 
 Normally, the linker will remove dead code. This flag disables this behavior.
diff --git a/src/doc/rustc/src/targets/built-in.md b/src/doc/rustc/src/targets/built-in.md
index 8620346..2e94ebe 100644
--- a/src/doc/rustc/src/targets/built-in.md
+++ b/src/doc/rustc/src/targets/built-in.md
@@ -6,5 +6,5 @@
 
 To see the list of built-in targets, you can run `rustc --print target-list`,
 or look at [the API
-docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/#modules).
+docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/index.html#modules).
 Each module there defines a builder for a particular target.
\ No newline at end of file
diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md
index 07e3a79..3d63d07 100644
--- a/src/doc/rustc/src/targets/index.md
+++ b/src/doc/rustc/src/targets/index.md
@@ -4,7 +4,7 @@
 architecture. The list of *targets* are the possible architectures that you can build for.
 
 To see all the options that you can set with a target, see the docs
-[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/struct.Target.html).
+[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/struct.Target.html).
 
 To compile to a particular target, use the `--target` flag:
 
diff --git a/src/doc/unstable-book/src/compiler-flags/linker-flavor.md b/src/doc/unstable-book/src/compiler-flags/linker-flavor.md
deleted file mode 100644
index 3965960..0000000
--- a/src/doc/unstable-book/src/compiler-flags/linker-flavor.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# `linker-flavor`
-
-The tracking issue for this feature is: None
-
-------------------------
-
-Every `rustc` target defaults to some linker. For example, Linux targets default
-to gcc. In some cases, you may want to override the default; you can do that
-with the unstable CLI argument: `-Z linker-flavor`.
-
-Here how you would use this flag to link a Rust binary for the
-`thumbv7m-none-eabi` using LLD instead of GCC.
-
-``` text
-$ xargo rustc --target thumbv7m-none-eabi -- \
-    -C linker=ld.lld \
-    -Z linker-flavor=ld \
-    -Z print-link-args | tr ' ' '\n'
-"ld.lld"
-"-L"
-"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib"
-"$PWD/target/thumbv7m-none-eabi/debug/deps/app-512e9dbf385f233c.0.o"
-"-o"
-"$PWD/target/thumbv7m-none-eabi/debug/deps/app-512e9dbf385f233c"
-"--gc-sections"
-"-L"
-"$PWD/target/thumbv7m-none-eabi/debug/deps"
-"-L"
-"$PWD/target/debug/deps"
-"-L"
-"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib"
-"-Bstatic"
-"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib/libcore-e1ccb7dfb1cb9ebb.rlib"
-"-Bdynamic"
-```
-
-Whereas the default is:
-
-``` text
-$ xargo rustc --target thumbv7m-none-eabi -- \
-    -C link-arg=-nostartfiles \
-    -Z print-link-args | tr ' ' '\n'
-"arm-none-eabi-gcc"
-"-L"
-"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib"
-"$PWD/target/thumbv7m-none-eabi/debug/deps/app-961e39416baa38d9.0.o"
-"-o"
-"$PWD/target/thumbv7m-none-eabi/debug/deps/app-961e39416baa38d9"
-"-Wl,--gc-sections"
-"-nodefaultlibs"
-"-L"
-"$PWD/target/thumbv7m-none-eabi/debug/deps"
-"-L"
-"$PWD/target/debug/deps"
-"-L"
-"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib"
-"-Wl,-Bstatic"
-"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib/libcore-e1ccb7dfb1cb9ebb.rlib"
-"-nostartfiles"
-"-Wl,-Bdynamic"
-```
diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md
index 8e888de..968534e 100644
--- a/src/doc/unstable-book/src/language-features/generators.md
+++ b/src/doc/unstable-book/src/language-features/generators.md
@@ -149,7 +149,7 @@
 * Whenever a generator is dropped it will drop all captured environment
   variables.
 
-Note that unlike closures generators at this time cannot take any arguments.
+Note that unlike closures, generators at this time cannot take any arguments.
 That is, generators must always look like `|| { ... }`. This restriction may be
 lifted at a future date, the design is ongoing!
 
diff --git a/src/doc/unstable-book/src/language-features/unsized-locals.md b/src/doc/unstable-book/src/language-features/unsized-locals.md
index 1165ab9..edc039f 100644
--- a/src/doc/unstable-book/src/language-features/unsized-locals.md
+++ b/src/doc/unstable-book/src/language-features/unsized-locals.md
@@ -8,7 +8,7 @@
 
 This implements [RFC1909]. When turned on, you can have unsized arguments and locals:
 
-[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-coercions.md
+[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md
 
 ```rust
 #![feature(unsized_locals)]
diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py
index a376c85..f02c7d8 100755
--- a/src/etc/gdb_rust_pretty_printing.py
+++ b/src/etc/gdb_rust_pretty_printing.py
@@ -9,6 +9,7 @@
 # except according to those terms.
 
 import gdb
+import re
 import sys
 import debugger_pretty_printers_common as rustpp
 
@@ -20,6 +21,16 @@
 
 rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string = True)
 
+# The btree pretty-printers fail in a confusing way unless
+# https://sourceware.org/bugzilla/show_bug.cgi?id=21763 is fixed.
+# This fix went in 8.1, so check for that.
+# See https://github.com/rust-lang/rust/issues/56730
+gdb_81 = False
+_match = re.match('([0-9]+)\\.([0-9]+)', gdb.VERSION)
+if _match:
+    if int(_match.group(1)) > 8 or (int(_match.group(1)) == 8 and int(_match.group(2)) >= 1):
+        gdb_81 = True
+
 #===============================================================================
 # GDB Pretty Printing Module for Rust
 #===============================================================================
@@ -110,10 +121,10 @@
     if type_kind == rustpp.TYPE_KIND_STD_VECDEQUE:
         return RustStdVecDequePrinter(val)
 
-    if type_kind == rustpp.TYPE_KIND_STD_BTREESET:
+    if type_kind == rustpp.TYPE_KIND_STD_BTREESET and gdb_81:
         return RustStdBTreeSetPrinter(val)
 
-    if type_kind == rustpp.TYPE_KIND_STD_BTREEMAP:
+    if type_kind == rustpp.TYPE_KIND_STD_BTREEMAP and gdb_81:
         return RustStdBTreeMapPrinter(val)
 
     if type_kind == rustpp.TYPE_KIND_STD_STRING:
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/Cargo.toml b/src/liballoc/Cargo.toml
index 642a43d..b2eb356 100644
--- a/src/liballoc/Cargo.toml
+++ b/src/liballoc/Cargo.toml
@@ -11,10 +11,10 @@
 
 [dependencies]
 core = { path = "../libcore" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
+compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] }
 
 [dev-dependencies]
-rand = "0.5"
+rand = "0.6"
 
 [[test]]
 name = "collectionstests"
@@ -28,3 +28,6 @@
 name = "vec_deque_append_bench"
 path = "../liballoc/benches/vec_deque_append.rs"
 harness = false
+
+[features]
+compiler-builtins-mem = ['compiler_builtins/mem']
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index c3a84bf..83adcce 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -801,7 +801,7 @@
  *        safe.)
  *      - It is in practice very useful to have Box<T> be unconditionally
  *        Unpin because of trait objects, for which the structural auto
- *        trait functionality does not apply (e.g. Box<dyn Foo> would
+ *        trait functionality does not apply (e.g., Box<dyn Foo> would
  *        otherwise not be Unpin).
  *
  *  Another type with the same semantics as Box but only a conditional
diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs
index 8c36962..5dd0ea7 100644
--- a/src/liballoc/collections/binary_heap.rs
+++ b/src/liballoc/collections/binary_heap.rs
@@ -858,7 +858,7 @@
     }
 }
 
-/// Hole represents a hole in a slice i.e. an index without valid value
+/// Hole represents a hole in a slice i.e., an index without valid value
 /// (because it was moved from or duplicated).
 /// In drop, `Hole` will restore the slice by filling the hole
 /// position with the value that was originally removed.
diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs
index af9a707..fa74dce 100644
--- a/src/liballoc/collections/btree/set.rs
+++ b/src/liballoc/collections/btree/set.rs
@@ -258,7 +258,7 @@
     }
 
     /// Visits the values representing the difference,
-    /// i.e. the values that are in `self` but not in `other`,
+    /// i.e., the values that are in `self` but not in `other`,
     /// in ascending order.
     ///
     /// # Examples
@@ -286,7 +286,7 @@
     }
 
     /// Visits the values representing the symmetric difference,
-    /// i.e. the values that are in `self` or in `other` but not in both,
+    /// i.e., the values that are in `self` or in `other` but not in both,
     /// in ascending order.
     ///
     /// # Examples
@@ -316,7 +316,7 @@
     }
 
     /// Visits the values representing the intersection,
-    /// i.e. the values that are both in `self` and `other`,
+    /// i.e., the values that are both in `self` and `other`,
     /// in ascending order.
     ///
     /// # Examples
@@ -344,7 +344,7 @@
     }
 
     /// Visits the values representing the union,
-    /// i.e. all the values in `self` or `other`, without duplicates,
+    /// i.e., all the values in `self` or `other`, without duplicates,
     /// in ascending order.
     ///
     /// # Examples
@@ -455,7 +455,7 @@
     }
 
     /// Returns `true` if the set is a subset of another,
-    /// i.e. `other` contains at least all the values in `self`.
+    /// i.e., `other` contains at least all the values in `self`.
     ///
     /// # Examples
     ///
@@ -498,7 +498,7 @@
     }
 
     /// Returns `true` if the set is a superset of another,
-    /// i.e. `self` contains at least all the values in `other`.
+    /// i.e., `self` contains at least all the values in `other`.
     ///
     /// # Examples
     ///
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index c8ee40f..0c5926f 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -1026,7 +1026,10 @@
             iter: Iter {
                 tail: drain_tail,
                 head: drain_head,
-                ring: unsafe { self.buffer_as_mut_slice() },
+                // Crucially, we only create shared references from `self` here and read from
+                // it.  We do not write to `self` nor reborrow to a mutable reference.
+                // Hence the raw pointer we created above, for `deque`, remains valid.
+                ring: unsafe { self.buffer_as_slice() },
             },
         }
     }
@@ -2795,7 +2798,7 @@
             // 0, 1, 2, .., len - 1
             let expected = (0..).take(len).collect::<VecDeque<_>>();
             for tail_pos in 0..cap {
-                for to_remove in 0..len + 1 {
+                for to_remove in 0..=len {
                     tester.tail = tail_pos;
                     tester.head = tail_pos;
                     for i in 0..len {
@@ -2821,10 +2824,10 @@
         let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
 
         let cap = tester.capacity();
-        for len in 0..cap + 1 {
-            for tail in 0..cap + 1 {
-                for drain_start in 0..len + 1 {
-                    for drain_end in drain_start..len + 1 {
+        for len in 0..=cap {
+            for tail in 0..=cap {
+                for drain_start in 0..=len {
+                    for drain_end in drain_start..=len {
                         tester.tail = tail;
                         tester.head = tail;
                         for i in 0..len {
@@ -2866,10 +2869,10 @@
         tester.reserve(63);
         let max_cap = tester.capacity();
 
-        for len in 0..cap + 1 {
+        for len in 0..=cap {
             // 0, 1, 2, .., len - 1
             let expected = (0..).take(len).collect::<VecDeque<_>>();
-            for tail_pos in 0..max_cap + 1 {
+            for tail_pos in 0..=max_cap {
                 tester.tail = tail_pos;
                 tester.head = tail_pos;
                 tester.reserve(63);
@@ -2899,7 +2902,7 @@
         // len is the length *before* splitting
         for len in 0..cap {
             // index to split at
-            for at in 0..len + 1 {
+            for at in 0..=len {
                 // 0, 1, 2, .., at - 1 (may be empty)
                 let expected_self = (0..).take(at).collect::<VecDeque<_>>();
                 // at, at + 1, .., len - 1 (may be empty)
@@ -2927,7 +2930,7 @@
     fn test_from_vec() {
         use vec::Vec;
         for cap in 0..35 {
-            for len in 0..cap + 1 {
+            for len in 0..=cap {
                 let mut vec = Vec::with_capacity(cap);
                 vec.extend(0..len);
 
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index e87bf78..f4674b3 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -739,7 +739,7 @@
 // On 64-bit we just need to check for overflow since trying to allocate
 // `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add
 // an extra guard for this in case we're running on a platform which can use
-// all 4GB in user-space. e.g. PAE or x32
+// all 4GB in user-space. e.g., PAE or x32
 
 #[inline]
 fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> {
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index c0a947e..52ad30c 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -276,7 +276,7 @@
 /// See the [module-level documentation](./index.html) for more details.
 ///
 /// The inherent methods of `Rc` are all associated functions, which means
-/// that you have to call them as e.g. [`Rc::get_mut(&mut value)`][get_mut] instead of
+/// that you have to call them as e.g., [`Rc::get_mut(&mut value)`][get_mut] instead of
 /// `value.get_mut()`. This avoids conflicts with methods of the inner
 /// type `T`.
 ///
@@ -1252,7 +1252,7 @@
     }
 
     /// Return `None` when the pointer is dangling and there is no allocated `RcBox`,
-    /// i.e. this `Weak` was created by `Weak::new`
+    /// i.e., this `Weak` was created by `Weak::new`
     #[inline]
     fn inner(&self) -> Option<&RcBox<T>> {
         if is_dangling(self.ptr) {
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 22da9dd..510b4b0 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -177,7 +177,7 @@
 impl<T> [T] {
     /// Sorts the slice.
     ///
-    /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
+    /// This sort is stable (i.e., does not reorder equal elements) and `O(n log n)` worst-case.
     ///
     /// When applicable, unstable sorting is preferred because it is generally faster than stable
     /// sorting and it doesn't allocate auxiliary memory.
@@ -211,7 +211,7 @@
 
     /// Sorts the slice with a comparator function.
     ///
-    /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
+    /// This sort is stable (i.e., does not reorder equal elements) and `O(n log n)` worst-case.
     ///
     /// The comparator function must define a total ordering for the elements in the slice. If
     /// the ordering is not total, the order of the elements is unspecified. An order is a
@@ -264,7 +264,7 @@
 
     /// Sorts the slice with a key extraction function.
     ///
-    /// This sort is stable (i.e. does not reorder equal elements) and `O(m n log(m n))`
+    /// This sort is stable (i.e., does not reorder equal elements) and `O(m n log(m n))`
     /// worst-case, where the key function is `O(m)`.
     ///
     /// When applicable, unstable sorting is preferred because it is generally faster than stable
@@ -301,10 +301,10 @@
     ///
     /// During sorting, the key function is called only once per element.
     ///
-    /// This sort is stable (i.e. does not reorder equal elements) and `O(m n + n log n)`
+    /// This sort is stable (i.e., does not reorder equal elements) and `O(m n + n log n)`
     /// worst-case, where the key function is `O(m)`.
     ///
-    /// For simple key functions (e.g. functions that are property accesses or
+    /// For simple key functions (e.g., functions that are property accesses or
     /// basic operations), [`sort_by_key`](#method.sort_by_key) is likely to be
     /// faster.
     ///
@@ -589,7 +589,7 @@
     type Output = Vec<T>;
 
     fn concat(&self) -> Vec<T> {
-        let size = self.iter().fold(0, |acc, v| acc + v.borrow().len());
+        let size = self.iter().map(|slice| slice.borrow().len()).sum();
         let mut result = Vec::with_capacity(size);
         for v in self {
             result.extend_from_slice(v.borrow())
@@ -603,8 +603,8 @@
             Some(first) => first,
             None => return vec![],
         };
-        let size = self.iter().fold(0, |acc, v| acc + v.borrow().len());
-        let mut result = Vec::with_capacity(size + self.len());
+        let size = self.iter().map(|slice| slice.borrow().len()).sum::<usize>() + self.len() - 1;
+        let mut result = Vec::with_capacity(size);
         result.extend_from_slice(first.borrow());
 
         for v in iter {
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 662f8ae..4652c0e 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);
@@ -1732,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
+            }
+        }
     }
 }
 
@@ -1753,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));
     }
 }
 
@@ -1769,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));
     }
 }
 
@@ -2158,7 +2169,7 @@
         use core::fmt::Write;
         let mut buf = String::new();
         buf.write_fmt(format_args!("{}", self))
-           .expect("a Display implementation return an error unexpectedly");
+           .expect("a Display implementation returned an error unexpectedly");
         buf.shrink_to_fit();
         buf
     }
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 0a397f7..111459d 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -1121,7 +1121,7 @@
     }
 
     /// Return `None` when the pointer is dangling and there is no allocated `ArcInner`,
-    /// i.e. this `Weak` was created by `Weak::new`
+    /// i.e., this `Weak` was created by `Weak::new`
     #[inline]
     fn inner(&self) -> Option<&ArcInner<T>> {
         if is_dangling(self.ptr) {
diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs
index 8494463..536291d 100644
--- a/src/liballoc/tests/binary_heap.rs
+++ b/src/liballoc/tests/binary_heap.rs
@@ -14,7 +14,7 @@
 use std::panic::{self, AssertUnwindSafe};
 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 
-use rand::{thread_rng, Rng};
+use rand::{thread_rng, seq::SliceRandom};
 
 #[test]
 fn test_iterator() {
@@ -318,11 +318,11 @@
     const NTEST: usize = 10;
 
     // don't use 0 in the data -- we want to catch the zeroed-out case.
-    let data = (1..DATASZ + 1).collect::<Vec<_>>();
+    let data = (1..=DATASZ).collect::<Vec<_>>();
 
     // since it's a fuzzy test, run several tries.
     for _ in 0..NTEST {
-        for i in 1..DATASZ + 1 {
+        for i in 1..=DATASZ {
             DROP_COUNTER.store(0, Ordering::SeqCst);
 
             let mut panic_ords: Vec<_> = data.iter()
@@ -332,7 +332,7 @@
             let panic_item = PanicOrd(i, true);
 
             // heapify the sane items
-            rng.shuffle(&mut panic_ords);
+            panic_ords.shuffle(&mut rng);
             let mut heap = BinaryHeap::from(panic_ords);
             let inner_data;
 
diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs
index 6ebdb86..33ef13a 100644
--- a/src/liballoc/tests/btree/map.rs
+++ b/src/liballoc/tests/btree/map.rs
@@ -302,7 +302,7 @@
     for i in 0..size {
         for j in i..size {
             let mut kvs = map.range((Included(&i), Included(&j))).map(|(&k, &v)| (k, v));
-            let mut pairs = (i..j + 1).map(|i| (i, i));
+            let mut pairs = (i..=j).map(|i| (i, i));
 
             for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
                 assert_eq!(kv, pair);
@@ -321,7 +321,7 @@
     for i in 0..size {
         for j in i..size {
             let mut kvs = map.range_mut((Included(&i), Included(&j))).map(|(&k, &mut v)| (k, v));
-            let mut pairs = (i..j + 1).map(|i| (i, i));
+            let mut pairs = (i..=j).map(|i| (i, i));
 
             for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
                 assert_eq!(kv, pair);
diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs
index a50f99b..6f31e6c 100644
--- a/src/liballoc/tests/slice.rs
+++ b/src/liballoc/tests/slice.rs
@@ -18,7 +18,7 @@
 use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize};
 use std::thread;
 
-use rand::{Rng, RngCore, thread_rng};
+use rand::{Rng, RngCore, thread_rng, seq::SliceRandom};
 use rand::distributions::Standard;
 
 fn square(n: usize) -> usize {
@@ -459,7 +459,7 @@
     for i in 0..v.len() {
         v[i] = i as i32;
     }
-    v.sort_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap());
+    v.sort_by(|_, _| *[Less, Equal, Greater].choose(&mut rng).unwrap());
     v.sort();
     for i in 0..v.len() {
         assert_eq!(v[i], i as i32);
@@ -484,7 +484,7 @@
             // create a vector like [(6, 1), (5, 1), (6, 2), ...],
             // where the first item of each tuple is random, but
             // the second item represents which occurrence of that
-            // number this element is, i.e. the second elements
+            // number this element is, i.e., the second elements
             // will occur in sorted order.
             let mut orig: Vec<_> = (0..len)
                 .map(|_| {
@@ -502,7 +502,7 @@
             // This comparison includes the count (the second item
             // of the tuple), so elements with equal first items
             // will need to be ordered with increasing
-            // counts... i.e. exactly asserting that this sort is
+            // counts... i.e., exactly asserting that this sort is
             // stable.
             assert!(v.windows(2).all(|w| w[0] <= w[1]));
 
@@ -1579,7 +1579,7 @@
             }).join();
 
             // Check that the number of things dropped is exactly
-            // what we expect (i.e. the contents of `v`).
+            // what we expect (i.e., the contents of `v`).
             for (i, c) in DROP_COUNTS.iter().enumerate().take(len) {
                 let count = c.load(Relaxed);
                 assert!(count == 1,
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index a5fa7f0..9ad8ad1 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -1005,7 +1005,7 @@
     // Note that there are subtleties with the number of backslashes
     // on the left- and right-hand sides. In particular, Unicode code points
     // are usually escaped with two backslashes on the right-hand side, as
-    // they are escaped. However, when the character is unescaped (e.g. for
+    // they are escaped. However, when the character is unescaped (e.g., for
     // printable characters), only a single backslash appears (as the character
     // itself appears in the debug string).
     assert_eq!("abc".escape_debug(), "abc");
@@ -1378,7 +1378,7 @@
 fn check_contains_all_substrings(s: &str) {
     assert!(s.contains(""));
     for i in 0..s.len() {
-        for j in i+1..s.len() + 1 {
+        for j in i+1..=s.len() {
             assert!(s.contains(&s[i..j]));
         }
     }
@@ -1514,9 +1514,9 @@
 
 #[test]
 fn trim_ws() {
-    assert_eq!(" \t  a \t  ".trim_left_matches(|c: char| c.is_whitespace()),
+    assert_eq!(" \t  a \t  ".trim_start_matches(|c: char| c.is_whitespace()),
                     "a \t  ");
-    assert_eq!(" \t  a \t  ".trim_right_matches(|c: char| c.is_whitespace()),
+    assert_eq!(" \t  a \t  ".trim_end_matches(|c: char| c.is_whitespace()),
                " \t  a");
     assert_eq!(" \t  a \t  ".trim_start_matches(|c: char| c.is_whitespace()),
                     "a \t  ");
@@ -1524,9 +1524,9 @@
                " \t  a");
     assert_eq!(" \t  a \t  ".trim_matches(|c: char| c.is_whitespace()),
                     "a");
-    assert_eq!(" \t   \t  ".trim_left_matches(|c: char| c.is_whitespace()),
+    assert_eq!(" \t   \t  ".trim_start_matches(|c: char| c.is_whitespace()),
                          "");
-    assert_eq!(" \t   \t  ".trim_right_matches(|c: char| c.is_whitespace()),
+    assert_eq!(" \t   \t  ".trim_end_matches(|c: char| c.is_whitespace()),
                "");
     assert_eq!(" \t   \t  ".trim_start_matches(|c: char| c.is_whitespace()),
                          "");
diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs
index 3ea6c87..1f2a721 100644
--- a/src/liballoc/tests/vec_deque.rs
+++ b/src/liballoc/tests/vec_deque.rs
@@ -861,7 +861,7 @@
         ring.push_back(i);
 
         let (left, right) = ring.as_slices();
-        let expected: Vec<_> = (0..i + 1).collect();
+        let expected: Vec<_> = (0..=i).collect();
         assert_eq!(left, &expected[..]);
         assert_eq!(right, []);
     }
@@ -869,7 +869,7 @@
     for j in -last..0 {
         ring.push_front(j);
         let (left, right) = ring.as_slices();
-        let expected_left: Vec<_> = (-last..j + 1).rev().collect();
+        let expected_left: Vec<_> = (-last..=j).rev().collect();
         let expected_right: Vec<_> = (0..first).collect();
         assert_eq!(left, &expected_left[..]);
         assert_eq!(right, &expected_right[..]);
@@ -889,7 +889,7 @@
         ring.push_back(i);
 
         let (left, right) = ring.as_mut_slices();
-        let expected: Vec<_> = (0..i + 1).collect();
+        let expected: Vec<_> = (0..=i).collect();
         assert_eq!(left, &expected[..]);
         assert_eq!(right, []);
     }
@@ -897,7 +897,7 @@
     for j in -last..0 {
         ring.push_front(j);
         let (left, right) = ring.as_mut_slices();
-        let expected_left: Vec<_> = (-last..j + 1).rev().collect();
+        let expected_left: Vec<_> = (-last..=j).rev().collect();
         let expected_right: Vec<_> = (0..first).collect();
         assert_eq!(left, &expected_left[..]);
         assert_eq!(right, &expected_right[..]);
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index ca7c766..63af69d 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -213,7 +213,7 @@
 /// about its design. This ensures that it's as low-overhead as possible in
 /// the general case, and can be correctly manipulated in primitive ways
 /// by unsafe code. Note that these guarantees refer to an unqualified `Vec<T>`.
-/// If additional type parameters are added (e.g. to support custom allocators),
+/// If additional type parameters are added (e.g., to support custom allocators),
 /// overriding their defaults may change the behavior.
 ///
 /// Most fundamentally, `Vec` is and always will be a (pointer, capacity, length)
diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins
deleted file mode 160000
index fe74674..0000000
--- a/src/libcompiler_builtins
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit fe74674f6e4be76d47b66f67d529ebf4186f4eb1
diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml
index 7fd61f0..fa2ab11 100644
--- a/src/libcore/Cargo.toml
+++ b/src/libcore/Cargo.toml
@@ -20,7 +20,7 @@
 path = "../libcore/benches/lib.rs"
 
 [dev-dependencies]
-rand = "0.5"
+rand = "0.6"
 
 [features]
 # Make panics and failed asserts immediately abort without formatting any message
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index 5863980..8db7d33 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -69,7 +69,7 @@
     /// * `align` must be a power of two,
     ///
     /// * `size`, when rounded up to the nearest multiple of `align`,
-    ///    must not overflow (i.e. the rounded value must be less than
+    ///    must not overflow (i.e., the rounded value must be less than
     ///    `usize::MAX`).
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[inline]
@@ -177,7 +177,7 @@
     /// to ensure that the following address will satisfy `align`
     /// (measured in bytes).
     ///
-    /// E.g. if `self.size()` is 9, then `self.padding_needed_for(4)`
+    /// e.g., if `self.size()` is 9, then `self.padding_needed_for(4)`
     /// returns 3, because that is the minimum number of bytes of
     /// padding required to get a 4-aligned address (assuming that the
     /// corresponding memory block starts at a 4-aligned address).
@@ -455,7 +455,7 @@
     /// if the caller does not ensure that `layout` has non-zero size.
     ///
     /// (Extension subtraits might provide more specific bounds on
-    /// behavior, e.g. guarantee a sentinel address or a null pointer
+    /// behavior, e.g., guarantee a sentinel address or a null pointer
     /// in response to a zero-size allocation request.)
     ///
     /// The allocated block of memory may or may not be initialized.
@@ -550,10 +550,10 @@
     /// * `new_size` must be greater than zero.
     ///
     /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
-    ///   must not overflow (i.e. the rounded value must be less than `usize::MAX`).
+    ///   must not overflow (i.e., the rounded value must be less than `usize::MAX`).
     ///
     /// (Extension subtraits might provide more specific bounds on
-    /// behavior, e.g. guarantee a sentinel address or a null pointer
+    /// behavior, e.g., guarantee a sentinel address or a null pointer
     /// in response to a zero-size allocation request.)
     ///
     /// # Errors
@@ -616,7 +616,7 @@
 ///   whether to return `Err`, or to return `Ok` with some pointer.
 ///
 /// * If an `Alloc` implementation chooses to return `Ok` in this
-///   case (i.e. the pointer denotes a zero-sized inaccessible block)
+///   case (i.e., the pointer denotes a zero-sized inaccessible block)
 ///   then that returned pointer must be considered "currently
 ///   allocated". On such an allocator, *all* methods that take
 ///   currently-allocated pointers as inputs must accept these
@@ -651,7 +651,7 @@
 ///
 ///  * if a layout `k` fits a memory block (denoted by `ptr`)
 ///    currently allocated via an allocator `a`, then it is legal to
-///    use that layout to deallocate it, i.e. `a.dealloc(ptr, k);`.
+///    use that layout to deallocate it, i.e., `a.dealloc(ptr, k);`.
 ///
 /// # Unsafety
 ///
@@ -673,7 +673,7 @@
 
     // (Note: some existing allocators have unspecified but well-defined
     // behavior in response to a zero size allocation request ;
-    // e.g. in C, `malloc` of 0 will either return a null pointer or a
+    // e.g., in C, `malloc` of 0 will either return a null pointer or a
     // unique pointer, but will not have arbitrary undefined
     // behavior.
     // However in jemalloc for example,
@@ -688,7 +688,7 @@
     ///
     /// The returned block of storage may or may not have its contents
     /// initialized. (Extension subtraits might restrict this
-    /// behavior, e.g. to ensure initialization to particular sets of
+    /// behavior, e.g., to ensure initialization to particular sets of
     /// bit patterns.)
     ///
     /// # Safety
@@ -697,7 +697,7 @@
     /// if the caller does not ensure that `layout` has non-zero size.
     ///
     /// (Extension subtraits might provide more specific bounds on
-    /// behavior, e.g. guarantee a sentinel address or a null pointer
+    /// behavior, e.g., guarantee a sentinel address or a null pointer
     /// in response to a zero-size allocation request.)
     ///
     /// # Errors
@@ -803,10 +803,10 @@
     /// * `new_size` must be greater than zero.
     ///
     /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
-    ///   must not overflow (i.e. the rounded value must be less than `usize::MAX`).
+    ///   must not overflow (i.e., the rounded value must be less than `usize::MAX`).
     ///
     /// (Extension subtraits might provide more specific bounds on
-    /// behavior, e.g. guarantee a sentinel address or a null pointer
+    /// behavior, e.g., guarantee a sentinel address or a null pointer
     /// in response to a zero-size allocation request.)
     ///
     /// # Errors
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index c2113df..f521ab9 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -126,7 +126,7 @@
     }
 }
 
-// Ensure that the result of e.g. joining a thread can be printed and
+// Ensure that the result of e.g., joining a thread can be printed and
 // hence used with `unwrap`. May eventually no longer be needed if
 // dispatch works with upcasting.
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs
index 6c59730..b0aca65 100644
--- a/src/libcore/benches/iter.rs
+++ b/src/libcore/benches/iter.rs
@@ -282,6 +282,12 @@
     (0i64..1000000).chain(1000000..).take_while(|&x| x < 1111111)
 }
 
+bench_sums! {
+    bench_cycle_take_sum,
+    bench_cycle_take_ref_sum,
+    (0i64..10000).cycle().take(1000000)
+}
+
 // Checks whether Skip<Zip<A,B>> is as fast as Zip<Skip<A>, Skip<B>>, from
 // https://users.rust-lang.org/t/performance-difference-between-iterator-zip-and-skip-order/15743
 #[bench]
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index d8d51f5..0a16c92 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -97,7 +97,7 @@
 //! ## Implementation details of logically-immutable methods
 //!
 //! Occasionally it may be desirable not to expose in an API that there is mutation happening
-//! "under the hood". This may be because logically the operation is immutable, but e.g. caching
+//! "under the hood". This may be because logically the operation is immutable, but e.g., caching
 //! forces the implementation to perform mutation; or because you must employ mutation to implement
 //! a trait method that was originally defined to take `&self`.
 //!
@@ -1227,7 +1227,7 @@
 }
 
 impl<'b, T: ?Sized> RefMut<'b, T> {
-    /// Make a new `RefMut` for a component of the borrowed data, e.g. an enum
+    /// Make a new `RefMut` for a component of the borrowed data, e.g., an enum
     /// variant.
     ///
     /// The `RefCell` is already mutably borrowed, so this cannot fail.
diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs
index 7e13137..e07a0f5 100644
--- a/src/libcore/char/mod.rs
+++ b/src/libcore/char/mod.rs
@@ -131,7 +131,7 @@
     state: EscapeUnicodeState,
 
     // The index of the next hex digit to be printed (0 if none),
-    // i.e. the number of remaining hex digits to be printed;
+    // i.e., the number of remaining hex digits to be printed;
     // increasing from the least significant digit: 0x543210
     hex_digit_idx: usize,
 }
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index 46bb580..225ea3d 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -13,7 +13,7 @@
 //! In Rust, some simple types are "implicitly copyable" and when you
 //! assign them or pass them as arguments, the receiver will get a copy,
 //! leaving the original value in place. These types do not require
-//! allocation to copy and do not have finalizers (i.e. they do not
+//! allocation to copy and do not have finalizers (i.e., they do not
 //! contain owned boxes or implement [`Drop`]), so the compiler considers
 //! them cheap and safe to copy. For other types copies must be made
 //! explicitly, by convention implementing the [`Clone`] trait and calling
@@ -93,10 +93,10 @@
 /// In addition to the [implementors listed below][impls],
 /// the following types also implement `Clone`:
 ///
-/// * Function item types (i.e. the distinct types defined for each function)
-/// * Function pointer types (e.g. `fn() -> i32`)
-/// * Array types, for all sizes, if the item type also implements `Clone` (e.g. `[i32; 123456]`)
-/// * Tuple types, if each component also implements `Clone` (e.g. `()`, `(i32, bool)`)
+/// * Function item types (i.e., the distinct types defined for each function)
+/// * Function pointer types (e.g., `fn() -> i32`)
+/// * Array types, for all sizes, if the item type also implements `Clone` (e.g., `[i32; 123456]`)
+/// * Tuple types, if each component also implements `Clone` (e.g., `()`, `(i32, bool)`)
 /// * Closure types, if they capture no value from the environment
 ///   or if all such captured values implement `Clone` themselves.
 ///   Note that variables captured by shared reference always implement `Clone`
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index dbc28ef..2d48137 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -327,7 +327,8 @@
 /// An example usage for error handling:
 ///
 /// ```
-/// use std::io::{self, Read};
+/// use std::fs;
+/// use std::io;
 /// use std::num;
 ///
 /// enum CliError {
@@ -348,9 +349,7 @@
 /// }
 ///
 /// fn open_and_parse_file(file_name: &str) -> Result<i32, CliError> {
-///     let mut file = std::fs::File::open("test")?;
-///     let mut contents = String::new();
-///     file.read_to_string(&mut contents)?;
+///     let mut contents = fs::read_to_string(&file_name)?;
 ///     let num: i32 = contents.trim().parse()?;
 ///     Ok(num)
 /// }
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index edeb3b0..899fae9 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -1,7 +1,6 @@
 #![stable(feature = "", since = "1.30.0")]
 
 #![allow(non_camel_case_types)]
-#![cfg_attr(stage0, allow(dead_code))]
 
 //! Utilities related to FFI bindings.
 
@@ -18,7 +17,7 @@
 ///
 /// [`!`]: ../../std/primitive.never.html
 /// [pointer]: ../../std/primitive.pointer.html
-// NB: For LLVM to recognize the void pointer type and by extension
+// N.B., for LLVM to recognize the void pointer type and by extension
 //     functions like malloc(), we need to have it represented as i8* in
 //     LLVM bitcode. The enum used here ensures this and prevents misuse
 //     of the "raw" type by only having private variants.. We need two
@@ -45,6 +44,7 @@
 /// Basic implementation of a `va_list`.
 #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
               not(target_arch = "x86_64")),
+          all(target_arch = "aarch4", target_os = "ios"),
           windows))]
 #[unstable(feature = "c_variadic",
            reason = "the `c_variadic` feature has not been properly tested on \
@@ -122,7 +122,6 @@
                      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
@@ -172,7 +171,6 @@
            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",
@@ -192,6 +190,7 @@
             where F: for<'copy> FnOnce(VaList<'copy>) -> R {
         #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
                       not(target_arch = "x86_64")),
+                  all(target_arch = "aarch4", target_os = "ios"),
                   windows))]
         let mut ap = va_copy(self);
         #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
@@ -206,7 +205,6 @@
     }
 }
 
-#[cfg(not(stage0))]
 extern "rust-intrinsic" {
     /// Destroy the arglist `ap` after initialization with `va_start` or
     /// `va_copy`.
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/future/future.rs b/src/libcore/future/future.rs
index 0c870f9..5dee1d6 100644
--- a/src/libcore/future/future.rs
+++ b/src/libcore/future/future.rs
@@ -33,6 +33,7 @@
 ///
 /// When using a future, you generally won't call `poll` directly, but instead
 /// `await!` the value.
+#[must_use]
 pub trait Future {
     /// The result of the `Future`.
     type Output;
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index bbebadd..3e59ee1 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -408,7 +408,7 @@
 
 /// A trait for creating instances of [`Hasher`].
 ///
-/// A `BuildHasher` is typically used (e.g. by [`HashMap`]) to create
+/// A `BuildHasher` is typically used (e.g., by [`HashMap`]) to create
 /// [`Hasher`]s for each key such that they are hashed independently of one
 /// another, since [`Hasher`]s contain state.
 ///
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index f4e96e6..0bfdd93 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -24,7 +24,7 @@
 /// therefore will eliminate all branches that reach to a call to
 /// `unreachable_unchecked()`.
 ///
-/// Like all instances of UB, if this assumption turns out to be wrong, i.e. the
+/// Like all instances of UB, if this assumption turns out to be wrong, i.e., the
 /// `unreachable_unchecked()` call is actually reachable among all possible
 /// control flow, the compiler will apply the wrong optimization strategy, and
 /// may sometimes even corrupt seemingly unrelated code, causing
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 16f0299..b94d5b4 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -52,7 +52,7 @@
 pub use ptr::drop_in_place;
 
 extern "rust-intrinsic" {
-    // NB: These intrinsics take raw pointers because they mutate aliased
+    // N.B., these intrinsics take raw pointers because they mutate aliased
     // memory, which is not valid for either `&` or `&mut`.
 
     /// Stores a value if the current value is the same as the `old` value.
@@ -635,7 +635,7 @@
     /// Tells LLVM that this point in the code is not reachable, enabling
     /// further optimizations.
     ///
-    /// NB: This is very different from the `unreachable!()` macro: Unlike the
+    /// N.B., this is very different from the `unreachable!()` macro: Unlike the
     /// macro, which panics when it is executed, it is *undefined behavior* to
     /// reach code marked with this function.
     ///
@@ -718,7 +718,6 @@
     pub fn uninit<T>() -> T;
 
     /// Moves a value out of scope without running drop glue.
-    #[cfg(not(stage0))]
     pub fn forget<T: ?Sized>(_: T);
 
     /// Reinterprets the bits of a value of one type as another type.
@@ -1476,14 +1475,12 @@
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `rotate_left` method. For example,
     /// [`std::u32::rotate_left`](../../std/primitive.u32.html#method.rotate_left)
-    #[cfg(not(stage0))]
     pub fn rotate_left<T>(x: T, y: T) -> T;
 
     /// Performs rotate right.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `rotate_right` method. For example,
     /// [`std::u32::rotate_right`](../../std/primitive.u32.html#method.rotate_right)
-    #[cfg(not(stage0))]
     pub fn rotate_right<T>(x: T, y: T) -> T;
 
     /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 3063cb1..c0b83a6 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -98,6 +98,7 @@
     message="`{Self}` is not an iterator"
 )]
 #[doc(spotlight)]
+#[must_use]
 pub trait Iterator {
     /// The type of the elements being iterated over.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -154,7 +155,7 @@
     ///
     /// `size_hint()` is primarily intended to be used for optimizations such as
     /// reserving space for the elements of the iterator, but must not be
-    /// trusted to e.g. omit bounds checks in unsafe code. An incorrect
+    /// trusted to e.g., omit bounds checks in unsafe code. An incorrect
     /// implementation of `size_hint()` should not lead to memory safety
     /// violations.
     ///
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index de7ab88..7b273f7 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -649,6 +649,19 @@
             _ => (usize::MAX, None)
         }
     }
+
+    #[inline]
+    fn try_fold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
+        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let mut accum = init;
+        while let Some(x) = self.iter.next() {
+            accum = f(accum, x)?;
+            accum = self.iter.try_fold(accum, &mut f)?;
+            self.iter = self.orig.clone();
+        }
+        Try::from_ok(accum)
+    }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
@@ -1855,18 +1868,11 @@
 
     #[inline]
     fn nth(&mut self, n: usize) -> Option<I::Item> {
-        // FIXME(#43234): merge these when borrow-checking gets better.
-        if n == 0 {
-            match self.peeked.take() {
-                Some(v) => v,
-                None => self.iter.nth(n),
-            }
-        } else {
-            match self.peeked.take() {
-                Some(None) => None,
-                Some(Some(_)) => self.iter.nth(n - 1),
-                None => self.iter.nth(n),
-            }
+        match self.peeked.take() {
+            Some(None) => None,
+            Some(v @ Some(_)) if n == 0 => v,
+            Some(Some(_)) => self.iter.nth(n - 1),
+            None => self.iter.nth(n),
         }
     }
 
@@ -1965,14 +1971,8 @@
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn peek(&mut self) -> Option<&I::Item> {
-        if self.peeked.is_none() {
-            self.peeked = Some(self.iter.next());
-        }
-        match self.peeked {
-            Some(Some(ref value)) => Some(value),
-            Some(None) => None,
-            _ => unreachable!(),
-        }
+        let iter = &mut self.iter;
+        self.peeked.get_or_insert_with(|| iter.next()).as_ref()
     }
 }
 
@@ -2109,8 +2109,12 @@
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let (_, upper) = self.iter.size_hint();
-        (0, upper) // can't know a lower bound, due to the predicate
+        if self.flag {
+            (0, Some(0))
+        } else {
+            let (_, upper) = self.iter.size_hint();
+            (0, upper) // can't know a lower bound, due to the predicate
+        }
     }
 
     #[inline]
@@ -2321,6 +2325,10 @@
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
+        if self.n == 0 {
+            return (0, Some(0));
+        }
+
         let (lower, upper) = self.iter.size_hint();
 
         let lower = cmp::min(lower, self.n);
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index d2c5a3b..45e5b61 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -770,7 +770,7 @@
     fn product<I: Iterator<Item=A>>(iter: I) -> Self;
 }
 
-// NB: explicitly use Add and Mul here to inherit overflow checks
+// N.B., explicitly use Add and Mul here to inherit overflow checks
 macro_rules! integer_sum_product {
     (@impls $zero:expr, $one:expr, #[$attr:meta], $($a:ty)*) => ($(
         #[$attr]
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 726e891..a51674f 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -92,6 +92,7 @@
 #![feature(link_llvm_intrinsics)]
 #![feature(never_type)]
 #![feature(nll)]
+#![feature(bind_by_move_pattern_guards)]
 #![feature(exhaustive_patterns)]
 #![feature(no_core)]
 #![feature(on_unimplemented)]
@@ -250,9 +251,7 @@
 #[path = "../stdsimd/coresimd/mod.rs"]
 #[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)]
 #[unstable(feature = "stdsimd", issue = "48556")]
-#[cfg(not(stage0))] // allow changes to how stdsimd works in stage0
 mod coresimd;
 
 #[stable(feature = "simd_arch", since = "1.27.0")]
-#[cfg(not(stage0))]
 pub use coresimd::arch;
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 23f0777..d3d1612 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -274,10 +274,10 @@
 /// In addition to the [implementors listed below][impls],
 /// the following types also implement `Copy`:
 ///
-/// * Function item types (i.e. the distinct types defined for each function)
-/// * Function pointer types (e.g. `fn() -> i32`)
-/// * Array types, for all sizes, if the item type also implements `Copy` (e.g. `[i32; 123456]`)
-/// * Tuple types, if each component also implements `Copy` (e.g. `()`, `(i32, bool)`)
+/// * Function item types (i.e., the distinct types defined for each function)
+/// * Function pointer types (e.g., `fn() -> i32`)
+/// * Array types, for all sizes, if the item type also implements `Copy` (e.g., `[i32; 123456]`)
+/// * Tuple types, if each component also implements `Copy` (e.g., `()`, `(i32, bool)`)
 /// * Closure types, if they capture no value from the environment
 ///   or if all such captured values implement `Copy` themselves.
 ///   Note that variables captured by shared reference always implement `Copy`
@@ -640,15 +640,15 @@
 #[unstable(feature = "pin", issue = "49150")]
 pub auto trait Unpin {}
 
-/// A type which does not implement `Unpin`.
+/// A marker type which does not implement `Unpin`.
 ///
-/// If a type contains a `Pinned`, it will not implement `Unpin` by default.
+/// If a type contains a `PhantomPinned`, it will not implement `Unpin` by default.
 #[unstable(feature = "pin", issue = "49150")]
 #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
-pub struct Pinned;
+pub struct PhantomPinned;
 
 #[unstable(feature = "pin", issue = "49150")]
-impl !Unpin for Pinned {}
+impl !Unpin for PhantomPinned {}
 
 #[unstable(feature = "pin", issue = "49150")]
 impl<'a, T: ?Sized + 'a> Unpin for &'a T {}
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index e4b2800..afd9fcb 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -149,7 +149,6 @@
 ///
 /// [`forget`]: fn.forget.html
 #[inline]
-#[cfg(not(stage0))]
 #[unstable(feature = "forget_unsized", issue = "0")]
 pub fn forget_unsized<T: ?Sized>(t: T) {
     unsafe { intrinsics::forget(t) }
@@ -305,7 +304,7 @@
 /// Returns the size of the pointed-to value in bytes.
 ///
 /// This is usually the same as `size_of::<T>()`. However, when `T` *has* no
-/// statically known size, e.g. a slice [`[T]`][slice] or a [trait object],
+/// statically known size, e.g., a slice [`[T]`][slice] or a [trait object],
 /// then `size_of_val` can be used to get the dynamically-known size.
 ///
 /// [slice]: ../../std/primitive.slice.html
@@ -1119,7 +1118,7 @@
     /// 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
+    // 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)]
diff --git a/src/libcore/num/bignum.rs b/src/libcore/num/bignum.rs
index 732a02e..2bfb49c 100644
--- a/src/libcore/num/bignum.rs
+++ b/src/libcore/num/bignum.rs
@@ -183,7 +183,7 @@
                 let nonzero = &digits[..end];
 
                 if nonzero.is_empty() {
-                    // There are no non-zero digits, i.e. the number is zero.
+                    // There are no non-zero digits, i.e., the number is zero.
                     return 0;
                 }
                 // This could be optimized with leading_zeros() and bit shifts, but that's
diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs
index ccf3950..c3a983d 100644
--- a/src/libcore/num/dec2flt/algorithm.rs
+++ b/src/libcore/num/dec2flt/algorithm.rs
@@ -61,9 +61,9 @@
     ///
     /// The only field which is relevant for the following code is PC, Precision Control. This
     /// field determines the precision of the operations performed by the  FPU. It can be set to:
-    ///  - 0b00, single precision i.e. 32-bits
-    ///  - 0b10, double precision i.e. 64-bits
-    ///  - 0b11, double extended precision i.e. 80-bits (default state)
+    ///  - 0b00, single precision i.e., 32-bits
+    ///  - 0b10, double precision i.e., 64-bits
+    ///  - 0b11, double extended precision i.e., 80-bits (default state)
     /// The 0b01 value is reserved and should not be used.
     pub struct FPUControlWord(u16);
 
diff --git a/src/libcore/num/dec2flt/rawfp.rs b/src/libcore/num/dec2flt/rawfp.rs
index 38f4e46..18c30e2 100644
--- a/src/libcore/num/dec2flt/rawfp.rs
+++ b/src/libcore/num/dec2flt/rawfp.rs
@@ -349,7 +349,7 @@
 }
 
 // Find the smallest floating point number strictly larger than the argument.
-// This operation is saturating, i.e. next_float(inf) == inf.
+// This operation is saturating, i.e., next_float(inf) == inf.
 // Unlike most code in this module, this function does handle zero, subnormals, and infinities.
 // However, like all other code here, it does not deal with NaN and negative numbers.
 pub fn next_float<T: RawFloat>(x: T) -> T {
diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs
index d58015b..097240e 100644
--- a/src/libcore/num/flt2dec/mod.rs
+++ b/src/libcore/num/flt2dec/mod.rs
@@ -23,7 +23,7 @@
 - `d[0]` is non-zero.
 
 - It's correctly rounded when parsed back: `v - minus < V < v + plus`.
-  Furthermore it is shortest such one, i.e. there is no representation
+  Furthermore it is shortest such one, i.e., there is no representation
   with less than `n` digits that is correctly rounded.
 
 - It's closest to the original value: `abs(V - v) <= 10^(k-n) / 2`. Note that
@@ -398,7 +398,7 @@
 /// given number of fractional digits. The result is stored to the supplied parts
 /// array while utilizing given byte buffer as a scratch. `upper` is currently
 /// unused but left for the future decision to change the case of non-finite values,
-/// i.e. `inf` and `nan`. The first part to be rendered is always a `Part::Sign`
+/// i.e., `inf` and `nan`. The first part to be rendered is always a `Part::Sign`
 /// (which can be an empty string if no sign is rendered).
 ///
 /// `format_shortest` should be the underlying digit-generation function.
@@ -591,7 +591,7 @@
 /// given number of fractional digits. The result is stored to the supplied parts
 /// array while utilizing given byte buffer as a scratch. `upper` is currently
 /// unused but left for the future decision to change the case of non-finite values,
-/// i.e. `inf` and `nan`. The first part to be rendered is always a `Part::Sign`
+/// i.e., `inf` and `nan`. The first part to be rendered is always a `Part::Sign`
 /// (which can be an empty string if no sign is rendered).
 ///
 /// `format_exact` should be the underlying digit-generation function.
diff --git a/src/libcore/num/flt2dec/strategy/dragon.rs b/src/libcore/num/flt2dec/strategy/dragon.rs
index aa6a08c..cda0773 100644
--- a/src/libcore/num/flt2dec/strategy/dragon.rs
+++ b/src/libcore/num/flt2dec/strategy/dragon.rs
@@ -81,11 +81,11 @@
     // - followed by `(mant + 2 * plus) * 2^exp` in the original type.
     //
     // obviously, `minus` and `plus` cannot be zero. (for infinities, we use out-of-range values.)
-    // also we assume that at least one digit is generated, i.e. `mant` cannot be zero too.
+    // also we assume that at least one digit is generated, i.e., `mant` cannot be zero too.
     //
     // this also means that any number between `low = (mant - minus) * 2^exp` and
     // `high = (mant + plus) * 2^exp` will map to this exact floating point number,
-    // with bounds included when the original mantissa was even (i.e. `!mant_was_odd`).
+    // with bounds included when the original mantissa was even (i.e., `!mant_was_odd`).
 
     assert!(d.mant > 0);
     assert!(d.minus > 0);
@@ -172,7 +172,7 @@
         // - `high - v = plus / scale * 10^(k-n)`
         //
         // assume that `d[0..n-1]` is the shortest representation between `low` and `high`,
-        // i.e. `d[0..n-1]` satisfies both of the following but `d[0..n-2]` doesn't:
+        // i.e., `d[0..n-1]` satisfies both of the following but `d[0..n-2]` doesn't:
         // - `low < d[0..n-1] * 10^(k-n) < high` (bijectivity: digits round to `v`); and
         // - `abs(v / 10^(k-n) - d[0..n-1]) <= 1/2` (the last digit is correct).
         //
@@ -304,7 +304,7 @@
 
     // rounding up if we stop in the middle of digits
     // if the following digits are exactly 5000..., check the prior digit and try to
-    // round to even (i.e. avoid rounding up when the prior digit is even).
+    // round to even (i.e., avoid rounding up when the prior digit is even).
     let order = mant.cmp(scale.mul_small(5));
     if order == Ordering::Greater || (order == Ordering::Equal &&
                                       (len == 0 || buf[len-1] & 1 == 1)) {
diff --git a/src/libcore/num/flt2dec/strategy/grisu.rs b/src/libcore/num/flt2dec/strategy/grisu.rs
index effe073..3e76fec 100644
--- a/src/libcore/num/flt2dec/strategy/grisu.rs
+++ b/src/libcore/num/flt2dec/strategy/grisu.rs
@@ -242,7 +242,7 @@
     //
     // find the digit length `kappa` between `(minus1, plus1)` as per Theorem 6.2.
     // Theorem 6.2 can be adopted to exclude `x` by requiring `y mod 10^k < y - x` instead.
-    // (e.g. `x` = 32000, `y` = 32777; `kappa` = 2 since `y mod 10^3 = 777 < y - x = 777`.)
+    // (e.g., `x` = 32000, `y` = 32777; `kappa` = 2 since `y mod 10^3 = 777 < y - x = 777`.)
     // the algorithm relies on the later verification phase to exclude `y`.
     let delta1 = plus1 - minus1;
 //  let delta1int = (delta1 >> e) as usize; // only for explanation
@@ -362,19 +362,19 @@
             // proceed, but we then have at least one valid representation known to be closest to
             // `v + 1 ulp` anyway. we will denote them as TC1 through TC3 for brevity.
             //
-            // TC1: `w(n) <= v + 1 ulp`, i.e. this is the last repr that can be the closest one.
+            // TC1: `w(n) <= v + 1 ulp`, i.e., this is the last repr that can be the closest one.
             // this is equivalent to `plus1 - w(n) = plus1w(n) >= plus1 - (v + 1 ulp) = plus1v_up`.
             // combined with TC2 (which checks if `w(n+1)` is valid), this prevents the possible
             // overflow on the calculation of `plus1w(n)`.
             //
-            // TC2: `w(n+1) < minus1`, i.e. the next repr definitely does not round to `v`.
+            // TC2: `w(n+1) < minus1`, i.e., the next repr definitely does not round to `v`.
             // this is equivalent to `plus1 - w(n) + 10^kappa = plus1w(n) + 10^kappa >
             // plus1 - minus1 = threshold`. the left hand side can overflow, but we know
             // `threshold > plus1v`, so if TC1 is false, `threshold - plus1w(n) >
             // threshold - (plus1v - 1 ulp) > 1 ulp` and we can safely test if
             // `threshold - plus1w(n) < 10^kappa` instead.
             //
-            // TC3: `abs(w(n) - (v + 1 ulp)) <= abs(w(n+1) - (v + 1 ulp))`, i.e. the next repr is
+            // TC3: `abs(w(n) - (v + 1 ulp)) <= abs(w(n+1) - (v + 1 ulp))`, i.e., the next repr is
             // no closer to `v + 1 ulp` than the current repr. given `z(n) = plus1v_up - plus1w(n)`,
             // this becomes `abs(z(n)) <= abs(z(n+1))`. again assuming that TC1 is false, we have
             // `z(n) > 0`. we have two cases to consider:
@@ -384,7 +384,7 @@
             // - when `z(n+1) < 0`:
             //   - TC3a: the precondition is `plus1v_up < plus1w(n) + 10^kappa`. assuming TC2 is
             //     false, `threshold >= plus1w(n) + 10^kappa` so it cannot overflow.
-            //   - TC3b: TC3 becomes `z(n) <= -z(n+1)`, i.e. `plus1v_up - plus1w(n) >=
+            //   - TC3b: TC3 becomes `z(n) <= -z(n+1)`, i.e., `plus1v_up - plus1w(n) >=
             //     plus1w(n+1) - plus1v_up = plus1w(n) + 10^kappa - plus1v_up`. the negated TC1
             //     gives `plus1v_up > plus1w(n)`, so it cannot overflow or underflow when
             //     combined with TC3a.
@@ -414,7 +414,7 @@
 
         // now we have the closest representation to `v` between `plus1` and `minus1`.
         // this is too liberal, though, so we reject any `w(n)` not between `plus0` and `minus0`,
-        // i.e. `plus1 - plus1w(n) <= minus0` or `plus1 - plus1w(n) >= plus0`. we utilize the facts
+        // i.e., `plus1 - plus1w(n) <= minus0` or `plus1 - plus1w(n) >= plus0`. we utilize the facts
         // that `threshold = plus1 - minus1` and `plus1 - plus0 = minus0 - minus1 = 2 ulp`.
         if 2 * ulp <= plus1w && plus1w <= threshold - 4 * ulp {
             Some((buf.len(), exp))
@@ -675,7 +675,7 @@
             return Some((len, exp));
         }
 
-        // otherwise we are doomed (i.e. some values between `v - 1 ulp` and `v + 1 ulp` are
+        // otherwise we are doomed (i.e., some values between `v - 1 ulp` and `v + 1 ulp` are
         // rounding down and others are rounding up) and give up.
         None
     }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 7f5d596..4acf3a1 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1544,7 +1544,7 @@
             concat!("Negates self, overflowing if this is equal to the minimum value.
 
 Returns a tuple of the negated version of self along with a boolean indicating whether an overflow
-happened. If `self` is the minimum value (e.g. `i32::MIN` for values of type `i32`), then the
+happened. If `self` is the minimum value (e.g., `i32::MIN` for values of type `i32`), then the
 minimum value will be returned again and `true` will be returned for an overflow happening.
 
 # Examples
@@ -1621,7 +1621,7 @@
             concat!("Computes the absolute value of `self`.
 
 Returns a tuple of the absolute version of self along with a boolean indicating whether an overflow
-happened. If self is the minimum value (e.g. ", stringify!($SelfT), "::MIN for values of type
+happened. If self is the minimum value (e.g., ", stringify!($SelfT), "::MIN for values of type
  ", stringify!($SelfT), "), then the minimum value will be returned again and true will be returned
 for an overflow happening.
 
@@ -2330,12 +2330,7 @@
             #[rustc_const_unstable(feature = "const_int_rotate")]
             #[inline]
             pub const fn rotate_left(self, n: u32) -> Self {
-                #[cfg(not(stage0))] {
-                    unsafe { intrinsics::rotate_left(self, n as $SelfT) }
-                }
-                #[cfg(stage0)] {
-                    (self << (n % $BITS)) | (self >> (($BITS - (n % $BITS)) % $BITS))
-                }
+                unsafe { intrinsics::rotate_left(self, n as $SelfT) }
             }
         }
 
@@ -2360,12 +2355,7 @@
             #[rustc_const_unstable(feature = "const_int_rotate")]
             #[inline]
             pub const fn rotate_right(self, n: u32) -> Self {
-                #[cfg(not(stage0))] {
-                    unsafe { intrinsics::rotate_right(self, n as $SelfT) }
-                }
-                #[cfg(stage0)] {
-                    (self >> (n % $BITS)) | (self << (($BITS - (n % $BITS)) % $BITS))
-                }
+                unsafe { intrinsics::rotate_right(self, n as $SelfT) }
             }
         }
 
@@ -3617,7 +3607,7 @@
         doc_comment! {
             concat!("Returns the smallest power of two greater than or equal to `self`.
 
-When return value overflows (i.e. `self > (1 << (N-1))` for type
+When return value overflows (i.e., `self > (1 << (N-1))` for type
 `uN`), it panics in debug mode and return value is wrapped to 0 in
 release mode (the only situation in which method can return 0).
 
@@ -4827,7 +4817,7 @@
 /// # Potential causes
 ///
 /// Among other causes, `ParseIntError` can be thrown because of leading or trailing whitespace
-/// in the string e.g. when it is obtained from the standard input.
+/// in the string e.g., when it is obtained from the standard input.
 /// Using the [`str.trim()`] method ensures that no whitespace remains before parsing.
 ///
 /// [`str.trim()`]: ../../std/primitive.str.html#method.trim
diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs
index 00134a5..94dd657 100644
--- a/src/libcore/num/wrapping.rs
+++ b/src/libcore/num/wrapping.rs
@@ -865,7 +865,7 @@
             doc_comment! {
                 concat!("Returns the smallest power of two greater than or equal to `self`.
 
-When return value overflows (i.e. `self > (1 << (N-1))` for type
+When return value overflows (i.e., `self > (1 << (N-1))` for type
 `uN`), overflows to `2^N = 0`.
 
 # Examples
diff --git a/src/libcore/ops/function.rs b/src/libcore/ops/function.rs
index c9591c3f..3b356b9 100644
--- a/src/libcore/ops/function.rs
+++ b/src/libcore/ops/function.rs
@@ -26,7 +26,7 @@
 /// is expected.
 ///
 /// Use `Fn` as a bound when you want to accept a parameter of function-like
-/// type and need to call it repeatedly and without mutating state (e.g. when
+/// type and need to call it repeatedly and without mutating state (e.g., when
 /// calling it concurrently). If you do not need such strict requirements, use
 /// [`FnMut`] or [`FnOnce`] as bounds.
 ///
@@ -72,6 +72,7 @@
     label="expected an `Fn<{Args}>` closure, found `{Self}`",
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use]
 pub trait Fn<Args> : FnMut<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -84,7 +85,7 @@
 ///
 /// `FnMut` is implemented automatically by closures which take mutable
 /// references to captured variables, as well as all types that implement
-/// [`Fn`], e.g. (safe) [function pointers][] (since `FnMut` is a supertrait of
+/// [`Fn`], e.g., (safe) [function pointers][] (since `FnMut` is a supertrait of
 /// [`Fn`]). Additionally, for any type `F` that implements `FnMut`, `&mut F`
 /// implements `FnMut`, too.
 ///
@@ -150,6 +151,7 @@
     label="expected an `FnMut<{Args}>` closure, found `{Self}`",
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use]
 pub trait FnMut<Args> : FnOnce<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -163,7 +165,7 @@
 /// implements `FnOnce`, it can only be called once.
 ///
 /// `FnOnce` is implemented automatically by closure that might consume captured
-/// variables, as well as all types that implement [`FnMut`], e.g. (safe)
+/// variables, as well as all types that implement [`FnMut`], e.g., (safe)
 /// [function pointers][] (since `FnOnce` is a supertrait of [`FnMut`]).
 ///
 /// Since both [`Fn`] and [`FnMut`] are subtraits of `FnOnce`, any instance of
@@ -228,6 +230,7 @@
     label="expected an `FnOnce<{Args}>` closure, found `{Self}`",
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use]
 pub trait FnOnce<Args> {
     /// The returned type after the call operator is used.
     #[stable(feature = "fn_once_output", since = "1.12.0")]
diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs
index edfa6df..785f073 100644
--- a/src/libcore/ops/mod.rs
+++ b/src/libcore/ops/mod.rs
@@ -27,7 +27,7 @@
 //! should have some resemblance to multiplication (and share expected
 //! properties like associativity).
 //!
-//! Note that the `&&` and `||` operators short-circuit, i.e. they only
+//! Note that the `&&` and `||` operators short-circuit, i.e., they only
 //! evaluate their second operand if it contributes to the result. Since this
 //! behavior is not enforceable by traits, `&&` and `||` are not supported as
 //! overloadable operators.
diff --git a/src/libcore/ops/unsize.rs b/src/libcore/ops/unsize.rs
index 4d9a40a..e86a392 100644
--- a/src/libcore/ops/unsize.rs
+++ b/src/libcore/ops/unsize.rs
@@ -93,7 +93,7 @@
 /// {}
 /// ```
 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
-#[cfg_attr(not(stage0), lang = "dispatch_from_dyn")]
+#[lang = "dispatch_from_dyn"]
 pub trait DispatchFromDyn<T> {
     // Empty.
 }
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index cf1c770..44d632e 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -62,7 +62,7 @@
 //! The following example uses [`Option`] to create an optional box of
 //! [`i32`]. Notice that in order to use the inner [`i32`] value first, the
 //! `check_optional` function needs to use pattern matching to
-//! determine whether the box has a value (i.e. it is [`Some(...)`][`Some`]) or
+//! determine whether the box has a value (i.e., it is [`Some(...)`][`Some`]) or
 //! not ([`None`]).
 //!
 //! ```
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index 308dd9c..0ad6e8c 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -7,23 +7,33 @@
 //! since moving an object with pointers to itself will invalidate them,
 //! which could cause undefined behavior.
 //!
-//! In order to prevent objects from moving, they must be pinned
-//! by wrapping a pointer to the data in the [`Pin`] type. A pointer wrapped
-//! in a `Pin` is otherwise equivalent to its normal version, e.g. `Pin<Box<T>>`
-//! and `Box<T>` work the same way except that the first is pinning the value
-//! of `T` in place.
+//! By default, all types in Rust are movable. Rust allows passing all types by-value,
+//! and common smart-pointer types such as `Box`, `Rc`, and `&mut` allow replacing and
+//! moving the values they contain. In order to prevent objects from moving, they must
+//! be pinned by wrapping a pointer to the data in the [`Pin`] type.
+//! Doing this prohibits moving the value behind the pointer.
+//! For example, `Pin<Box<T>>` functions much like a regular `Box<T>`,
+//! but doesn't allow moving `T`. The pointer value itself (the `Box`) can still be moved,
+//! but the value behind it cannot.
 //!
-//! First of all, these are pointer types because pinned data mustn't be passed around by value
-//! (that would change its location in memory).
-//! Secondly, since data can be moved out of `&mut` and `Box` with functions such as [`swap`],
-//! which causes their contents to swap places in memory,
-//! we need dedicated types that prohibit such operations.
+//! Since data can be moved out of `&mut` and `Box` with functions such as [`swap`],
+//! changing the location of the underlying data, [`Pin`] prohibits accessing the
+//! underlying pointer type (the `&mut` or `Box`) directly, and provides its own set of
+//! APIs for accessing and using the value. [`Pin`] also guarantees that no other
+//! functions will move the pointed-to value. This allows for the creation of
+//! self-references and other special behaviors that are only possible for unmovable
+//! values.
 //!
-//! However, these restrictions are usually not necessary,
-//! so most types implement the [`Unpin`] auto-trait,
-//! which indicates that the type can be moved out safely.
-//! Doing so removes the limitations of pinning types,
-//! making them the same as their non-pinning counterparts.
+//! However, these restrictions are usually not necessary. Many types are always freely
+//! movable. These types implement the [`Unpin`] auto-trait, which nullifies the affect
+//! of [`Pin`]. For `T: Unpin`, `Pin<Box<T>>` and `Box<T>` function identically, as do
+//! `Pin<&mut T>` and `&mut T`.
+//!
+//! Note that pinning and `Unpin` only affect the pointed-to type. For example, whether
+//! or not `Box<T>` is `Unpin` has no affect on the behavior of `Pin<Box<T>>`. Similarly,
+//! `Pin<Box<T>>` and `Pin<&mut T>` are always `Unpin` themselves, even though the
+//! `T` underneath them isn't, because the pointers in `Pin<Box<_>>` and `Pin<&mut _>`
+//! are always freely movable, even if the data they point to isn't.
 //!
 //! [`Pin`]: struct.Pin.html
 //! [`Unpin`]: trait.Unpin.html
@@ -36,7 +46,7 @@
 //! #![feature(pin)]
 //!
 //! use std::pin::Pin;
-//! use std::marker::Pinned;
+//! use std::marker::PhantomPinned;
 //! use std::ptr::NonNull;
 //!
 //! // This is a self-referential struct since the slice field points to the data field.
@@ -47,7 +57,7 @@
 //! struct Unmovable {
 //!     data: String,
 //!     slice: NonNull<String>,
-//!     _pin: Pinned,
+//!     _pin: PhantomPinned,
 //! }
 //!
 //! impl Unmovable {
@@ -60,7 +70,7 @@
 //!             // we only create the pointer once the data is in place
 //!             // otherwise it will have already moved before we even started
 //!             slice: NonNull::dangling(),
-//!             _pin: Pinned,
+//!             _pin: PhantomPinned,
 //!         };
 //!         let mut boxed = Box::pinned(res);
 //!
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 0387708..79ca600 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -103,7 +103,7 @@
 ///   dropped normally.
 ///
 /// * It is friendlier to the optimizer to do this over [`ptr::read`] when
-///   dropping manually allocated memory (e.g. when writing Box/Rc/Vec),
+///   dropping manually allocated memory (e.g., when writing Box/Rc/Vec),
 ///   as the compiler doesn't need to prove that it's sound to elide the
 ///   copy.
 ///
@@ -836,7 +836,7 @@
 ///
 /// The compiler shouldn't change the relative order or number of volatile
 /// memory operations. However, volatile memory operations on zero-sized types
-/// (e.g. if a zero-sized type is passed to `read_volatile`) are no-ops
+/// (e.g., if a zero-sized type is passed to `read_volatile`) are no-ops
 /// and may be ignored.
 ///
 /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
@@ -913,7 +913,7 @@
 ///
 /// The compiler shouldn't change the relative order or number of volatile
 /// memory operations. However, volatile memory operations on zero-sized types
-/// (e.g. if a zero-sized type is passed to `write_volatile`) are no-ops
+/// (e.g., if a zero-sized type is passed to `write_volatile`) are no-ops
 /// and may be ignored.
 ///
 /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
@@ -1035,7 +1035,7 @@
 
     /// Calculates the offset from a pointer.
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -1089,7 +1089,7 @@
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -1253,7 +1253,7 @@
 
     /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -1310,7 +1310,7 @@
     /// Calculates the offset from a pointer (convenience for
     /// `.offset((count as isize).wrapping_neg())`).
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -1367,7 +1367,7 @@
     /// Calculates the offset from a pointer using wrapping arithmetic.
     /// (convenience for `.wrapping_offset(count as isize)`)
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -1408,7 +1408,7 @@
     /// Calculates the offset from a pointer using wrapping arithmetic.
     /// (convenience for `.wrapping_offset((count as isize).wrapping_sub())`)
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -1655,7 +1655,7 @@
 
     /// Calculates the offset from a pointer.
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -1708,7 +1708,7 @@
     }
 
     /// Calculates the offset from a pointer using wrapping arithmetic.
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -1891,7 +1891,7 @@
 
     /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -1948,7 +1948,7 @@
     /// Calculates the offset from a pointer (convenience for
     /// `.offset((count as isize).wrapping_neg())`).
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -2005,7 +2005,7 @@
     /// Calculates the offset from a pointer using wrapping arithmetic.
     /// (convenience for `.wrapping_offset(count as isize)`)
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -2046,7 +2046,7 @@
     /// Calculates the offset from a pointer using wrapping arithmetic.
     /// (convenience for `.wrapping_offset((count as isize).wrapping_sub())`)
     ///
-    /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
+    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
@@ -2375,7 +2375,7 @@
     fn mod_inv(x: usize, m: usize) -> usize {
         /// Multiplicative modular inverse table modulo 2⁴ = 16.
         ///
-        /// Note, that this table does not contain values where inverse does not exist (i.e. for
+        /// Note, that this table does not contain values where inverse does not exist (i.e., for
         /// `0⁻¹ mod 16`, `2⁻¹ mod 16`, etc.)
         const INV_TABLE_MOD_16: [u8; 8] = [1, 11, 13, 7, 9, 3, 5, 15];
         /// Modulo for which the `INV_TABLE_MOD_16` is intended.
@@ -2398,7 +2398,7 @@
                 // y = y * (2 - xy) mod n
                 //
                 // Note, that we use wrapping operations here intentionally – the original formula
-                // uses e.g. subtraction `mod n`. It is entirely fine to do them `mod
+                // uses e.g., subtraction `mod n`. It is entirely fine to do them `mod
                 // usize::max_value()` instead, because we take the result `mod n` at the end
                 // anyway.
                 inverse = inverse.wrapping_mul(
@@ -2516,6 +2516,39 @@
     a == b
 }
 
+/// Hash a raw pointer.
+///
+/// This can be used to hash a `&T` reference (which coerces to `*const T` implicitly)
+/// by its address rather than the value it points to
+/// (which is what the `Hash for &T` implementation does).
+///
+/// # Examples
+///
+/// ```
+/// #![feature(ptr_hash)]
+/// use std::collections::hash_map::DefaultHasher;
+/// use std::hash::{Hash, Hasher};
+/// use std::ptr;
+///
+/// let five = 5;
+/// let five_ref = &five;
+///
+/// let mut hasher = DefaultHasher::new();
+/// ptr::hash(five_ref, &mut hasher);
+/// let actual = hasher.finish();
+///
+/// let mut hasher = DefaultHasher::new();
+/// (five_ref as *const i32).hash(&mut hasher);
+/// let expected = hasher.finish();
+///
+/// assert_eq!(actual, expected);
+/// ```
+#[unstable(feature = "ptr_hash", reason = "newly added", issue = "56286")]
+pub fn hash<T: ?Sized, S: hash::Hasher>(hashee: *const T, into: &mut S) {
+    use hash::Hash;
+    hashee.hash(into);
+}
+
 // Impls for function pointers
 macro_rules! fnptr_impls_safety_abi {
     ($FnTy: ty, $($Arg: ident),*) => {
@@ -2815,14 +2848,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: unsafe { NonZero(reference as _) }, _marker: PhantomData }
+        Unique { pointer: unsafe { NonZero(reference as *mut T) }, _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: unsafe { NonZero(reference as _) }, _marker: PhantomData }
+        Unique { pointer: unsafe { NonZero(reference as *const T) }, _marker: PhantomData }
     }
 }
 
@@ -2857,12 +2890,12 @@
 }
 
 /// `NonNull` pointers are not `Send` because the data they reference may be aliased.
-// NB: This impl is unnecessary, but should provide better error messages.
+// N.B., this impl is unnecessary, but should provide better error messages.
 #[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> !Send for NonNull<T> { }
 
 /// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
-// NB: This impl is unnecessary, but should provide better error messages.
+// N.B., this impl is unnecessary, but should provide better error messages.
 #[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> !Sync for NonNull<T> { }
 
@@ -3025,7 +3058,7 @@
 impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
     #[inline]
     fn from(reference: &'a mut T) -> Self {
-        NonNull { pointer: unsafe { NonZero(reference as _) } }
+        NonNull { pointer: unsafe { NonZero(reference as *mut T) } }
     }
 }
 
@@ -3033,6 +3066,6 @@
 impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
     #[inline]
     fn from(reference: &'a T) -> Self {
-        NonNull { pointer: unsafe { NonZero(reference as _) } }
+        NonNull { pointer: unsafe { NonZero(reference as *const T) } }
     }
 }
diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs
index 3d4bccb..4f1af8b 100644
--- a/src/libcore/raw.rs
+++ b/src/libcore/raw.rs
@@ -24,7 +24,7 @@
 /// `Box<dyn AnotherTrait>`.
 ///
 /// `TraitObject` is guaranteed to match layouts, but it is not the
-/// type of trait objects (e.g. the fields are not directly accessible
+/// type of trait objects (e.g., the fields are not directly accessible
 /// on a `&SomeTrait`) nor does it control that layout (changing the
 /// definition will not change the layout of a `&SomeTrait`). It is
 /// only designed to be used by unsafe code that needs to manipulate
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 8c55a16..59c11b2 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Slice management and manipulation
+//! Slice management and manipulation.
 //!
 //! For more details see [`std::slice`].
 //!
@@ -702,8 +702,7 @@
     /// resulting code better than in the case of [`chunks`].
     ///
     /// See [`chunks`] for a variant of this iterator that also returns the remainder as a smaller
-    /// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice of
-    /// the slice.
+    /// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice.
     ///
     /// # Panics
     ///
@@ -1152,7 +1151,7 @@
     ///
     /// # Examples
     ///
-    /// Print the slice split once by numbers divisible by 3 (i.e. `[10, 40]`,
+    /// Print the slice split once by numbers divisible by 3 (i.e., `[10, 40]`,
     /// `[20, 60, 50]`):
     ///
     /// ```
@@ -1216,7 +1215,7 @@
     /// # Examples
     ///
     /// Print the slice split once, starting from the end, by numbers divisible
-    /// by 3 (i.e. `[50]`, `[10, 40, 30, 20]`):
+    /// by 3 (i.e., `[50]`, `[10, 40, 30, 20]`):
     ///
     /// ```
     /// let v = [10, 40, 30, 20, 60, 50];
@@ -1472,8 +1471,8 @@
 
     /// Sorts the slice, but may not preserve the order of equal elements.
     ///
-    /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
-    /// and `O(n log n)` worst-case.
+    /// This sort is unstable (i.e., may reorder equal elements), in-place
+    /// (i.e., does not allocate), and `O(n log n)` worst-case.
     ///
     /// # Current implementation
     ///
@@ -1483,7 +1482,7 @@
     /// randomization to avoid degenerate cases, but with a fixed seed to always provide
     /// deterministic behavior.
     ///
-    /// It is typically faster than stable sorting, except in a few special cases, e.g. when the
+    /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
     /// slice consists of several concatenated sorted sequences.
     ///
     /// # Examples
@@ -1507,8 +1506,8 @@
     /// Sorts the slice with a comparator function, but may not preserve the order of equal
     /// elements.
     ///
-    /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
-    /// and `O(n log n)` worst-case.
+    /// This sort is unstable (i.e., may reorder equal elements), in-place
+    /// (i.e., does not allocate), and `O(n log n)` worst-case.
     ///
     /// The comparator function must define a total ordering for the elements in the slice. If
     /// the ordering is not total, the order of the elements is unspecified. An order is a
@@ -1534,7 +1533,7 @@
     /// randomization to avoid degenerate cases, but with a fixed seed to always provide
     /// deterministic behavior.
     ///
-    /// It is typically faster than stable sorting, except in a few special cases, e.g. when the
+    /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
     /// slice consists of several concatenated sorted sequences.
     ///
     /// # Examples
@@ -1561,8 +1560,9 @@
     /// Sorts the slice with a key extraction function, but may not preserve the order of equal
     /// elements.
     ///
-    /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
-    /// and `O(m n log(m n))` worst-case, where the key function is `O(m)`.
+    /// This sort is unstable (i.e., may reorder equal elements), in-place
+    /// (i.e., does not allocate), and `O(m n log(m n))` worst-case, where the key function is
+    /// `O(m)`.
     ///
     /// # Current implementation
     ///
@@ -2459,13 +2459,13 @@
 
     #[inline]
     fn index(self, slice: &[T]) -> &T {
-        // NB: use intrinsic indexing
+        // N.B., use intrinsic indexing
         &(*slice)[self]
     }
 
     #[inline]
     fn index_mut(self, slice: &mut [T]) -> &mut T {
-        // NB: use intrinsic indexing
+        // N.B., use intrinsic indexing
         &mut (*slice)[self]
     }
 }
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 6c953d1..4a22d92 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -482,7 +482,7 @@
 #[inline]
 fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 { (ch << 6) | (byte & CONT_MASK) as u32 }
 
-/// Checks whether the byte is a UTF-8 continuation byte (i.e. starts with the
+/// Checks whether the byte is a UTF-8 continuation byte (i.e., starts with the
 /// bits `10`).
 #[inline]
 fn utf8_is_cont_byte(byte: u8) -> bool { (byte & !CONT_MASK) == TAG_CONT_U8 }
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index 1c97453..2059160 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -397,7 +397,7 @@
                     let found_char = index - shift;
                     if let Some(slice) = haystack.get(found_char..(found_char + self.utf8_size)) {
                         if slice == &self.utf8_encoded[0..self.utf8_size] {
-                            // move finger to before the character found (i.e. at its start index)
+                            // move finger to before the character found (i.e., at its start index)
                             self.finger_back = found_char;
                             return Some((self.finger_back, self.finger_back + self.utf8_size));
                         }
@@ -1016,7 +1016,7 @@
     It can be proven that the following is an equivalent definition of a local period
     for a factorization (u, v): any positive integer r such that x[i] == x[i+r] for
     all i such that |u| - r <= i <= |u| - 1 and such that both x[i] and x[i+r] are
-    defined. (i.e. i > 0 and i + r < |x|).
+    defined. (i.e., i > 0 and i + r < |x|).
 
     Using the above reformulation, it is easy to prove that
 
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 27eeb04..060983a 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -1940,7 +1940,7 @@
     8,
     u64 AtomicU64 ATOMIC_U64_INIT
 }
-#[cfg(all(not(stage0), target_has_atomic = "128"))]
+#[cfg(target_has_atomic = "128")]
 atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
@@ -1954,7 +1954,7 @@
     16,
     i128 AtomicI128 ATOMIC_I128_INIT
 }
-#[cfg(all(not(stage0), target_has_atomic = "128"))]
+#[cfg(target_has_atomic = "128")]
 atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs
index c0ce725..8ea7abc 100644
--- a/src/libcore/task/wake.rs
+++ b/src/libcore/task/wake.rs
@@ -227,7 +227,7 @@
     /// # Unsafety
     ///
     /// This function is unsafe to call because it's asserting the `UnsafeWake`
-    /// value is in a consistent state, i.e. hasn't been dropped.
+    /// value is in a consistent state, i.e., hasn't been dropped.
     unsafe fn clone_raw(&self) -> Waker;
 
     /// Drops this instance of `UnsafeWake`, deallocating resources
@@ -249,7 +249,7 @@
     /// # Unsafety
     ///
     /// This function is unsafe to call because it's asserting the `UnsafeWake`
-    /// value is in a consistent state, i.e. hasn't been dropped.
+    /// value is in a consistent state, i.e., hasn't been dropped.
     unsafe fn drop_raw(&self);
 
     /// Indicates that the associated task is ready to make progress and should
@@ -266,7 +266,7 @@
     /// # Unsafety
     ///
     /// This function is unsafe to call because it's asserting the `UnsafeWake`
-    /// value is in a consistent state, i.e. hasn't been dropped.
+    /// value is in a consistent state, i.e., hasn't been dropped.
     unsafe fn wake(&self);
 
     /// Indicates that the associated task is ready to make progress and should
@@ -286,7 +286,7 @@
     /// # Unsafety
     ///
     /// This function is unsafe to call because it's asserting the `UnsafeWake`
-    /// value is in a consistent state, i.e. hasn't been dropped, and that the
+    /// value is in a consistent state, i.e., hasn't been dropped, and that the
     /// `UnsafeWake` hasn't moved from the thread on which it was created.
     unsafe fn wake_local(&self) {
         self.wake()
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 19be1a0..4efa013 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1001,6 +1001,8 @@
     let mut it = (0..).step_by(1).take(0).cycle();
     assert_eq!(it.size_hint(), (0, Some(0)));
     assert_eq!(it.next(), None);
+
+    assert_eq!(empty::<i32>().cycle().fold(0, |acc, x| acc + x), 0);
 }
 
 #[test]
diff --git a/src/libcore/tests/num/dec2flt/mod.rs b/src/libcore/tests/num/dec2flt/mod.rs
index 17b2f59..879a41b 100644
--- a/src/libcore/tests/num/dec2flt/mod.rs
+++ b/src/libcore/tests/num/dec2flt/mod.rs
@@ -17,7 +17,7 @@
 
 // Take a float literal, turn it into a string in various ways (that are all trusted
 // to be correct) and see if those strings are parsed back to the value of the literal.
-// Requires a *polymorphic literal*, i.e. one that can serve as f64 as well as f32.
+// Requires a *polymorphic literal*, i.e., one that can serve as f64 as well as f32.
 macro_rules! test_literal {
     ($x: expr) => ({
         let x32: f32 = $x;
diff --git a/src/libcore/tests/num/flt2dec/random.rs b/src/libcore/tests/num/flt2dec/random.rs
index ab61909..21a7c9f 100644
--- a/src/libcore/tests/num/flt2dec/random.rs
+++ b/src/libcore/tests/num/flt2dec/random.rs
@@ -18,7 +18,8 @@
 use core::num::flt2dec::strategy::grisu::format_shortest_opt;
 use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
 
-use rand::{FromEntropy, XorShiftRng};
+use rand::FromEntropy;
+use rand::rngs::SmallRng;
 use rand::distributions::{Distribution, Uniform};
 
 pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
@@ -71,7 +72,10 @@
 pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
         where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
               G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    let mut rng = XorShiftRng::from_entropy();
+    if cfg!(target_os = "emscripten") {
+        return // using rng pulls in i128 support, which doesn't work
+    }
+    let mut rng = SmallRng::from_entropy();
     let f32_range = Uniform::new(0x0000_0001u32, 0x7f80_0000);
     iterate("f32_random_equivalence_test", k, n, f, g, |_| {
         let x = f32::from_bits(f32_range.sample(&mut rng));
@@ -82,7 +86,10 @@
 pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
         where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
               G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    let mut rng = XorShiftRng::from_entropy();
+    if cfg!(target_os = "emscripten") {
+        return // using rng pulls in i128 support, which doesn't work
+    }
+    let mut rng = SmallRng::from_entropy();
     let f64_range = Uniform::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
     iterate("f64_random_equivalence_test", k, n, f, g, |_| {
         let x = f64::from_bits(f64_range.sample(&mut rng));
@@ -99,7 +106,7 @@
     // this is of course very stressful (and thus should be behind an `#[ignore]` attribute),
     // but with `-C opt-level=3 -C lto` this only takes about an hour or so.
 
-    // iterate from 0x0000_0001 to 0x7f7f_ffff, i.e. all finite ranges
+    // iterate from 0x0000_0001 to 0x7f7f_ffff, i.e., all finite ranges
     let (npassed, nignored) = iterate("f32_exhaustive_equivalence_test",
                                       k, 0x7f7f_ffff, f, g, |i: usize| {
 
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index dba5a43..4f00ebe 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -1024,11 +1024,11 @@
 fn sort_unstable() {
     use core::cmp::Ordering::{Equal, Greater, Less};
     use core::slice::heapsort;
-    use rand::{FromEntropy, Rng, XorShiftRng};
+    use rand::{FromEntropy, Rng, rngs::SmallRng, seq::SliceRandom};
 
     let mut v = [0; 600];
     let mut tmp = [0; 600];
-    let mut rng = XorShiftRng::from_entropy();
+    let mut rng = SmallRng::from_entropy();
 
     for len in (2..25).chain(500..510) {
         let v = &mut v[0..len];
@@ -1073,7 +1073,7 @@
     for i in 0..v.len() {
         v[i] = i as i32;
     }
-    v.sort_unstable_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap());
+    v.sort_unstable_by(|_, _| *[Less, Equal, Greater].choose(&mut rng).unwrap());
     v.sort_unstable();
     for i in 0..v.len() {
         assert_eq!(v[i], i as i32);
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index 938e975..475bb72 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -216,7 +216,7 @@
     ///
     /// This method does **not** return the length of the duration when
     /// represented by milliseconds. The returned number always represents a
-    /// fractional portion of a second (i.e. it is less than one thousand).
+    /// fractional portion of a second (i.e., it is less than one thousand).
     ///
     /// # Examples
     ///
@@ -235,7 +235,7 @@
     ///
     /// This method does **not** return the length of the duration when
     /// represented by microseconds. The returned number always represents a
-    /// fractional portion of a second (i.e. it is less than one million).
+    /// fractional portion of a second (i.e., it is less than one million).
     ///
     /// # Examples
     ///
@@ -254,7 +254,7 @@
     ///
     /// This method does **not** return the length of the duration when
     /// represented by nanoseconds. The returned number always represents a
-    /// fractional portion of a second (i.e. it is less than one billion).
+    /// fractional portion of a second (i.e., it is less than one billion).
     ///
     /// # Examples
     ///
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/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index 396b036..e3cf959 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -10,7 +10,7 @@
 
 //! Generate files suitable for use with [Graphviz](http://www.graphviz.org/)
 //!
-//! The `render` function generates output (e.g. an `output.dot` file) for
+//! The `render` function generates output (e.g., an `output.dot` file) for
 //! use with [Graphviz](http://www.graphviz.org/) by walking a labeled
 //! graph. (Graphviz can then automatically lay out the nodes and edges
 //! of the graph, and also optionally render the graph as an image or
@@ -25,7 +25,7 @@
 //! expressiveness of the [DOT language](
 //! http://www.graphviz.org/doc/info/lang.html). For example, there are
 //! many [attributes](http://www.graphviz.org/content/attrs) related to
-//! providing layout hints (e.g. left-to-right versus top-down, which
+//! providing layout hints (e.g., left-to-right versus top-down, which
 //! algorithm to use, etc). The current intention of this library is to
 //! emit a human-readable .dot file with very regular structure suitable
 //! for easy post-processing.
@@ -373,7 +373,7 @@
 // implement a Labelling service) that I have encountered is that it
 // makes it impossible to use types outside of the current crate
 // directly as Nodes/Edges; you need to wrap them in newtype'd
-// structs. See e.g. the `No` and `Ed` structs in the examples. (In
+// structs. See e.g., the `No` and `Ed` structs in the examples. (In
 // practice clients using a graph in some other crate would need to
 // provide some sort of adapter shim over the graph anyway to
 // interface with this library).
@@ -400,7 +400,7 @@
     /// The caller must ensure that the input conforms to an
     /// identifier format: it must be a non-empty string made up of
     /// alphanumeric or underscore characters, not beginning with a
-    /// digit (i.e. the regular expression `[a-zA-Z_][a-zA-Z_0-9]*`).
+    /// digit (i.e., the regular expression `[a-zA-Z_][a-zA-Z_0-9]*`).
     ///
     /// (Note: this format is a strict subset of the `ID` format
     /// defined by the DOT language.  This function may change in the
diff --git a/src/liblibc b/src/liblibc
deleted file mode 160000
index c75ca64..0000000
--- a/src/liblibc
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit c75ca6465a139704e00295be355b1f067af2f535
diff --git a/src/libpanic_abort/Cargo.toml b/src/libpanic_abort/Cargo.toml
index 633d273..e304e61 100644
--- a/src/libpanic_abort/Cargo.toml
+++ b/src/libpanic_abort/Cargo.toml
@@ -11,5 +11,5 @@
 
 [dependencies]
 core = { path = "../libcore" }
-libc = { path = "../rustc/libc_shim" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
+libc = { version = "0.2", default-features = false }
+compiler_builtins = "0.1.0"
diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs
index 9235f8e..95c3514 100644
--- a/src/libpanic_abort/lib.rs
+++ b/src/libpanic_abort/lib.rs
@@ -66,6 +66,12 @@
     unsafe fn abort() -> ! {
         core::intrinsics::abort();
     }
+
+    #[cfg(target_env="sgx")]
+    unsafe fn abort() -> ! {
+        extern "C" { pub fn panic_exit() -> !; }
+        panic_exit();
+    }
 }
 
 // This... is a bit of an oddity. The tl;dr; is that this is required to link
diff --git a/src/libpanic_unwind/Cargo.toml b/src/libpanic_unwind/Cargo.toml
index 74aaa4d..c9fce62 100644
--- a/src/libpanic_unwind/Cargo.toml
+++ b/src/libpanic_unwind/Cargo.toml
@@ -12,6 +12,6 @@
 [dependencies]
 alloc = { path = "../liballoc" }
 core = { path = "../libcore" }
-libc = { path = "../rustc/libc_shim" }
+libc = { version = "0.2", default-features = false }
 unwind = { path = "../libunwind" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
+compiler_builtins = "0.1.0"
diff --git a/src/libpanic_unwind/dwarf/mod.rs b/src/libpanic_unwind/dwarf/mod.rs
index 3ff250f..c9ae87a 100644
--- a/src/libpanic_unwind/dwarf/mod.rs
+++ b/src/libpanic_unwind/dwarf/mod.rs
@@ -32,7 +32,7 @@
         DwarfReader { ptr }
     }
 
-    // DWARF streams are packed, so e.g. a u32 would not necessarily be aligned
+    // DWARF streams are packed, so e.g., a u32 would not necessarily be aligned
     // on a 4-byte boundary. This may cause problems on platforms with strict
     // alignment requirements. By wrapping data in a "packed" struct, we are
     // telling the backend to generate "misalignment-safe" code.
diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs
index 11ebcf5..441058c 100644
--- a/src/libpanic_unwind/gcc.rs
+++ b/src/libpanic_unwind/gcc.rs
@@ -25,7 +25,7 @@
 //!
 //! In both phases the unwinder walks stack frames from top to bottom using
 //! information from the stack frame unwind sections of the current process's
-//! modules ("module" here refers to an OS module, i.e. an executable or a
+//! modules ("module" here refers to an OS module, i.e., an executable or a
 //! dynamic library).
 //!
 //! For each stack frame, it invokes the associated "personality routine", whose
@@ -296,7 +296,7 @@
 // Each module's image contains a frame unwind info section (usually
 // ".eh_frame").  When a module is loaded/unloaded into the process, the
 // unwinder must be informed about the location of this section in memory. The
-// methods of achieving that vary by the platform.  On some (e.g. Linux), the
+// methods of achieving that vary by the platform.  On some (e.g., Linux), the
 // unwinder can discover unwind info sections on its own (by dynamically
 // enumerating currently loaded modules via the dl_iterate_phdr() API and
 // finding their ".eh_frame" sections); Others, like Windows, require modules
diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs
index cfe671c..49f8a42 100644
--- a/src/libpanic_unwind/lib.rs
+++ b/src/libpanic_unwind/lib.rs
@@ -62,7 +62,7 @@
     if #[cfg(target_os = "emscripten")] {
         #[path = "emcc.rs"]
         mod imp;
-    } else if #[cfg(target_arch = "wasm32")] {
+    } else if #[cfg(any(target_arch = "wasm32", target_env = "sgx"))] {
         #[path = "dummy.rs"]
         mod imp;
     } else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] {
diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs
index 832a0af..9d24079 100644
--- a/src/libpanic_unwind/seh.rs
+++ b/src/libpanic_unwind/seh.rs
@@ -12,7 +12,7 @@
 //!
 //! On Windows (currently only on MSVC), the default exception handling
 //! mechanism is Structured Exception Handling (SEH). This is quite different
-//! than Dwarf-based exception handling (e.g. what other unix platforms use) in
+//! than Dwarf-based exception handling (e.g., what other unix platforms use) in
 //! terms of compiler internals, so LLVM is required to have a good deal of
 //! extra support for SEH.
 //!
@@ -304,7 +304,7 @@
     })
 }
 
-// This is required by the compiler to exist (e.g. it's a lang item), but
+// This is required by the compiler to exist (e.g., it's a lang item), but
 // it's never actually called by the compiler because __C_specific_handler
 // or _except_handler3 is the personality function that is always used.
 // Hence this is just an aborting stub.
diff --git a/src/libproc_macro/bridge/client.rs b/src/libproc_macro/bridge/client.rs
index ed27df4..f5e1271 100644
--- a/src/libproc_macro/bridge/client.rs
+++ b/src/libproc_macro/bridge/client.rs
@@ -262,7 +262,7 @@
     Connected(Bridge<'a>),
 
     /// Access to the bridge is being exclusively acquired
-    /// (e.g. during `BridgeState::with`).
+    /// (e.g., during `BridgeState::with`).
     InUse,
 }
 
@@ -283,7 +283,7 @@
     /// 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
+    /// N.B., 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| {
@@ -333,7 +333,7 @@
 /// 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).
+/// N.B., `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.
diff --git a/src/libproc_macro/bridge/mod.rs b/src/libproc_macro/bridge/mod.rs
index f03c63f..edb4d3f 100644
--- a/src/libproc_macro/bridge/mod.rs
+++ b/src/libproc_macro/bridge/mod.rs
@@ -14,7 +14,7 @@
 //! 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).
+//! Rust ABIs (e.g., stage0/bin/rustc vs stage1/bin/rustc during bootstrap).
 
 #![deny(unsafe_code)]
 
diff --git a/src/libproc_macro/bridge/scoped_cell.rs b/src/libproc_macro/bridge/scoped_cell.rs
index 51d1fec..c86d5fc 100644
--- a/src/libproc_macro/bridge/scoped_cell.rs
+++ b/src/libproc_macro/bridge/scoped_cell.rs
@@ -19,7 +19,7 @@
     type Out;
 }
 
-/// Type lambda taking a lifetime, i.e. `Lifetime -> Type`.
+/// 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 {}
diff --git a/src/libproc_macro/bridge/server.rs b/src/libproc_macro/bridge/server.rs
index f500b17..0c1d4f7 100644
--- a/src/libproc_macro/bridge/server.rs
+++ b/src/libproc_macro/bridge/server.rs
@@ -16,7 +16,7 @@
 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).
+/// adjusting it (i.e., adding bounds to types and default bodies to methods).
 macro_rules! associated_item {
     (type TokenStream) =>
         (type TokenStream: 'static + Clone;);
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index 32c8130..f2b8583 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -110,7 +110,7 @@
     }
 }
 
-// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// N.B., 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 {
@@ -196,7 +196,7 @@
     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,
+    /// 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")]
@@ -426,7 +426,7 @@
 #[unstable(feature = "proc_macro_span", issue = "54725")]
 impl Eq for SourceFile {}
 
-/// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`).
+/// A single token or a delimited sequence of token trees (e.g., `[1, (), ..]`).
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 #[derive(Clone)]
 pub enum TokenTree {
@@ -533,7 +533,7 @@
     }
 }
 
-// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// N.B., 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 {
@@ -663,7 +663,7 @@
     }
 }
 
-// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// N.B., 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 {
@@ -711,10 +711,10 @@
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 pub enum Spacing {
-    /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`.
+    /// e.g., `+` is `Alone` in `+ =`, `+ident` or `+()`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     Alone,
-    /// E.g. `+` is `Joint` in `+=` or `'#`.
+    /// e.g., `+` is `Joint` in `+=` or `'#`.
     /// Additionally, single quote `'` can join with identifiers to form lifetimes `'ident`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     Joint,
@@ -765,7 +765,7 @@
     }
 }
 
-// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// N.B., 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 {
@@ -860,7 +860,7 @@
     }
 }
 
-// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// N.B., 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 {
@@ -1110,7 +1110,7 @@
     }
 }
 
-// NB: the bridge only provides `to_string`, implement `fmt::Display`
+// N.B., 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 {
diff --git a/src/libprofiler_builtins/Cargo.toml b/src/libprofiler_builtins/Cargo.toml
index 79192fb..7c95cf0 100644
--- a/src/libprofiler_builtins/Cargo.toml
+++ b/src/libprofiler_builtins/Cargo.toml
@@ -13,7 +13,7 @@
 
 [dependencies]
 core = { path = "../libcore" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
+compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] }
 
 [build-dependencies]
 cc = "1.0.1"
diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs
index 8d6c7d6..db72ce7 100644
--- a/src/libprofiler_builtins/build.rs
+++ b/src/libprofiler_builtins/build.rs
@@ -56,9 +56,15 @@
         cfg.define("COMPILER_RT_HAS_UNAME", Some("1"));
     }
 
+    // The source for `compiler-rt` comes from the `compiler-builtins` crate, so
+    // load our env var set by cargo to find the source code.
+    let root = env::var_os("DEP_COMPILER_RT_COMPILER_RT").unwrap();
+    let root = Path::new(&root);
+
     for src in profile_sources {
-        cfg.file(Path::new("../libcompiler_builtins/compiler-rt/lib/profile").join(src));
+        cfg.file(root.join("lib").join("profile").join(src));
     }
 
+    cfg.warnings(false);
     cfg.compile("profiler-rt");
 }
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index 3316735..a572b6b 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -32,7 +32,7 @@
 byteorder = { version = "1.1", features = ["i128"]}
 chalk-engine = { version = "0.8.0", default-features=false }
 rustc_fs_util = { path = "../librustc_fs_util" }
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 
 # Note that these dependencies are a lie, they're just here to get linkage to
 # work.
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs
index 6b9c0aa..c5d6ce24 100644
--- a/src/librustc/cfg/construct.rs
+++ b/src/librustc/cfg/construct.rs
@@ -53,7 +53,7 @@
     let body_exit;
 
     // Find the tables for this body.
-    let owner_def_id = tcx.hir.local_def_id(tcx.hir.body_owner(body.id()));
+    let owner_def_id = tcx.hir().local_def_id(tcx.hir().body_owner(body.id()));
     let tables = tcx.typeck_tables_of(owner_def_id);
 
     let mut cfg_builder = CFGBuilder {
@@ -109,7 +109,7 @@
     }
 
     fn stmt(&mut self, stmt: &hir::Stmt, pred: CFGIndex) -> CFGIndex {
-        let hir_id = self.tcx.hir.node_to_hir_id(stmt.node.id());
+        let hir_id = self.tcx.hir().node_to_hir_id(stmt.node.id());
         match stmt.node {
             hir::StmtKind::Decl(ref decl, _) => {
                 let exit = self.decl(&decl, pred);
@@ -379,7 +379,7 @@
             }
 
             hir::ExprKind::Index(ref l, ref r) |
-            hir::ExprKind::Binary(_, ref l, ref r) => { // NB: && and || handled earlier
+            hir::ExprKind::Binary(_, ref l, ref r) => { // N.B., && and || handled earlier
                 self.straightline(expr, pred, [l, r].iter().map(|&e| &**e))
             }
 
@@ -588,9 +588,9 @@
         match destination.target_id {
             Ok(loop_id) => {
                 for b in &self.breakable_block_scopes {
-                    if b.block_expr_id == self.tcx.hir.node_to_hir_id(loop_id).local_id {
+                    if b.block_expr_id == self.tcx.hir().node_to_hir_id(loop_id).local_id {
                         let scope = region::Scope {
-                            id: self.tcx.hir.node_to_hir_id(loop_id).local_id,
+                            id: self.tcx.hir().node_to_hir_id(loop_id).local_id,
                             data: region::ScopeData::Node
                         };
                         return (scope, match scope_cf_kind {
@@ -600,9 +600,9 @@
                     }
                 }
                 for l in &self.loop_scopes {
-                    if l.loop_id == self.tcx.hir.node_to_hir_id(loop_id).local_id {
+                    if l.loop_id == self.tcx.hir().node_to_hir_id(loop_id).local_id {
                         let scope = region::Scope {
-                            id: self.tcx.hir.node_to_hir_id(loop_id).local_id,
+                            id: self.tcx.hir().node_to_hir_id(loop_id).local_id,
                             data: region::ScopeData::Node
                         };
                         return (scope, match scope_cf_kind {
diff --git a/src/librustc/cfg/graphviz.rs b/src/librustc/cfg/graphviz.rs
index 650aa39..3981069 100644
--- a/src/librustc/cfg/graphviz.rs
+++ b/src/librustc/cfg/graphviz.rs
@@ -32,11 +32,11 @@
 impl<'a, 'tcx> LabelledCFG<'a, 'tcx> {
     fn local_id_to_string(&self, local_id: hir::ItemLocalId) -> String {
         assert!(self.cfg.owner_def_id.is_local());
-        let node_id = self.tcx.hir.hir_to_node_id(hir::HirId {
-            owner: self.tcx.hir.def_index_to_hir_id(self.cfg.owner_def_id.index).owner,
+        let node_id = self.tcx.hir().hir_to_node_id(hir::HirId {
+            owner: self.tcx.hir().def_index_to_hir_id(self.cfg.owner_def_id.index).owner,
             local_id
         });
-        let s = self.tcx.hir.node_to_string(node_id);
+        let s = self.tcx.hir().node_to_string(node_id);
 
         // Replacing newlines with \\l causes each line to be left-aligned,
         // improving presentation of (long) pretty-printed expressions.
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 388bbc5..f0c6196 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -17,7 +17,7 @@
 //! fully identify a dependency node, even across multiple compilation sessions.
 //! In other words, the value of the fingerprint does not depend on anything
 //! that is specific to a given compilation session, like an unpredictable
-//! interning key (e.g. NodeId, DefId, Symbol) or the numeric value of a
+//! interning key (e.g., NodeId, DefId, Symbol) or the numeric value of a
 //! pointer. The concept behind this could be compared to how git commit hashes
 //! uniquely identify a given commit and has a few advantages:
 //!
@@ -28,7 +28,7 @@
 //! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
 //!   implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
 //! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
-//!   memory without any post-processing (e.g. "abomination-style" pointer
+//!   memory without any post-processing (e.g., "abomination-style" pointer
 //!   reconstruction).
 //! * Because a `DepNode` is self-contained, we can instantiate `DepNodes` that
 //!   refer to things that do not exist anymore. In previous implementations
@@ -81,7 +81,7 @@
 use ty::subst::Substs;
 
 // erase!() just makes tokens go away. It's used to specify which macro argument
-// is repeated (i.e. which sub-expression of the macro we are in) but don't need
+// is repeated (i.e., which sub-expression of the macro we are in) but don't need
 // to actually use any of the arguments.
 macro_rules! erase {
     ($x:tt) => ({})
@@ -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);
             )*
         }
     );
@@ -449,10 +449,10 @@
     // Represents the `Krate` as a whole (the `hir::Krate` value) (as
     // distinct from the krate module). This is basically a hash of
     // the entire krate, so if you read from `Krate` (e.g., by calling
-    // `tcx.hir.krate()`), we will have to assume that any change
+    // `tcx.hir().krate()`), we will have to assume that any change
     // means that you need to be recompiled. This is because the
     // `Krate` value gives you access to all other items. To avoid
-    // this fate, do not call `tcx.hir.krate()`; instead, prefer
+    // this fate, do not call `tcx.hir().krate()`; instead, prefer
     // wrappers like `tcx.visit_all_items_in_krate()`.  If there is no
     // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
     // access to the krate, but you must remember to add suitable
@@ -733,7 +733,7 @@
     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
 
     fn to_fingerprint(&self, tcx: TyCtxt<'_, '_, '_>) -> Fingerprint {
-        tcx.hir.definitions().def_path_hash(*self).0
+        tcx.hir().definitions().def_path_hash(*self).0
     }
 
     fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String {
diff --git a/src/librustc/dep_graph/dep_tracking_map.rs b/src/librustc/dep_graph/dep_tracking_map.rs
index a674b5d..da7dabf 100644
--- a/src/librustc/dep_graph/dep_tracking_map.rs
+++ b/src/librustc/dep_graph/dep_tracking_map.rs
@@ -65,7 +65,7 @@
     ///
     /// ```
     /// fn type_of_item(..., item: &hir::Item) -> Ty<'tcx> {
-    ///     let item_def_id = ccx.tcx.hir.local_def_id(it.id);
+    ///     let item_def_id = ccx.tcx.hir().local_def_id(it.id);
     ///     ccx.tcx.item_types.memoized(item_def_id, || {
     ///         ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id)); // (*)
     ///         compute_type_of_item(ccx, item)
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index 96590c1..3dc6f76 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -47,7 +47,7 @@
 We cannot create an object of type `Box<Foo>` or `&Foo` since in this case
 `Self` would not be `Sized`.
 
-Generally, `Self : Sized` is used to indicate that the trait should not be used
+Generally, `Self: Sized` is used to indicate that the trait should not be used
 as a trait object. If the trait comes from your own crate, consider removing
 this restriction.
 
@@ -217,9 +217,9 @@
 ```
 
 If this is not an option, consider replacing the type parameter with another
-trait object (e.g. if `T: OtherTrait`, use `on: Box<OtherTrait>`). If the number
-of types you intend to feed to this method is limited, consider manually listing
-out the methods of different types.
+trait object (e.g., if `T: OtherTrait`, use `on: Box<OtherTrait>`). If the
+number of types you intend to feed to this method is limited, consider manually
+listing out the methods of different types.
 
 ### Method has no receiver
 
@@ -642,7 +642,7 @@
 ```
 
 Lang items are already implemented in the standard library. Unless you are
-writing a free-standing application (e.g. a kernel), you do not need to provide
+writing a free-standing application (e.g., a kernel), you do not need to provide
 them yourself.
 
 You can build a free-standing crate by adding `#![no_std]` to the crate
@@ -699,7 +699,7 @@
 match with any of the type parameters or the string `Self`. This might happen
 if you misspelled a type parameter, or if you intended to use literal curly
 braces. If it is the latter, escape the curly braces with a second curly brace
-of the same type; e.g. a literal `{` is `{{`.
+of the same type; e.g., a literal `{` is `{{`.
 "##,
 
 E0231: r##"
@@ -832,7 +832,7 @@
 
 E0271: r##"
 This is because of a type mismatch between the associated type of some
-trait (e.g. `T::Bar`, where `T` implements `trait Quux { type Bar; }`)
+trait (e.g., `T::Bar`, where `T` implements `trait Quux { type Bar; }`)
 and another type `U` that is required to be equal to `T::Bar`, but is not.
 Examples follow.
 
@@ -1622,7 +1622,7 @@
 won't work on enums.
 
 `#[repr(simd)]` will give a struct consisting of a homogeneous series of machine
-types (i.e. `u8`, `i32`, etc) a representation that permits vectorization via
+types (i.e., `u8`, `i32`, etc) a representation that permits vectorization via
 SIMD. This doesn't make much sense for enums since they don't consist of a
 single list of data.
 "##,
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index 020012d..5ff533f 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -100,7 +100,7 @@
     /// Check any attribute.
     fn check_attributes(&self, item: &hir::Item, target: Target) {
         if target == Target::Fn || target == Target::Const {
-            self.tcx.codegen_fn_attrs(self.tcx.hir.local_def_id(item.id));
+            self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(item.id));
         } else if let Some(a) = item.attrs.iter().find(|a| a.check_name("target_feature")) {
             self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function")
                 .span_label(item.span, "not a function")
@@ -352,7 +352,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
@@ -375,7 +375,7 @@
 
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut checker = CheckAttrVisitor { tcx };
-    tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
+    tcx.hir().krate().visit_all_item_likes(&mut checker.as_deep_visitor());
 }
 
 fn is_c_like_enum(item: &hir::Item) -> bool {
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index 50922ee..fb3c3de 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -46,7 +46,7 @@
 pub enum Def {
     // Type namespace
     Mod(DefId),
-    Struct(DefId), // DefId refers to NodeId of the struct itself
+    Struct(DefId), // `DefId` refers to `NodeId` of the struct itself
     Union(DefId),
     Enum(DefId),
     Variant(DefId),
@@ -63,27 +63,27 @@
     PrimTy(hir::PrimTy),
     TyParam(DefId),
     SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
-    ToolMod, // e.g. `rustfmt` in `#[rustfmt::skip]`
+    ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`
 
     // Value namespace
     Fn(DefId),
     Const(DefId),
     Static(DefId, bool /* is_mutbl */),
-    StructCtor(DefId, CtorKind), // DefId refers to NodeId of the struct's constructor
-    VariantCtor(DefId, CtorKind), // DefId refers to the enum variant
-    SelfCtor(DefId /* impl */),  // DefId refers to the impl
+    StructCtor(DefId, CtorKind), // `DefId` refers to `NodeId` of the struct's constructor
+    VariantCtor(DefId, CtorKind), // `DefId` refers to the enum variant
+    SelfCtor(DefId /* impl */),  // `DefId` refers to the impl
     Method(DefId),
     AssociatedConst(DefId),
 
     Local(ast::NodeId),
-    Upvar(ast::NodeId,  // node id of closed over local
-          usize,        // index in the freevars list of the closure
+    Upvar(ast::NodeId,  // `NodeId` of closed over local
+          usize,        // index in the `freevars` list of the closure
           ast::NodeId), // expr node that creates the closure
     Label(ast::NodeId),
 
     // Macro namespace
     Macro(DefId, MacroKind),
-    NonMacroAttr(NonMacroAttrKind), // e.g. `#[inline]` or `#[rustfmt::skip]`
+    NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
 
     // Both namespaces
     Err,
@@ -170,6 +170,7 @@
 
 impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
     type Output = T;
+
     fn index(&self, ns: Namespace) -> &T {
         match ns {
             ValueNS => &self.value_ns,
@@ -238,6 +239,7 @@
             ast::VariantData::Struct(..) => CtorKind::Fictive,
         }
     }
+
     pub fn from_hir(vdata: &hir::VariantData) -> CtorKind {
         match *vdata {
             hir::VariantData::Tuple(..) => CtorKind::Fn,
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index d9963f2..f7e2c70 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -131,7 +131,7 @@
 /// Each method of the Visitor trait is a hook to be potentially
 /// overridden.  Each method's default implementation recursively visits
 /// the substructure of the input via the corresponding `walk` method;
-/// e.g. the `visit_mod` method by default calls `intravisit::walk_mod`.
+/// e.g., the `visit_mod` method by default calls `intravisit::walk_mod`.
 ///
 /// Note that this visitor does NOT visit nested items by default
 /// (this is why the module is called `intravisit`, to distinguish it
@@ -493,7 +493,7 @@
                              item.id)
         }
         ItemKind::Mod(ref module) => {
-            // visit_mod() takes care of visiting the Item's NodeId
+            // `visit_mod()` takes care of visiting the `Item`'s `NodeId`.
             visitor.visit_mod(module, item.span, item.id)
         }
         ItemKind::ForeignMod(ref foreign_module) => {
@@ -518,7 +518,7 @@
         }
         ItemKind::Enum(ref enum_definition, ref type_parameters) => {
             visitor.visit_generics(type_parameters);
-            // visit_enum_def() takes care of visiting the Item's NodeId
+            // `visit_enum_def()` takes care of visiting the `Item`'s `NodeId`.
             visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
         }
         ItemKind::Impl(
@@ -877,7 +877,7 @@
 }
 
 pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref: &'v TraitItemRef) {
-    // NB: Deliberately force a compilation error if/when new fields are added.
+    // N.B., deliberately force a compilation error if/when new fields are added.
     let TraitItemRef { id, ident, ref kind, span: _, ref defaultness } = *trait_item_ref;
     visitor.visit_nested_trait_item(id);
     visitor.visit_ident(ident);
@@ -886,7 +886,7 @@
 }
 
 pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
-    // NB: Deliberately force a compilation error if/when new fields are added.
+    // N.B., deliberately force a compilation error if/when new fields are added.
     let ImplItem {
         id: _,
         hir_id: _,
@@ -932,7 +932,7 @@
 }
 
 pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) {
-    // NB: Deliberately force a compilation error if/when new fields are added.
+    // N.B., deliberately force a compilation error if/when new fields are added.
     let ImplItemRef { id, ident, ref kind, span: _, ref vis, ref defaultness } = *impl_item_ref;
     visitor.visit_nested_impl_item(id);
     visitor.visit_ident(ident);
diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc/hir/itemlikevisit.rs
index a62000e..f8bc764 100644
--- a/src/librustc/hir/itemlikevisit.rs
+++ b/src/librustc/hir/itemlikevisit.rs
@@ -19,7 +19,7 @@
 ///
 /// 1. **Shallow visit**: Get a simple callback for every item (or item-like thing) in the HIR.
 ///    - Example: find all items with a `#[foo]` attribute on them.
-///    - How: Implement `ItemLikeVisitor` and call `tcx.hir.krate().visit_all_item_likes()`.
+///    - How: Implement `ItemLikeVisitor` and call `tcx.hir().krate().visit_all_item_likes()`.
 ///    - Pro: Efficient; just walks the lists of item-like things, not the nodes themselves.
 ///    - Con: Don't get information about nesting
 ///    - Con: Don't have methods for specific bits of HIR, like "on
@@ -29,7 +29,7 @@
 ///    within one another.
 ///    - Example: Examine each expression to look for its type and do some check or other.
 ///    - How: Implement `intravisit::Visitor` and use
-///      `tcx.hir.krate().visit_all_item_likes(visitor.as_deep_visitor())`. Within
+///      `tcx.hir().krate().visit_all_item_likes(visitor.as_deep_visitor())`. Within
 ///      your `intravisit::Visitor` impl, implement methods like
 ///      `visit_expr()`; don't forget to invoke
 ///      `intravisit::walk_visit_expr()` to keep walking the subparts.
@@ -43,7 +43,7 @@
 ///    - How: Implement `intravisit::Visitor` and override the
 ///      `nested_visit_map()` methods to return
 ///      `NestedVisitorMap::All`. Walk your crate with
-///      `intravisit::walk_crate()` invoked on `tcx.hir.krate()`.
+///      `intravisit::walk_crate()` invoked on `tcx.hir().krate()`.
 ///    - Pro: Visitor methods for any kind of HIR node, not just item-like things.
 ///    - Pro: Preserves nesting information
 ///    - Con: Does not integrate well into dependency tracking.
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index dc8baa1..6958801 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -72,7 +72,7 @@
 use syntax::source_map::{self, respan, CompilerDesugaringKind, Spanned};
 use syntax::std_inject;
 use syntax::symbol::{keywords, Symbol};
-use syntax::tokenstream::{Delimited, TokenStream, TokenTree};
+use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax::parse::token::Token;
 use syntax::visit::{self, Visitor};
 use syntax_pos::{Span, MultiSpan};
@@ -82,7 +82,7 @@
 pub struct LoweringContext<'a> {
     crate_root: Option<&'static str>,
 
-    // Use to assign ids to hir nodes that do not directly correspond to an ast node
+    // Used to assign ids to HIR nodes that do not directly correspond to an AST node.
     sess: &'a Session,
 
     cstore: &'a dyn CrateStore,
@@ -114,10 +114,10 @@
     anonymous_lifetime_mode: AnonymousLifetimeMode,
 
     // Used to create lifetime definitions from in-band lifetime usages.
-    // e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
+    // e.g., `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
     // When a named lifetime is encountered in a function or impl header and
     // has not been defined
-    // (i.e. it doesn't appear in the in_scope_lifetimes list), it is added
+    // (i.e., it doesn't appear in the in_scope_lifetimes list), it is added
     // to this list. The results of this list are then added to the list of
     // lifetime definitions in the corresponding impl or function generics.
     lifetimes_to_define: Vec<(Span, ParamName)>,
@@ -149,7 +149,7 @@
         is_value: bool,
     ) -> hir::Path;
 
-    /// Obtain the resolution for a node id
+    /// Obtain the resolution for a node-id.
     fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
 
     /// Obtain the possible resolutions for the given `use` statement.
@@ -159,8 +159,8 @@
     /// This should only return `None` during testing.
     fn definitions(&mut self) -> &mut Definitions;
 
-    /// Given suffix ["b","c","d"], creates a HIR path for `[::crate_root]::b::c::d` and resolves
-    /// it based on `is_value`.
+    /// Given suffix `["b", "c", "d"]`, creates a HIR path for `[::crate_root]::b::c::d` and
+    /// resolves it based on `is_value`.
     fn resolve_str_path(
         &mut self,
         span: Span,
@@ -185,7 +185,7 @@
     ///
     /// We optionally store a `DefId` for the parent item here so we can look up necessary
     /// information later. It is `None` when no information about the context should be stored,
-    /// e.g. for consts and statics.
+    /// e.g., for consts and statics.
     Existential(Option<DefId>),
 
     /// `impl Trait` is not accepted in this position.
@@ -358,8 +358,8 @@
     fn lower_crate(mut self, c: &Crate) -> hir::Crate {
         /// Full-crate AST visitor that inserts into a fresh
         /// `LoweringContext` any information that may be
-        /// needed from arbitrary locations in the crate.
-        /// E.g. The number of lifetime generic parameters
+        /// needed from arbitrary locations in the crate,
+        /// e.g., the number of lifetime generic parameters
         /// declared for every type and trait definition.
         struct MiscCollector<'lcx, 'interner: 'lcx> {
             lctx: &'lcx mut LoweringContext<'interner>,
@@ -512,7 +512,7 @@
                 debug
             );
         }
-        // Always allocate the first HirId for the owner itself
+        // Always allocate the first `HirId` for the owner itself.
         self.lower_node_id_with_owner(owner, owner)
     }
 
@@ -536,7 +536,7 @@
         let existing_hir_id = self.node_id_to_hir_id[ast_node_id];
 
         if existing_hir_id == hir::DUMMY_HIR_ID {
-            // Generate a new HirId
+            // Generate a new `HirId`.
             let hir_id = alloc_hir_id(self);
             self.node_id_to_hir_id[ast_node_id] = hir_id;
             LoweredNodeId {
@@ -573,12 +573,12 @@
         ret
     }
 
-    /// This method allocates a new HirId for the given NodeId and stores it in
-    /// the LoweringContext's NodeId => HirId map.
-    /// Take care not to call this method if the resulting HirId is then not
+    /// This method allocates a new `HirId` for the given `NodeId` and stores it in
+    /// the `LoweringContext`'s `NodeId => HirId` map.
+    /// Take care not to call this method if the resulting `HirId` is then not
     /// actually used in the HIR, as that would trigger an assertion in the
-    /// HirIdValidator later on, which makes sure that all NodeIds got mapped
-    /// properly. Calling the method twice with the same NodeId is fine though.
+    /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
+    /// properly. Calling the method twice with the same `NodeId` is fine though.
     fn lower_node_id(&mut self, ast_node_id: NodeId) -> LoweredNodeId {
         self.lower_node_id_generic(ast_node_id, |this| {
             let &mut (def_index, ref mut local_id_counter) =
@@ -743,7 +743,7 @@
                     ),
                 };
 
-                // Add a definition for the in-band lifetime def
+                // Add a definition for the in-band lifetime def.
                 self.resolver.definitions().create_def_with_parent(
                     parent_id.index,
                     def_node_id,
@@ -1067,7 +1067,7 @@
     fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
         // Note that we explicitly do not walk the path. Since we don't really
         // lower attributes (we use the AST version) there is nowhere to keep
-        // the HirIds. We don't actually need HIR version of attributes anyway.
+        // the `HirId`s. We don't actually need HIR version of attributes anyway.
         Attribute {
             id: attr.id,
             style: attr.style,
@@ -1088,12 +1088,10 @@
     fn lower_token_tree(&mut self, tree: TokenTree) -> TokenStream {
         match tree {
             TokenTree::Token(span, token) => self.lower_token(token, span),
-            TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
+            TokenTree::Delimited(span, delim, tts) => TokenTree::Delimited(
                 span,
-                Delimited {
-                    delim: delimited.delim,
-                    tts: self.lower_token_stream(delimited.tts.into()).into(),
-                },
+                delim,
+                self.lower_token_stream(tts.into()).into(),
             ).into(),
         }
     }
@@ -1201,7 +1199,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,
                 }),
             )),
@@ -1246,7 +1244,7 @@
                     }
                     ImplTraitContext::Universal(in_band_ty_params) => {
                         self.lower_node_id(def_node_id);
-                        // Add a definition for the in-band Param
+                        // Add a definition for the in-band `Param`.
                         let def_index = self
                             .resolver
                             .definitions()
@@ -1257,7 +1255,7 @@
                             bounds,
                             ImplTraitContext::Universal(in_band_ty_params),
                         );
-                        // Set the name to `impl Bound1 + Bound2`
+                        // Set the name to `impl Bound1 + Bound2`.
                         let ident = Ident::from_str(&pprust::ty_to_string(t)).with_span_pos(span);
                         in_band_ty_params.push(hir::GenericParam {
                             id: def_node_id,
@@ -1365,7 +1363,7 @@
                 impl_trait_fn: fn_def_id,
             });
             let exist_ty_id = lctx.lower_node_id(exist_ty_node_id);
-            // Generate an `existential type Foo: Trait;` declaration
+            // Generate an `existential type Foo: Trait;` declaration.
             trace!("creating existential type with id {:#?}", exist_ty_id);
 
             trace!("exist ty def index: {:#?}", exist_ty_def_index);
@@ -1384,7 +1382,7 @@
             // does not actually exist in the AST.
             lctx.items.insert(exist_ty_id.node_id, exist_ty_item);
 
-            // `impl Trait` now just becomes `Foo<'a, 'b, ..>`
+            // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
             hir::TyKind::Def(hir::ItemId { id: exist_ty_id.node_id }, lifetimes)
         })
     }
@@ -1397,7 +1395,7 @@
     ) -> (HirVec<hir::GenericArg>, HirVec<hir::GenericParam>) {
         // This visitor walks over impl trait bounds and creates defs for all lifetimes which
         // appear in the bounds, excluding lifetimes that are created within the bounds.
-        // e.g. 'a, 'b, but not 'c in `impl for<'c> SomeTrait<'a, 'b, 'c>`
+        // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
         struct ImplTraitLifetimeCollector<'r, 'a: 'r> {
             context: &'r mut LoweringContext<'a>,
             parent: DefIndex,
@@ -1429,7 +1427,7 @@
             }
 
             fn visit_ty(&mut self, t: &'v hir::Ty) {
-                // Don't collect elided lifetimes used inside of `fn()` syntax
+                // Don't collect elided lifetimes used inside of `fn()` syntax.
                 if let hir::TyKind::BareFn(_) = t.node {
                     let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
                     self.collect_elided_lifetimes = false;
@@ -1459,10 +1457,10 @@
             }
 
             fn visit_generic_param(&mut self, param: &'v hir::GenericParam) {
-                // Record the introduction of 'a in `for<'a> ...`
+                // Record the introduction of 'a in `for<'a> ...`.
                 if let hir::GenericParamKind::Lifetime { .. } = param.kind {
                     // Introduce lifetimes one at a time so that we can handle
-                    // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`
+                    // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`.
                     let lt_name = hir::LifetimeName::Param(param.name);
                     self.currently_bound_lifetimes.push(lt_name);
                 }
@@ -1475,7 +1473,7 @@
                     hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
                         if self.collect_elided_lifetimes {
                             // Use `'_` for both implicit and underscore lifetimes in
-                            // `abstract type Foo<'_>: SomeTrait<'_>;`
+                            // `abstract type Foo<'_>: SomeTrait<'_>;`.
                             hir::LifetimeName::Underscore
                         } else {
                             return;
@@ -1648,7 +1646,7 @@
                         {
                             ParenthesizedGenericArgs::Ok
                         }
-                        // Avoid duplicated errors
+                        // Avoid duplicated errors.
                         Def::Err => ParenthesizedGenericArgs::Ok,
                         // An error
                         Def::Struct(..)
@@ -1689,7 +1687,7 @@
         });
 
         // Simple case, either no projections, or only fully-qualified.
-        // E.g. `std::mem::size_of` or `<I as Iterator>::Item`.
+        // E.g., `std::mem::size_of` or `<I as Iterator>::Item`.
         if resolution.unresolved_segments() == 0 {
             return hir::QPath::Resolved(qself, path);
         }
@@ -1697,11 +1695,11 @@
         // Create the innermost type that we're projecting from.
         let mut ty = if path.segments.is_empty() {
             // If the base path is empty that means there exists a
-            // syntactical `Self`, e.g. `&i32` in `<&i32>::clone`.
+            // syntactical `Self`, e.g., `&i32` in `<&i32>::clone`.
             qself.expect("missing QSelf for <T>::...")
         } else {
             // Otherwise, the base path is an implicit `Self` type path,
-            // e.g. `Vec` in `Vec::new` or `<I as Iterator>::Item` in
+            // e.g., `Vec` in `Vec::new` or `<I as Iterator>::Item` in
             // `<I as Iterator>::Item::default`.
             let new_id = self.next_id();
             P(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)))
@@ -1709,7 +1707,7 @@
 
         // Anything after the base path are associated "extensions",
         // out of which all but the last one are associated types,
-        // e.g. for `std::vec::Vec::<T>::IntoIter::Item::clone`:
+        // e.g., for `std::vec::Vec::<T>::IntoIter::Item::clone`:
         // * base path is `std::vec::Vec<T>`
         // * "extensions" are `IntoIter`, `Item` and `clone`
         // * type nodes are:
@@ -1739,7 +1737,7 @@
             ty = P(self.ty_path(new_id, p.span, qpath));
         }
 
-        // Should've returned in the for loop above.
+        // We should've returned in the for loop above.
         span_bug!(
             p.span,
             "lower_qpath: no final extension segment in {}..{}",
@@ -1838,11 +1836,11 @@
                 let no_bindings = generic_args.bindings.is_empty();
                 let (incl_angl_brckt, insertion_span, suggestion) = if no_ty_args && no_bindings {
                     // If there are no (non-implicit) generic args or associated-type
-                    // bindings, our suggestion includes the angle brackets
+                    // bindings, our suggestion includes the angle brackets.
                     (true, path_span.shrink_to_hi(), format!("<{}>", anon_lt_suggestion))
                 } else {
                     // Otherwise—sorry, this is kind of gross—we need to infer the
-                    // place to splice in the `'_, ` from the generics that do exist
+                    // place to splice in the `'_, ` from the generics that do exist.
                     let first_generic_span = first_generic_span
                         .expect("already checked that type args or bindings exist");
                     (false, first_generic_span.shrink_to_lo(), format!("{}, ", anon_lt_suggestion))
@@ -2096,14 +2094,15 @@
         return_impl_trait_id: NodeId,
     ) -> hir::FunctionRetTy {
         // Get lifetimes used in the input arguments to the function. Our output type must also
-        // have the same lifetime. FIXME(cramertj) multiple different lifetimes are not allowed
-        // because `impl Trait + 'a + 'b` doesn't allow for capture `'a` and `'b` where neither
-        // is a subset of the other. We really want some new lifetime that is a subset of all input
-        // lifetimes, but that doesn't exist at the moment.
+        // have the same lifetime.
+        // FIXME(cramertj): multiple different lifetimes are not allowed because
+        // `impl Trait + 'a + 'b` doesn't allow for capture `'a` and `'b` where neither is a subset
+        // of the other. We really want some new lifetime that is a subset of all input lifetimes,
+        // but that doesn't exist at the moment.
 
         struct AsyncFnLifetimeCollector<'r, 'a: 'r> {
             context: &'r mut LoweringContext<'a>,
-            // Lifetimes bound by HRTB
+            // Lifetimes bound by HRTB.
             currently_bound_lifetimes: Vec<hir::LifetimeName>,
             // Whether to count elided lifetimes.
             // Disabled inside of `Fn` or `fn` syntax.
@@ -2133,7 +2132,7 @@
             }
 
             fn visit_ty(&mut self, t: &'v hir::Ty) {
-                // Don't collect elided lifetimes used inside of `fn()` syntax
+                // Don't collect elided lifetimes used inside of `fn()` syntax.
                 if let &hir::TyKind::BareFn(_) = &t.node {
                     let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
                     self.collect_elided_lifetimes = false;
@@ -2424,8 +2423,8 @@
             GenericParamKind::Type { ref default, .. } => {
                 // 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() {
+                // Instead, use `gensym("Self")` to create a distinct name that looks the same.
+                let ident = if param.ident.name == keywords::SelfUpper.name() {
                     param.ident.gensym()
                 } else {
                     param.ident
@@ -2467,7 +2466,7 @@
         -> hir::Generics
     {
         // Collect `?Trait` bounds in where clause and move them to parameter definitions.
-        // FIXME: This could probably be done with less rightward drift. Also looks like two control
+        // FIXME: this could probably be done with less rightward drift. Also looks like two control
         //        paths where report_error is called are also the only paths that advance to after
         //        the match statement, so the error reporting could probably just be moved there.
         let mut add_bounds: NodeMap<Vec<_>> = Default::default();
@@ -2563,7 +2562,7 @@
                                 .iter()
                                 .filter_map(|bound| match *bound {
                                     // Ignore `?Trait` bounds.
-                                    // Tthey were copied into type parameters already.
+                                    // They were copied into type parameters already.
                                     GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
                                     _ => Some(this.lower_param_bound(
                                         bound,
@@ -2662,7 +2661,7 @@
             id: self.lower_node_id(f.id).node_id,
             ident: match f.ident {
                 Some(ident) => ident,
-                // FIXME(jseyfried) positional field hygiene
+                // FIXME(jseyfried): positional field hygiene
                 None => Ident::new(Symbol::intern(&index.to_string()), f.span),
             },
             vis: self.lower_visibility(&f.vis, None),
@@ -2946,7 +2945,7 @@
         }
 
         // [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
-        //     not cause an assertion failure inside the `lower_defaultness` function
+        //     not cause an assertion failure inside the `lower_defaultness` function.
     }
 
     fn lower_use_tree(
@@ -2981,7 +2980,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() {
@@ -3190,7 +3189,7 @@
 
     /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
     /// many times in the HIR tree; for each occurrence, we need to assign distinct
-    /// node-ids. (See e.g. #56128.)
+    /// node-ids. (See e.g., #56128.)
     fn renumber_segment_ids(&mut self, path: &P<hir::Path>) -> P<hir::Path> {
         debug!("renumber_segment_ids(path = {:?})", path);
         let mut path = path.clone();
@@ -3780,7 +3779,7 @@
                 let else_opt = else_opt.as_ref().map(|els| {
                     match els.node {
                         ExprKind::IfLet(..) => {
-                            // wrap the if-let expr in a block
+                            // Wrap the `if let` expr in a block.
                             let span = els.span;
                             let els = P(self.lower_expr(els));
                             let LoweredNodeId { node_id, hir_id } = self.next_id();
@@ -3871,7 +3870,7 @@
                     let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
 
                     self.with_new_scopes(|this| {
-                        // FIXME(cramertj) allow `async` non-`move` closures with
+                        // FIXME(cramertj): allow `async` non-`move` closures with arguments.
                         if capture_clause == CaptureBy::Ref &&
                             !decl.inputs.is_empty()
                         {
@@ -3883,13 +3882,13 @@
                                 are not currently supported",
                             )
                                 .help("consider using `let` statements to manually capture \
-                                        variables by reference before entering an \
-                                        `async move` closure")
+                                       variables by reference before entering an \
+                                       `async move` closure")
                                 .emit();
                         }
 
                         // Transform `async |x: u8| -> X { ... }` into
-                        // `|x: u8| future_from_generator(|| -> X { ... })`
+                        // `|x: u8| future_from_generator(|| -> X { ... })`.
                         let body_id = this.lower_body(Some(&outer_decl), |this| {
                             let async_ret_ty = if let FunctionRetTy::Ty(ty) = &decl.output {
                                 Some(&**ty)
@@ -3972,7 +3971,7 @@
             ExprKind::Index(ref el, ref er) => {
                 hir::ExprKind::Index(P(self.lower_expr(el)), P(self.lower_expr(er)))
             }
-            // Desugar `<start>..=<end>` to `std::ops::RangeInclusive::new(<start>, <end>)`
+            // Desugar `<start>..=<end>` into `std::ops::RangeInclusive::new(<start>, <end>)`.
             ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => {
                 let id = self.next_id();
                 let e1 = self.lower_expr(e1);
@@ -4106,11 +4105,11 @@
             ),
             ExprKind::Paren(ref ex) => {
                 let mut ex = self.lower_expr(ex);
-                // include parens in span, but only if it is a super-span.
+                // Include parens in span, but only if it is a super-span.
                 if e.span.contains(ex.span) {
                     ex.span = e.span;
                 }
-                // merge attributes into the inner expression.
+                // Merge attributes into the inner expression.
                 let mut attrs = e.attrs.clone();
                 attrs.extend::<Vec<_>>(ex.attrs.into());
                 ex.attrs = attrs;
@@ -4128,8 +4127,8 @@
                 hir::ExprKind::Yield(P(expr))
             }
 
-            // Desugar ExprIfLet
-            // From: `if let <pat> = <sub_expr> <body> [<else_opt>]`
+            // Desugar `ExprIfLet`
+            // from: `if let <pat> = <sub_expr> <body> [<else_opt>]`
             ExprKind::IfLet(ref pats, ref sub_expr, ref body, ref else_opt) => {
                 // to:
                 //
@@ -4173,8 +4172,8 @@
                 )
             }
 
-            // Desugar ExprWhileLet
-            // From: `[opt_ident]: while let <pat> = <sub_expr> <body>`
+            // Desugar `ExprWhileLet`
+            // from: `[opt_ident]: while let <pat> = <sub_expr> <body>`
             ExprKind::WhileLet(ref pats, ref sub_expr, ref body, opt_label) => {
                 // to:
                 //
@@ -4223,12 +4222,12 @@
                     self.lower_label(opt_label),
                     hir::LoopSource::WhileLet,
                 );
-                // add attributes to the outer returned expr node
+                // Add attributes to the outer returned expr node.
                 loop_expr
             }
 
-            // Desugar ExprForLoop
-            // From: `[opt_ident]: for <pat> in <head> <body>`
+            // Desugar `ExprForLoop`
+            // from: `[opt_ident]: for <pat> in <head> <body>`
             ExprKind::ForLoop(ref pat, ref head, ref body, opt_label) => {
                 // to:
                 //
@@ -4386,21 +4385,21 @@
                 ));
 
                 // `{ let _result = ...; _result }`
-                // underscore prevents an unused_variables lint if the head diverges
+                // Underscore prevents an `unused_variables` lint if the head diverges.
                 let result_ident = self.str_to_ident("_result");
                 let (let_stmt, let_stmt_binding) =
                     self.stmt_let(e.span, false, result_ident, match_expr);
 
                 let result = P(self.expr_ident(e.span, result_ident, let_stmt_binding));
                 let block = P(self.block_all(e.span, hir_vec![let_stmt], Some(result)));
-                // add the attributes to the outer returned expr node
+                // Add the attributes to the outer returned expr node.
                 return self.expr_block(block, e.attrs.clone());
             }
 
-            // Desugar ExprKind::Try
-            // From: `<expr>?`
+            // Desugar `ExprKind::Try`
+            // from: `<expr>?`
             ExprKind::Try(ref sub_expr) => {
-                // to:
+                // into:
                 //
                 // match Try::into_result(<expr>) {
                 //     Ok(val) => #[allow(unreachable_code)] val,
@@ -4414,7 +4413,7 @@
                 let unstable_span =
                     self.allow_internal_unstable(CompilerDesugaringKind::QuestionMark, e.span);
 
-                // Try::into_result(<expr>)
+                // `Try::into_result(<expr>)`
                 let discr = {
                     // expand <expr>
                     let sub_expr = self.lower_expr(sub_expr);
@@ -4425,9 +4424,9 @@
                     P(self.expr_call(e.span, path, hir_vec![sub_expr]))
                 };
 
-                // #[allow(unreachable_code)]
+                // `#[allow(unreachable_code)]`
                 let attr = {
-                    // allow(unreachable_code)
+                    // `allow(unreachable_code)`
                     let allow = {
                         let allow_ident = Ident::from_str("allow").with_span_pos(e.span);
                         let uc_ident = Ident::from_str("unreachable_code").with_span_pos(e.span);
@@ -4438,7 +4437,7 @@
                 };
                 let attrs = vec![attr];
 
-                // Ok(val) => #[allow(unreachable_code)] val,
+                // `Ok(val) => #[allow(unreachable_code)] val,`
                 let ok_arm = {
                     let val_ident = self.str_to_ident("val");
                     let val_pat = self.pat_ident(e.span, val_ident);
@@ -4453,8 +4452,8 @@
                     self.arm(hir_vec![ok_pat], val_expr)
                 };
 
-                // Err(err) => #[allow(unreachable_code)]
-                //             return Try::from_error(From::from(err)),
+                // `Err(err) => #[allow(unreachable_code)]
+                //              return Try::from_error(From::from(err)),`
                 let err_arm = {
                     let err_ident = self.str_to_ident("err");
                     let err_local = self.pat_ident(e.span, err_ident);
@@ -5014,7 +5013,7 @@
     /// error, depending on the mode.
     fn elided_path_lifetimes(&mut self, span: Span, count: usize) -> P<[hir::Lifetime]> {
         match self.anonymous_lifetime_mode {
-            // NB. We intentionally ignore the create-parameter mode here
+            // N.B., We intentionally ignore the create-parameter mode here
             // and instead "pass through" to resolve-lifetimes, which will then
             // report an error. This is because we don't want to support
             // impl elision for deprecated forms like
diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs
index 1ab1c7d..40904ea 100644
--- a/src/librustc/hir/map/blocks.rs
+++ b/src/librustc/hir/map/blocks.rs
@@ -13,7 +13,7 @@
 //! it captures a common set of attributes that all "function-like
 //! things" (represented by `FnLike` instances) share.  For example,
 //! all `FnLike` instances have a type signature (be it explicit or
-//! inferred).  And all `FnLike` instances have a body, i.e. the code
+//! inferred).  And all `FnLike` instances have a body, i.e., the code
 //! that is run when the function-like thing it represents is invoked.
 //!
 //! With the above abstraction in place, one can treat the program
@@ -34,7 +34,7 @@
 /// More specifically, it is one of either:
 ///
 ///   - A function item,
-///   - A closure expr (i.e. an ExprKind::Closure), or
+///   - A closure expr (i.e., an ExprKind::Closure), or
 ///   - The default implementation for a trait method.
 ///
 /// To construct one, use the `Code::from_node` function.
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index eb9bd18..d5031ef 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -150,10 +150,9 @@
     }
 }
 
-
 /// The definition table containing node definitions.
-/// It holds the DefPathTable for local DefIds/DefPaths and it also stores a
-/// mapping from NodeIds to local DefIds.
+/// It holds the `DefPathTable` for local `DefId`s/`DefPath`s and it also stores a
+/// mapping from `NodeId`s to local `DefId`s.
 #[derive(Clone, Default)]
 pub struct Definitions {
     table: DefPathTable,
diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs
index ac4119d..58d1a78 100644
--- a/src/librustc/hir/map/hir_id_validator.rs
+++ b/src/librustc/hir/map/hir_id_validator.rs
@@ -100,7 +100,7 @@
 
         if max != self.hir_ids_seen.len() - 1 {
             // Collect the missing ItemLocalIds
-            let missing: Vec<_> = (0 .. max as u32 + 1)
+            let missing: Vec<_> = (0 ..= max as u32)
               .filter(|&i| !self.hir_ids_seen.contains_key(&ItemLocalId::from_u32(i)))
               .collect();
 
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index ef777ab..b98e279 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -286,9 +286,7 @@
 
         match node {
             Node::Item(item) => {
-                let def_id = || {
-                    self.local_def_id(item.id)
-                };
+                let def_id = || self.local_def_id(item.id);
 
                 match item.node {
                     ItemKind::Static(_, m, _) => Some(Def::Static(def_id(), m == MutMutable)),
@@ -383,7 +381,7 @@
     pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem {
         self.read(id.node_id);
 
-        // NB: intentionally bypass `self.forest.krate()` so that we
+        // N.B., intentionally bypass `self.forest.krate()` so that we
         // do not trigger a read of the whole krate here
         self.forest.krate.trait_item(id)
     }
@@ -391,7 +389,7 @@
     pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem {
         self.read(id.node_id);
 
-        // NB: intentionally bypass `self.forest.krate()` so that we
+        // N.B., intentionally bypass `self.forest.krate()` so that we
         // do not trigger a read of the whole krate here
         self.forest.krate.impl_item(id)
     }
@@ -399,7 +397,7 @@
     pub fn body(&self, id: BodyId) -> &'hir Body {
         self.read(id.node_id);
 
-        // NB: intentionally bypass `self.forest.krate()` so that we
+        // N.B., intentionally bypass `self.forest.krate()` so that we
         // do not trigger a read of the whole krate here
         self.forest.krate.body(id)
     }
@@ -413,7 +411,7 @@
     }
 
     /// Returns the `NodeId` that corresponds to the definition of
-    /// which this is the body of, i.e. a `fn`, `const` or `static`
+    /// which this is the body of, i.e., a `fn`, `const` or `static`
     /// item (possibly associated), a closure, or a `hir::AnonConst`.
     pub fn body_owner(&self, BodyId { node_id }: BodyId) -> NodeId {
         let parent = self.get_parent_node(node_id);
@@ -475,7 +473,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)),
         }
@@ -484,7 +482,7 @@
     pub fn trait_impls(&self, trait_did: DefId) -> &'hir [NodeId] {
         self.dep_graph.read(DepNode::new_no_params(DepKind::AllLocalTraitImpls));
 
-        // NB: intentionally bypass `self.forest.krate()` so that we
+        // N.B., intentionally bypass `self.forest.krate()` so that we
         // do not trigger a read of the whole krate here
         self.forest.krate.trait_impls.get(&trait_did).map_or(&[], |xs| &xs[..])
     }
@@ -492,7 +490,7 @@
     pub fn trait_auto_impl(&self, trait_did: DefId) -> Option<NodeId> {
         self.dep_graph.read(DepNode::new_no_params(DepKind::AllLocalTraitImpls));
 
-        // NB: intentionally bypass `self.forest.krate()` so that we
+        // N.B., intentionally bypass `self.forest.krate()` so that we
         // do not trigger a read of the whole krate here
         self.forest.krate.trait_auto_impl.get(&trait_did).cloned()
     }
@@ -565,14 +563,14 @@
         result
     }
 
-    /// Similar to get_parent, returns the parent node id or id if there is no
-    /// parent. Note that the parent may be CRATE_NODE_ID, which is not itself
+    /// Similar to `get_parent`; returns the parent node-id, or own `id` if there is
+    /// no parent. Note that the parent may be `CRATE_NODE_ID`, which is not itself
     /// present in the map -- so passing the return value of get_parent_node to
     /// get may actually panic.
     /// This function returns the immediate parent in the AST, whereas get_parent
     /// returns the enclosing item. Note that this might not be the actual parent
     /// node in the AST - some kinds of nodes are not in the map and these will
-    /// never appear as the parent_node. So you can always walk the parent_nodes
+    /// never appear as the parent_node. So you can always walk the `parent_nodes`
     /// from a node to the root of the ast (unless you get the same id back here
     /// that can happen if the id is not in the map itself or is just weird).
     pub fn get_parent_node(&self, id: NodeId) -> NodeId {
@@ -608,7 +606,7 @@
 
     /// If there is some error when walking the parents (e.g., a node does not
     /// have a parent in the map or a node can't be found), then we return the
-    /// last good node id we found. Note that reaching the crate root (id == 0),
+    /// last good node id we found. Note that reaching the crate root (`id == 0`),
     /// is not an error, since items in the crate module have the crate root as
     /// parent.
     fn walk_parent_nodes<F, F2>(&self,
@@ -644,7 +642,7 @@
         }
     }
 
-    /// Retrieve the NodeId for `id`'s enclosing method, unless there's a
+    /// Retrieve the `NodeId` for `id`'s enclosing method, unless there's a
     /// `while` or `loop` before reaching it, as block tail returns are not
     /// available in them.
     ///
@@ -691,7 +689,7 @@
         self.walk_parent_nodes(id, match_fn, match_non_returning_block).ok()
     }
 
-    /// Retrieve the NodeId for `id`'s parent item, or `id` itself if no
+    /// Retrieve the `NodeId` for `id`'s parent item, or `id` itself if no
     /// parent item is in this map. The "parent item" is the closest parent node
     /// in the HIR which is recorded by the map and is an item, either an item
     /// in a module, trait, or impl.
@@ -708,13 +706,13 @@
         }
     }
 
-    /// Returns the DefId of `id`'s nearest module parent, or `id` itself if no
+    /// Returns the `DefId` of `id`'s nearest module parent, or `id` itself if no
     /// module parent is in this map.
     pub fn get_module_parent(&self, id: NodeId) -> DefId {
         self.local_def_id(self.get_module_parent_node(id))
     }
 
-    /// Returns the NodeId of `id`'s nearest module parent, or `id` itself if no
+    /// Returns the `NodeId` of `id`'s nearest module parent, or `id` itself if no
     /// module parent is in this map.
     pub fn get_module_parent_node(&self, id: NodeId) -> NodeId {
         match self.walk_parent_nodes(id, |node| match *node {
@@ -727,7 +725,7 @@
     }
 
     /// Returns the nearest enclosing scope. A scope is an item or block.
-    /// FIXME it is not clear to me that all items qualify as scopes - statics
+    /// FIXME: it is not clear to me that all items qualify as scopes -- statics
     /// and associated types probably shouldn't, for example. Behavior in this
     /// regard should be expected to be highly unstable.
     pub fn get_enclosing_scope(&self, id: NodeId) -> Option<NodeId> {
@@ -1258,8 +1256,8 @@
 }
 
 pub fn describe_def(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<Def> {
-    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-        tcx.hir.describe_def(node_id)
+    if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
+        tcx.hir().describe_def(node_id)
     } else {
         bug!("Calling local describe_def query provider for upstream DefId: {:?}",
              def_id)
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 1674320..156d55b 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// The Rust HIR.
+// HIR datatypes. See the [rustc guide] for more info.
+//!
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
 
 pub use self::BlockCheckMode::*;
 pub use self::CaptureClause::*;
@@ -71,7 +73,7 @@
 
 /// A HirId uniquely identifies a node in the HIR of the current crate. It is
 /// composed of the `owner`, which is the DefIndex of the directly enclosing
-/// hir::Item, hir::TraitItem, or hir::ImplItem (i.e. the closest "item-like"),
+/// hir::Item, hir::TraitItem, or hir::ImplItem (i.e., the closest "item-like"),
 /// and the `local_id` which is unique within the given owner.
 ///
 /// This two-level structure makes for more stable values: One can move an item
@@ -181,7 +183,7 @@
     Plain(Ident),
 
     /// Synthetic name generated when user elided a lifetime in an impl header,
-    /// e.g. the lifetimes in cases like these:
+    /// e.g., the lifetimes in cases like these:
     ///
     ///     impl Foo for &u32
     ///     impl Foo<'_> for u32
@@ -197,7 +199,7 @@
 
     /// Indicates an illegal name was given and an error has been
     /// repored (so we should squelch other derived errors). Occurs
-    /// when e.g. `'_` is used in the wrong place.
+    /// when e.g., `'_` is used in the wrong place.
     Error,
 }
 
@@ -222,7 +224,7 @@
     /// User-given names or fresh (synthetic) names.
     Param(ParamName),
 
-    /// User typed nothing. e.g. the lifetime in `&u32`.
+    /// User typed nothing. e.g., the lifetime in `&u32`.
     Implicit,
 
     /// Indicates an error during lowering (usually `'_` in wrong place)
@@ -311,7 +313,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()
     }
 }
 
@@ -351,7 +353,7 @@
     /// Whether to infer remaining type parameters, if any.
     /// This only applies to expression and pattern paths, and
     /// out of those only the segments with no type parameters
-    /// to begin with, e.g. `Vec::new` is `<Vec<..>>::new::<..>`.
+    /// to begin with, e.g., `Vec::new` is `<Vec<..>>::new::<..>`.
     pub infer_types: bool,
 }
 
@@ -388,7 +390,7 @@
     }
 
     // FIXME: hack required because you can't create a static
-    // GenericArgs, so you can't just return a &GenericArgs.
+    // `GenericArgs`, so you can't just return a `&GenericArgs`.
     pub fn with_generic_args<F, R>(&self, f: F) -> R
         where F: FnOnce(&GenericArgs) -> R
     {
@@ -514,17 +516,17 @@
 
 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
 pub enum LifetimeParamKind {
-    // Indicates that the lifetime definition was explicitly declared, like:
-    // `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`
+    // Indicates that the lifetime definition was explicitly declared (e.g., in
+    // `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`).
     Explicit,
 
     // Indicates that the lifetime definition was synthetically added
-    // as a result of an in-band lifetime usage like:
-    // `fn foo(x: &'a u8) -> &'a u8 { x }`
+    // as a result of an in-band lifetime usage (e.g., in
+    // `fn foo(x: &'a u8) -> &'a u8 { x }`).
     InBand,
 
-    // Indication that the lifetime was elided like both cases here:
-    // `fn foo(x: &u8) -> &'_ u8 { x }`
+    // Indication that the lifetime was elided (e.g., in both cases in
+    // `fn foo(x: &u8) -> &'_ u8 { x }`).
     Elided,
 
     // Indication that the lifetime name was somehow in error.
@@ -533,7 +535,7 @@
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum GenericParamKind {
-    /// A lifetime definition, eg `'a: 'b + 'c + 'd`.
+    /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
     Lifetime {
         kind: LifetimeParamKind,
     },
@@ -637,11 +639,11 @@
 /// A single predicate in a `where` clause
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum WherePredicate {
-    /// A type binding, eg `for<'c> Foo: Send+Clone+'c`
+    /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate),
-    /// A lifetime predicate, e.g. `'a: 'b+'c`
+    /// A lifetime predicate (e.g., `'a: 'b + 'c`).
     RegionPredicate(WhereRegionPredicate),
-    /// An equality predicate (unsupported)
+    /// An equality predicate (unsupported).
     EqPredicate(WhereEqPredicate),
 }
 
@@ -667,7 +669,7 @@
     pub bounds: GenericBounds,
 }
 
-/// A lifetime predicate, e.g. `'a: 'b+'c`
+/// A lifetime predicate, e.g., `'a: 'b+'c`
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct WhereRegionPredicate {
     pub span: Span,
@@ -675,7 +677,7 @@
     pub bounds: GenericBounds,
 }
 
-/// An equality predicate (unsupported), e.g. `T=int`
+/// An equality predicate (unsupported), e.g., `T=int`
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct WhereEqPredicate {
     pub id: NodeId,
@@ -697,7 +699,7 @@
     pub span: Span,
     pub exported_macros: HirVec<MacroDef>,
 
-    // NB: We use a BTreeMap here so that `visit_all_items` iterates
+    // N.B., we use a BTreeMap here so that `visit_all_items` iterates
     // over the ids in increasing order. In principle it should not
     // matter what order we visit things in, but in *practice* it
     // does, because it can affect the order in which errors are
@@ -932,11 +934,11 @@
 
     /// A fresh binding `ref mut binding @ OPT_SUBPATTERN`.
     /// The `NodeId` is the canonical ID for the variable being bound,
-    /// e.g. in `Ok(x) | Err(x)`, both `x` use the same canonical ID,
+    /// e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID,
     /// which is the pattern ID of the first `x`.
     Binding(BindingAnnotation, NodeId, Ident, Option<P<Pat>>),
 
-    /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
+    /// A struct or struct variant pattern, e.g., `Variant {x, y, ..}`.
     /// The `bool` is `true` in the presence of a `..`.
     Struct(QPath, HirVec<Spanned<FieldPat>>, bool),
 
@@ -954,11 +956,11 @@
     Tuple(HirVec<P<Pat>>, Option<usize>),
     /// A `box` pattern
     Box(P<Pat>),
-    /// A reference pattern, e.g. `&mut (a, b)`
+    /// A reference pattern, e.g., `&mut (a, b)`
     Ref(P<Pat>, Mutability),
     /// A literal
     Lit(P<Expr>),
-    /// A range pattern, e.g. `1...2` or `1..2`
+    /// A range pattern, e.g., `1...2` or `1..2`
     Range(P<Expr>, P<Expr>, RangeEnd),
     /// `[a, b, ..i, y, z]` is represented as:
     ///     `PatKind::Slice(box [a, b], Some(i), box [y, z])`
@@ -1319,8 +1321,8 @@
 
 /// A constant (expression) that's not an item or associated item,
 /// but needs its own `DefId` for type-checking, const-eval, etc.
-/// These are usually found nested inside types (e.g. array lengths)
-/// or expressions (e.g. repeat counts), and also used to define
+/// These are usually found nested inside types (e.g., array lengths)
+/// or expressions (e.g., repeat counts), and also used to define
 /// explicit discriminant values for enum variants.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
 pub struct AnonConst {
@@ -1541,12 +1543,12 @@
     /// Path to a definition, optionally "fully-qualified" with a `Self`
     /// type, if the path points to an associated item in a trait.
     ///
-    /// E.g. an unqualified path like `Clone::clone` has `None` for `Self`,
+    /// e.g., an unqualified path like `Clone::clone` has `None` for `Self`,
     /// while `<Vec<T> as Clone>::clone` has `Some(Vec<T>)` for `Self`,
     /// even though they both have the same two-segment `Clone::clone` `Path`.
     Resolved(Option<P<Ty>>, P<Path>),
 
-    /// Type-related paths, e.g. `<T>::default` or `<T>::Output`.
+    /// Type-related paths, e.g., `<T>::default` or `<T>::Output`.
     /// Will be resolved by type-checking to an associated item.
     ///
     /// UFCS source paths can desugar into this, with `Vec::new` turning into
@@ -1633,7 +1635,7 @@
     CaptureByRef,
 }
 
-// NB: If you change this, you'll probably want to change the corresponding
+// N.B., if you change this, you'll probably want to change the corresponding
 // type structure in middle/ty.rs as well.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct MutTy {
@@ -1792,14 +1794,14 @@
     Ptr(MutTy),
     /// A reference (`&'a T` or `&'a mut T`)
     Rptr(Lifetime, MutTy),
-    /// A bare function (e.g. `fn(usize) -> bool`)
+    /// A bare function (e.g., `fn(usize) -> bool`)
     BareFn(P<BareFnTy>),
     /// The never type (`!`)
     Never,
     /// A tuple (`(A, B, C, D,...)`)
     Tup(HirVec<Ty>),
     /// A path to a type definition (`module::module::...::Type`), or an
-    /// associated type, e.g. `<Vec<T> as Trait>::Type` or `<T>::Target`.
+    /// associated type, e.g., `<Vec<T> as Trait>::Type` or `<T>::Target`.
     ///
     /// Type parameters may be stored in each `PathSegment`.
     Path(QPath),
@@ -1814,7 +1816,7 @@
     TraitObject(HirVec<PolyTraitRef>, Lifetime),
     /// Unused for now
     Typeof(AnonConst),
-    /// TyKind::Infer means the type should be inferred instead of it having been
+    /// `TyKind::Infer` means the type should be inferred instead of it having been
     /// specified. This can appear anywhere in a type.
     Infer,
     /// Placeholder for a type that has failed to be defined.
@@ -2017,7 +2019,7 @@
     pub name: Name,
     pub attrs: HirVec<Attribute>,
     pub data: VariantData,
-    /// Explicit discriminant, eg `Foo = 1`
+    /// Explicit discriminant, e.g., `Foo = 1`
     pub disr_expr: Option<AnonConst>,
 }
 
@@ -2025,15 +2027,15 @@
 
 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
 pub enum UseKind {
-    /// One import, e.g. `use foo::bar` or `use foo::bar as baz`.
+    /// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
     /// Also produced for each element of a list `use`, e.g.
     // `use foo::{a, b}` lowers to `use foo::a; use foo::b;`.
     Single,
 
-    /// Glob import, e.g. `use foo::*`.
+    /// Glob import, e.g., `use foo::*`.
     Glob,
 
-    /// Degenerate list import, e.g. `use foo::{a, b}` produces
+    /// Degenerate list import, e.g., `use foo::{a, b}` produces
     /// an additional `use foo::{}` for performing checks such as
     /// unstable feature gating. May be removed in the future.
     ListStem,
@@ -2196,7 +2198,7 @@
 pub enum ItemKind {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
     ///
-    /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
+    /// e.g., `extern crate foo` or `extern crate foo_bar as foo`
     ExternCrate(Option<Name>),
 
     /// `use foo::bar::*;` or `use foo::bar::baz as quux;`
@@ -2218,15 +2220,15 @@
     ForeignMod(ForeignMod),
     /// Module-level inline assembly (from global_asm!)
     GlobalAsm(P<GlobalAsm>),
-    /// A type alias, e.g. `type Foo = Bar<u8>`
+    /// A type alias, e.g., `type Foo = Bar<u8>`
     Ty(P<Ty>, Generics),
-    /// An existential type definition, e.g. `existential type Foo: Bar;`
+    /// An existential type definition, e.g., `existential type Foo: Bar;`
     Existential(ExistTy),
-    /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
+    /// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`
     Enum(EnumDef, Generics),
-    /// A struct definition, e.g. `struct Foo<A> {x: A}`
+    /// A struct definition, e.g., `struct Foo<A> {x: A}`
     Struct(VariantData, Generics),
-    /// A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
+    /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`
     Union(VariantData, Generics),
     /// Represents a Trait Declaration
     Trait(IsAuto, Unsafety, Generics, GenericBounds, HirVec<TraitItemRef>),
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index 8a714a5..d6816d3 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -101,7 +101,7 @@
     }
 
     /// Checks if the pattern contains any patterns that bind something to
-    /// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`.
+    /// an ident, e.g., `foo`, or `Foo(foo)` or `foo @ Bar(..)`.
     pub fn contains_bindings(&self) -> bool {
         let mut contains_bindings = false;
         self.walk(|p| {
@@ -116,7 +116,7 @@
     }
 
     /// Checks if the pattern contains any patterns that bind something to
-    /// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`,
+    /// an ident or wildcard, e.g., `foo`, or `Foo(_)`, `foo @ Bar(..)`,
     pub fn contains_bindings_or_wild(&self) -> bool {
         let mut contains_bindings = false;
         self.walk(|p| {
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 9a0cedd..a24f2fa 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -65,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> {
@@ -1622,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| {
@@ -1636,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| {
@@ -1664,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| {
@@ -2448,8 +2448,8 @@
     }
 }
 
-/// Expressions that syntactically contain an "exterior" struct literal i.e. not surrounded by any
-/// parens or other delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
+/// Expressions that syntactically contain an "exterior" struct literal i.e., not surrounded by any
+/// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
 /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
 fn contains_exterior_struct_lit(value: &hir::Expr) -> bool {
     match value.node {
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index 7c623a1..2e56308 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -45,7 +45,7 @@
 /// This is the context state available during incr. comp. hashing. It contains
 /// enough information to transform DefIds and HirIds into stable DefPaths (i.e.
 /// a reference to the TyCtxt) and it holds a few caches for speeding up various
-/// things (e.g. each DefId/DefPath is only hashed once).
+/// things (e.g., each DefId/DefPath is only hashed once).
 #[derive(Clone)]
 pub struct StableHashingContext<'a> {
     sess: &'a Session,
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index c728871..a46e12b 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -471,6 +471,7 @@
 
 impl_stable_hash_for!(enum mir::ConstraintCategory {
     Return,
+    Yield,
     UseAsConst,
     UseAsStatic,
     TypeAnnotation,
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 439c6e4..3211937 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 {
@@ -269,10 +265,10 @@
                 span.hash_stable(hcx, hasher);
                 hash_token(token, hcx, hasher);
             }
-            tokenstream::TokenTree::Delimited(span, ref delimited) => {
+            tokenstream::TokenTree::Delimited(span, delim, ref tts) => {
                 span.hash_stable(hcx, hasher);
-                std_hash::Hash::hash(&delimited.delim, hasher);
-                for sub_tt in delimited.stream().trees() {
+                std_hash::Hash::hash(&delim, hasher);
+                for sub_tt in tts.stream().trees() {
                     sub_tt.hash_stable(hcx, hasher);
                 }
             }
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index e6a7c20..56da6b7 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -338,7 +338,7 @@
 );
 
 impl_stable_hash_for!(
-    impl<'tcx, M> for enum mir::interpret::AllocType<'tcx, M> [ mir::interpret::AllocType ] {
+    impl<'tcx> for enum mir::interpret::AllocKind<'tcx> [ mir::interpret::AllocKind ] {
         Function(instance),
         Static(def_id),
         Memory(mem),
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/combine.rs b/src/librustc/infer/combine.rs
index f132109..f124623 100644
--- a/src/librustc/infer/combine.rs
+++ b/src/librustc/infer/combine.rs
@@ -371,7 +371,7 @@
         if self.ambient_variance == ty::Variance::Invariant {
             // Avoid fetching the variance if we are in an invariant
             // context; no need, and it can induce dependency cycles
-            // (e.g. #41849).
+            // (e.g., #41849).
             relate::relate_substs(self, None, a_subst, b_subst)
         } else {
             let opt_variances = self.tcx().variances_of(item_def_id);
diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs
index c7b5ddb..27faa45 100644
--- a/src/librustc/infer/equate.rs
+++ b/src/librustc/infer/equate.rs
@@ -47,9 +47,9 @@
                           b_subst: &'tcx Substs<'tcx>)
                           -> RelateResult<'tcx, &'tcx Substs<'tcx>>
     {
-        // NB: Once we are equating types, we don't care about
+        // N.B., once we are equating types, we don't care about
         // variance, so don't try to lookup the variance here. This
-        // also avoids some cycles (e.g. #41849) since looking up
+        // also avoids some cycles (e.g., #41849) since looking up
         // variance requires computing types which can require
         // performing trait matching (which then performs equality
         // unification).
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 59a490f..d213a5c 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -97,7 +97,7 @@
                     )
                 };
                 let span = scope.span(self, region_scope_tree);
-                let tag = match self.hir.find(scope.node_id(self, region_scope_tree)) {
+                let tag = match self.hir().find(scope.node_id(self, region_scope_tree)) {
                     Some(Node::Block(_)) => "block",
                     Some(Node::Expr(expr)) => match expr.node {
                         hir::ExprKind::Call(..) => "call",
@@ -190,8 +190,8 @@
         let cm = self.sess.source_map();
 
         let scope = region.free_region_binding_scope(self);
-        let node = self.hir.as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID);
-        let tag = match self.hir.find(node) {
+        let node = self.hir().as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID);
+        let tag = match self.hir().find(node) {
             Some(Node::Block(_)) | Some(Node::Expr(_)) => "body",
             Some(Node::Item(it)) => Self::item_scope_tag(&it),
             Some(Node::TraitItem(it)) => Self::trait_item_scope_tag(&it),
@@ -200,8 +200,8 @@
         };
         let (prefix, span) = match *region {
             ty::ReEarlyBound(ref br) => {
-                let mut sp = cm.def_span(self.hir.span(node));
-                if let Some(param) = self.hir
+                let mut sp = cm.def_span(self.hir().span(node));
+                if let Some(param) = self.hir()
                     .get_generics(scope)
                     .and_then(|generics| generics.get_named(&br.name))
                 {
@@ -213,8 +213,8 @@
                 bound_region: ty::BoundRegion::BrNamed(_, ref name),
                 ..
             }) => {
-                let mut sp = cm.def_span(self.hir.span(node));
-                if let Some(param) = self.hir
+                let mut sp = cm.def_span(self.hir().span(node));
+                if let Some(param) = self.hir()
                     .get_generics(scope)
                     .and_then(|generics| generics.get_named(&name))
                 {
@@ -225,15 +225,15 @@
             ty::ReFree(ref fr) => match fr.bound_region {
                 ty::BrAnon(idx) => (
                     format!("the anonymous lifetime #{} defined on", idx + 1),
-                    self.hir.span(node),
+                    self.hir().span(node),
                 ),
                 ty::BrFresh(_) => (
                     "an anonymous lifetime defined on".to_owned(),
-                    self.hir.span(node),
+                    self.hir().span(node),
                 ),
                 _ => (
                     format!("the lifetime {} as defined on", fr.bound_region),
-                    cm.def_span(self.hir.span(node)),
+                    cm.def_span(self.hir().span(node)),
                 ),
             },
             _ => bug!(),
@@ -1083,7 +1083,7 @@
                     // the expected type argument.
                     if !param.is_self() {
                         let type_param = generics.type_param(param, self.tcx);
-                        let hir = &self.tcx.hir;
+                        let hir = &self.tcx.hir();
                         hir.as_local_node_id(type_param.def_id).map(|id| {
                             // Get the `hir::Param` to verify whether it already has any bounds.
                             // We do this to avoid suggesting code that ends up as `T: 'a'b`,
@@ -1095,7 +1095,8 @@
                             let sp = hir.span(id);
                             // `sp` only covers `T`, change it so that it covers
                             // `T:` when appropriate
-                            let sp = if has_bounds {
+                            let is_impl_trait = bound_kind.to_string().starts_with("impl ");
+                            let sp = if has_bounds && !is_impl_trait {
                                 sp.to(self.tcx
                                     .sess
                                     .source_map()
@@ -1103,7 +1104,7 @@
                             } else {
                                 sp
                             };
-                            (sp, has_bounds)
+                            (sp, has_bounds, is_impl_trait)
                         })
                     } else {
                         None
@@ -1136,25 +1137,33 @@
 
         fn binding_suggestion<'tcx, S: fmt::Display>(
             err: &mut DiagnosticBuilder<'tcx>,
-            type_param_span: Option<(Span, bool)>,
+            type_param_span: Option<(Span, bool, bool)>,
             bound_kind: GenericKind<'tcx>,
             sub: S,
         ) {
-            let consider = &format!(
-                "consider adding an explicit lifetime bound `{}: {}`...",
-                bound_kind, sub
+            let consider = format!(
+                "consider adding an explicit lifetime bound {}",
+                if type_param_span.map(|(_, _, is_impl_trait)| is_impl_trait).unwrap_or(false) {
+                    format!(" `{}` to `{}`...", sub, bound_kind)
+                } else {
+                    format!("`{}: {}`...", bound_kind, sub)
+                },
             );
-            if let Some((sp, has_lifetimes)) = type_param_span {
-                let tail = if has_lifetimes { " + " } else { "" };
-                let suggestion = format!("{}: {}{}", bound_kind, sub, tail);
+            if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span {
+                let suggestion = if is_impl_trait {
+                    format!("{} + {}", bound_kind, sub)
+                } else {
+                    let tail = if has_lifetimes { " + " } else { "" };
+                    format!("{}: {}{}", bound_kind, sub, tail)
+                };
                 err.span_suggestion_short_with_applicability(
                     sp,
-                    consider,
+                    &consider,
                     suggestion,
                     Applicability::MaybeIncorrect, // Issue #41966
                 );
             } else {
-                err.help(consider);
+                err.help(&consider);
             }
         }
 
@@ -1315,8 +1324,8 @@
                 format!(" for lifetime parameter `{}` in coherence check", name)
             }
             infer::UpvarRegion(ref upvar_id, _) => {
-                let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_path.hir_id);
-                let var_name = self.tcx.hir.name(var_node_id);
+                let var_node_id = self.tcx.hir().hir_to_node_id(upvar_id.var_path.hir_id);
+                let var_name = self.tcx.hir().name(var_node_id);
                 format!(" for capture of `{}` by closure", var_name)
             }
             infer::NLL(..) => bug!("NLL variable found in lexical phase"),
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index efb3162..4064df0 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -109,13 +109,13 @@
         let mut local_visitor = FindLocalByTypeVisitor {
             infcx: &self,
             target_ty: &ty,
-            hir_map: &self.tcx.hir,
+            hir_map: &self.tcx.hir(),
             found_local_pattern: None,
             found_arg_pattern: None,
         };
 
         if let Some(body_id) = body_id {
-            let expr = self.tcx.hir.expect_expr(body_id.node_id);
+            let expr = self.tcx.hir().expect_expr(body_id.node_id);
             local_visitor.visit_expr(expr);
         }
 
diff --git a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
index 10a2d17..df0dcbe 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -30,7 +30,7 @@
     ///    { x.push(y); }
     /// ```
     /// The function returns the nested type corresponding to the anonymous region
-    /// for e.g. `&u8` and Vec<`&u8`.
+    /// for e.g., `&u8` and Vec<`&u8`.
     pub(super) fn find_anon_type(
         &self,
         region: Region<'tcx>,
@@ -38,8 +38,8 @@
     ) -> Option<(&hir::Ty, &hir::FnDecl)> {
         if let Some(anon_reg) = self.tcx.is_suitable_region(region) {
             let def_id = anon_reg.def_id;
-            if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
-                let fndecl = match self.tcx.hir.get(node_id) {
+            if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
+                let fndecl = match self.tcx.hir().get(node_id) {
                     Node::Item(&hir::Item {
                         node: hir::ItemKind::Fn(ref fndecl, ..),
                         ..
@@ -97,14 +97,14 @@
     // associated with the anonymous region we are looking for.
     bound_region: ty::BoundRegion,
     // The type where the anonymous lifetime appears
-    // for e.g. Vec<`&u8`> and <`&u8`>
+    // for e.g., Vec<`&u8`> and <`&u8`>
     found_type: Option<&'gcx hir::Ty>,
     current_index: ty::DebruijnIndex,
 }
 
 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_ty(&mut self, arg: &'gcx hir::Ty) {
@@ -124,7 +124,7 @@
 
             hir::TyKind::Rptr(ref lifetime, _) => {
                 // the lifetime of the TyRptr
-                let hir_id = self.tcx.hir.node_to_hir_id(lifetime.id);
+                let hir_id = self.tcx.hir().node_to_hir_id(lifetime.id);
                 match (self.tcx.named_region(hir_id), self.bound_region) {
                     // Find the index of the anonymous region that was part of the
                     // error. We will then search the function parameters for a bound
@@ -150,7 +150,7 @@
                     // region at the right depth with the same index
                     (Some(rl::Region::EarlyBound(_, id, _)), ty::BrNamed(def_id, _)) => {
                         debug!(
-                            "EarlyBound self.infcx.tcx.hir.local_def_id(id)={:?} \
+                            "EarlyBound self.infcx.tcx.hir().local_def_id(id)={:?} \
                              def_id={:?}",
                             id,
                             def_id
@@ -172,7 +172,7 @@
                             "FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}",
                             debruijn_index
                         );
-                        debug!("self.infcx.tcx.hir.local_def_id(id)={:?}", id);
+                        debug!("self.infcx.tcx.hir().local_def_id(id)={:?}", id);
                         debug!("def_id={:?}", def_id);
                         if debruijn_index == self.current_index && id == def_id {
                             self.found_type = Some(arg);
@@ -227,11 +227,11 @@
 
 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) {
-        let hir_id = self.tcx.hir.node_to_hir_id(lifetime.id);
+        let hir_id = self.tcx.hir().node_to_hir_id(lifetime.id);
         match (self.tcx.named_region(hir_id), self.bound_region) {
             // the lifetime of the TyPath!
             (Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)), ty::BrAnon(br_index)) => {
@@ -243,7 +243,7 @@
 
             (Some(rl::Region::EarlyBound(_, id, _)), ty::BrNamed(def_id, _)) => {
                 debug!(
-                    "EarlyBound self.infcx.tcx.hir.local_def_id(id)={:?} \
+                    "EarlyBound self.infcx.tcx.hir().local_def_id(id)={:?} \
                      def_id={:?}",
                     id,
                     def_id
diff --git a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs
index 7a92b30..4c3fbc7 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs
@@ -56,7 +56,7 @@
             // closure, provide a specific message pointing this out.
             if let (&SubregionOrigin::BindingTypeIsNotValidAtDecl(ref external_span),
                     &RegionKind::ReFree(ref free_region)) = (&sub_origin, sup_region) {
-                let hir = &self.tcx.hir;
+                let hir = &self.tcx.hir();
                 if let Some(node_id) = hir.as_local_node_id(free_region.scope) {
                     if let Node::Expr(Expr {
                         node: Closure(_, _, _, closure_span, None),
diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs
index 013c02f..e5c2c75 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs
@@ -60,7 +60,7 @@
             _ => return None, // not a free region
         };
 
-        let hir = &self.tcx.hir;
+        let hir = &self.tcx.hir();
         if let Some(node_id) = hir.as_local_node_id(id) {
             if let Some(body_id) = hir.maybe_body_owned_by(node_id) {
                 let body = hir.body(body_id);
diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs
index a539c32..f5ac39a 100644
--- a/src/librustc/infer/error_reporting/note.rs
+++ b/src/librustc/infer/error_reporting/note.rs
@@ -41,8 +41,8 @@
                               "...so that reference does not outlive borrowed content");
             }
             infer::ReborrowUpvar(span, ref upvar_id) => {
-                let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_path.hir_id);
-                let var_name = self.tcx.hir.name(var_node_id);
+                let var_node_id = self.tcx.hir().hir_to_node_id(upvar_id.var_path.hir_id);
+                let var_name = self.tcx.hir().name(var_node_id);
                 err.span_note(span,
                               &format!("...so that closure can access `{}`", var_name));
             }
@@ -61,7 +61,7 @@
                 err.span_note(span,
                               &format!("...so that captured variable `{}` does not outlive the \
                                         enclosing closure",
-                                       self.tcx.hir.name(id)));
+                                       self.tcx.hir().name(id)));
             }
             infer::IndexSlice(span) => {
                 err.span_note(span, "...so that slice is not indexed outside the lifetime");
@@ -174,8 +174,8 @@
                 err
             }
             infer::ReborrowUpvar(span, ref upvar_id) => {
-                let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_path.hir_id);
-                let var_name = self.tcx.hir.name(var_node_id);
+                let var_node_id = self.tcx.hir().hir_to_node_id(upvar_id.var_path.hir_id);
+                let var_name = self.tcx.hir().name(var_node_id);
                 let mut err = struct_span_err!(self.tcx.sess,
                                                span,
                                                E0313,
@@ -232,7 +232,7 @@
                                                E0474,
                                                "captured variable `{}` does not outlive the \
                                                 enclosing closure",
-                                               self.tcx.hir.name(id));
+                                               self.tcx.hir().name(id));
                 self.tcx.note_and_explain_region(region_scope_tree, &mut err,
                     "captured variable is valid for ", sup, "");
                 self.tcx.note_and_explain_region(region_scope_tree, &mut err,
diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs
index cf91b85..c8cd11c 100644
--- a/src/librustc/infer/higher_ranked/mod.rs
+++ b/src/librustc/infer/higher_ranked/mod.rs
@@ -542,7 +542,7 @@
     /// Pops the placeholder regions found in `placeholder_map` from the region
     /// inference context. Whenever you create placeholder regions via
     /// `replace_bound_vars_with_placeholders`, they must be popped before you
-    /// commit the enclosing snapshot (if you do not commit, e.g. within a
+    /// commit the enclosing snapshot (if you do not commit, e.g., within a
     /// probe or as a result of an error, then this is not necessary, as
     /// popping happens as part of the rollback).
     ///
diff --git a/src/librustc/infer/lexical_region_resolve/graphviz.rs b/src/librustc/infer/lexical_region_resolve/graphviz.rs
index a210d63..512e57d 100644
--- a/src/librustc/infer/lexical_region_resolve/graphviz.rs
+++ b/src/librustc/infer/lexical_region_resolve/graphviz.rs
@@ -31,9 +31,8 @@
 use std::collections::hash_map::Entry::Vacant;
 use std::collections::btree_map::BTreeMap;
 use std::env;
-use std::fs::File;
+use std::fs;
 use std::io;
-use std::io::prelude::*;
 use std::sync::atomic::{AtomicBool, Ordering};
 
 fn print_help_message() {
@@ -268,5 +267,5 @@
     debug!("dump_region_data calling render");
     let mut v = Vec::new();
     dot::render(&g, &mut v).unwrap();
-    File::create(path).and_then(|mut f| f.write_all(&v))
+    fs::write(path, &v)
 }
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index d8beae45..b1a1335 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -219,7 +219,7 @@
     /// `UniverseIndex::root()` but grows from there as we enter
     /// universal quantifiers.
     ///
-    /// NB: At present, we exclude the universal quantifiers on the
+    /// N.B., at present, we exclude the universal quantifiers on the
     /// item we are type-checking, and just consider those names as
     /// part of the root universe. So this would only get incremented
     /// when we enter into a higher-ranked (`for<..>`) type or trait
@@ -732,7 +732,7 @@
             region_obligations_snapshot: self.region_obligations.borrow().len(),
             universe: self.universe(),
             was_in_snapshot: in_snapshot,
-            // Borrow tables "in progress" (i.e. during typeck)
+            // Borrow tables "in progress" (i.e., during typeck)
             // to ban writes from within a snapshot to them.
             _in_progress_tables: self.in_progress_tables.map(|tables| tables.borrow()),
         }
@@ -1047,7 +1047,7 @@
                 // type parameter definition. The substitutions are
                 // for actual parameters that may be referred to by
                 // the default of this type parameter, if it exists.
-                // E.g. `struct Foo<A, B, C = (A, B)>(...);` when
+                // e.g., `struct Foo<A, B, C = (A, B)>(...);` when
                 // used in a path such as `Foo::<T, U>::new()` will
                 // use an inference variable for `C` with `[T, U]`
                 // as the substitutions for the default, `(T, U)`.
@@ -1261,7 +1261,7 @@
          * Where possible, replaces type/int/float variables in
          * `value` with their final value. Note that region variables
          * are unaffected. If a type variable has not been unified, it
-         * is left as is.  This is an idempotent operation that does
+         * is left as is. This is an idempotent operation that does
          * not affect inference state in any way and so you can do it
          * at will.
          */
@@ -1298,7 +1298,7 @@
         /*!
          * Attempts to resolve all type/region variables in
          * `value`. Region inference must have been run already (e.g.,
-         * by calling `resolve_regions_and_report_errors`).  If some
+         * by calling `resolve_regions_and_report_errors`). If some
          * variable was never unified, an `Err` results.
          *
          * This method is idempotent, but it not typically not invoked
@@ -1331,7 +1331,7 @@
         let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
         debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
 
-        // Don't report an error if actual type is Error.
+        // Don't report an error if actual type is `Error`.
         if actual_ty.references_error() {
             return self.tcx.sess.diagnostic().struct_dummy();
         }
diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs
index 972ba16..773c712 100644
--- a/src/librustc/infer/nll_relate/mod.rs
+++ b/src/librustc/infer/nll_relate/mod.rs
@@ -15,7 +15,7 @@
 //!
 //! Here are the key differences:
 //!
-//! - This code may choose to bypass some checks (e.g. the occurs check)
+//! - 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.
@@ -97,7 +97,7 @@
     /// region that is instantiated existentially. This creates an
     /// inference variable, typically.
     ///
-    /// So e.g. if you have `for<'a> fn(..) <: for<'b> fn(..)`, then
+    /// So e.g., if you have `for<'a> fn(..) <: for<'b> fn(..)`, then
     /// we will invoke this method to instantiate `'a` with an
     /// inference variable (though `'b` would be instantiated first,
     /// as a placeholder).
@@ -107,7 +107,7 @@
     /// higher-ranked region that is instantiated universally.
     /// This creates a new region placeholder, typically.
     ///
-    /// So e.g. if you have `for<'a> fn(..) <: for<'b> fn(..)`, then
+    /// So e.g., if you have `for<'a> fn(..) <: for<'b> fn(..)`, then
     /// we will invoke this method to instantiate `'b` with a
     /// placeholder region.
     fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx>;
diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs
index fda9817..44c5fe5 100644
--- a/src/librustc/infer/opaque_types/mod.rs
+++ b/src/librustc/infer/opaque_types/mod.rs
@@ -691,13 +691,13 @@
                     //     let x = || foo(); // returns the Opaque assoc with `foo`
                     // }
                     // ```
-                    if let Some(opaque_node_id) = tcx.hir.as_local_node_id(def_id) {
+                    if let Some(opaque_node_id) = tcx.hir().as_local_node_id(def_id) {
                         let parent_def_id = self.parent_def_id;
                         let def_scope_default = || {
-                            let opaque_parent_node_id = tcx.hir.get_parent(opaque_node_id);
-                            parent_def_id == tcx.hir.local_def_id(opaque_parent_node_id)
+                            let opaque_parent_node_id = tcx.hir().get_parent(opaque_node_id);
+                            parent_def_id == tcx.hir().local_def_id(opaque_parent_node_id)
                         };
-                        let in_definition_scope = match tcx.hir.find(opaque_node_id) {
+                        let in_definition_scope = match tcx.hir().find(opaque_node_id) {
                             Some(Node::Item(item)) => match item.node {
                                 // impl trait
                                 hir::ItemKind::Existential(hir::ExistTy {
@@ -725,7 +725,7 @@
                             },
                             _ => bug!(
                                 "expected (impl) item, found {}",
-                                tcx.hir.node_to_string(opaque_node_id),
+                                tcx.hir().node_to_string(opaque_node_id),
                             ),
                         };
                         if in_definition_scope {
@@ -761,7 +761,7 @@
         );
 
         // Use the same type variable if the exact same Opaque appears more
-        // than once in the return type (e.g. if it's passed to a type alias).
+        // than once in the return type (e.g., if it's passed to a type alias).
         if let Some(opaque_defn) = self.opaque_types.get(&def_id) {
             return opaque_defn.concrete_ty;
         }
@@ -783,7 +783,7 @@
         );
 
         // make sure that we are in fact defining the *entire* type
-        // e.g. `existential type Foo<T: Bound>: Bar;` needs to be
+        // e.g., `existential type Foo<T: Bound>: Bar;` needs to be
         // defined by a function like `fn foo<T: Bound>() -> Foo<T>`.
         debug!(
             "instantiate_opaque_types: param_env: {:#?}",
@@ -848,16 +848,16 @@
     opaque_node_id: ast::NodeId,
 ) -> bool {
     let mut node_id = tcx
-        .hir
+        .hir()
         .as_local_node_id(def_id)
         .unwrap();
     // named existential types can be defined by any siblings or
     // children of siblings
-    let mod_id = tcx.hir.get_parent(opaque_node_id);
+    let mod_id = tcx.hir().get_parent(opaque_node_id);
     // so we walk up the node tree until we hit the root or the parent
     // of the opaque type
     while node_id != mod_id && node_id != ast::CRATE_NODE_ID {
-        node_id = tcx.hir.get_parent(node_id);
+        node_id = tcx.hir().get_parent(node_id);
     }
     // syntactically we are allowed to define the concrete type
     node_id == mod_id
diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs
index 502a582..7b21a69 100644
--- a/src/librustc/infer/outlives/obligations.rs
+++ b/src/librustc/infer/outlives/obligations.rs
@@ -408,7 +408,7 @@
 
         // Remove outlives bounds that we get from the environment but
         // which are also deducable from the trait. This arises (cc
-        // #55756) in cases where you have e.g. `<T as Foo<'a>>::Item:
+        // #55756) in cases where you have e.g., `<T as Foo<'a>>::Item:
         // 'a` in the environment but `trait Foo<'b> { type Item: 'b
         // }` in the trait definition.
         approx_env_bounds.retain(|bound| {
diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs
index af1b696..9cac73d 100644
--- a/src/librustc/infer/region_constraints/mod.rs
+++ b/src/librustc/infer/region_constraints/mod.rs
@@ -60,7 +60,7 @@
     /// which can never be rolled back.
     undo_log: Vec<UndoLog<'tcx>>,
 
-    /// The number of open snapshots, i.e. those that haven't been committed or
+    /// The number of open snapshots, i.e., those that haven't been committed or
     /// rolled back.
     num_open_snapshots: usize,
 
@@ -607,7 +607,7 @@
 
         // never overwrite an existing (constraint, origin) - only insert one if it isn't
         // present in the map yet. This prevents origins from outside the snapshot being
-        // replaced with "less informative" origins e.g. during calls to `can_eq`
+        // replaced with "less informative" origins e.g., during calls to `can_eq`
         let in_snapshot = self.in_snapshot();
         let undo_log = &mut self.undo_log;
         self.data.constraints.entry(constraint).or_insert_with(|| {
diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs
index 5624961..b7aac23 100644
--- a/src/librustc/infer/type_variable.rs
+++ b/src/librustc/infer/type_variable.rs
@@ -175,7 +175,7 @@
     /// Creates a new type variable.
     ///
     /// - `diverging`: indicates if this is a "diverging" type
-    ///   variable, e.g.  one created as the type of a `return`
+    ///   variable, e.g.,  one created as the type of a `return`
     ///   expression. The code in this module doesn't care if a
     ///   variable is diverging, but the main Rust type-checker will
     ///   sometimes "unify" such variables with the `!` or `()` types.
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index ddb0c5b..4324cfc 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -119,7 +119,7 @@
 #[macro_use]
 mod macros;
 
-// NB: This module needs to be declared first so diagnostics are
+// N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
 pub mod diagnostics;
 
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 22f2023..b7759a8 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -174,7 +174,7 @@
 declare_lint! {
     pub LEGACY_DIRECTORY_OWNERSHIP,
     Deny,
-    "non-inline, non-`#[path]` modules (e.g. `mod foo;`) were erroneously allowed in some files \
+    "non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \
      not named `mod.rs`"
 }
 
@@ -366,7 +366,7 @@
 }
 
 /// Does nothing as a lint pass, but registers some `Lint`s
-/// which are used by other parts of the compiler.
+/// that are used by other parts of the compiler.
 #[derive(Copy, Clone)]
 pub struct HardwiredLints;
 
@@ -463,7 +463,7 @@
                     Ok(ref s) => {
                         // FIXME(Manishearth) ideally the emitting code
                         // can tell us whether or not this is global
-                        let opt_colon = if s.trim_left().starts_with("::") {
+                        let opt_colon = if s.trim_start().starts_with("::") {
                             ""
                         } else {
                             "::"
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 469d774..449f8e0 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -774,7 +774,7 @@
         where F: FnOnce(&mut Self),
     {
         let old_param_env = self.param_env;
-        self.param_env = self.tcx.param_env(self.tcx.hir.local_def_id(id));
+        self.param_env = self.tcx.param_env(self.tcx.hir().local_def_id(id));
         f(self);
         self.param_env = old_param_env;
     }
@@ -797,13 +797,13 @@
     /// items in the context of the outer item, so enable
     /// deep-walking.
     fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'tcx> {
-        hir_visit::NestedVisitorMap::All(&self.tcx.hir)
+        hir_visit::NestedVisitorMap::All(&self.tcx.hir())
     }
 
     fn visit_nested_body(&mut self, body: hir::BodyId) {
         let old_tables = self.tables;
         self.tables = self.tcx.body_tables(body);
-        let body = self.tcx.hir.body(body);
+        let body = self.tcx.hir().body(body);
         self.visit_body(body);
         self.tables = old_tables;
     }
@@ -866,7 +866,7 @@
         // in order for `check_fn` to be able to use them.
         let old_tables = self.tables;
         self.tables = self.tcx.body_tables(body_id);
-        let body = self.tcx.hir.body(body_id);
+        let body = self.tcx.hir().body(body_id);
         run_lints!(self, check_fn, fk, decl, body, span, id);
         hir_visit::walk_fn(self, fk, decl, body_id, span, id);
         run_lints!(self, check_fn_post, fk, decl, body, span, id);
@@ -1191,7 +1191,7 @@
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
 
-    let krate = tcx.hir.krate();
+    let krate = tcx.hir().krate();
     let passes = tcx.sess.lint_store.borrow_mut().late_passes.take();
 
     let passes = {
@@ -1270,7 +1270,7 @@
     //
     // Rustdoc runs everybody-loops before the early lints and removes
     // function bodies, so it's totally possible for linted
-    // node ids to not exist (e.g. macros defined within functions for the
+    // node ids to not exist (e.g., macros defined within functions for the
     // unused_macro lint) anymore. So we only run this check
     // when we're not in rustdoc mode. (see issue #47639)
     if !sess.opts.actually_rustdoc {
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index cfb9f04..06e3e0b 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -66,7 +66,7 @@
         for &(ref lint_name, level) in &sess.opts.lint_opts {
             store.check_lint_name_cmdline(sess, &lint_name, level);
 
-            // If the cap is less than this specified level, e.g. if we've got
+            // If the cap is less than this specified level, e.g., if we've got
             // `--cap-lints allow` but we've also got `-D foo` then we ignore
             // this specification as the lint cap will set it to allow anyway.
             let level = cmp::min(level, self.lint_cap);
@@ -191,7 +191,7 @@
     /// * It'll validate all lint-related attributes in `attrs`
     /// * It'll mark all lint-related attributes as used
     /// * Lint levels will be updated based on the attributes provided
-    /// * Lint attributes are validated, e.g. a #[forbid] can't be switched to
+    /// * Lint attributes are validated, e.g., a #[forbid] can't be switched to
     ///   #[allow]
     ///
     /// Don't forget to call `pop`!
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 4b878b8..7a8aa7e 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -67,7 +67,7 @@
     /// `declare_lint!()` invocations to follow the convention of upper-case
     /// statics without repeating the name.
     ///
-    /// The name is written with underscores, e.g. "unused_imports".
+    /// The name is written with underscores, e.g., "unused_imports".
     /// On the command line, underscores become dashes.
     pub name: &'static str,
 
@@ -76,7 +76,7 @@
 
     /// Description of the lint or the issue it detects.
     ///
-    /// e.g. "imports that are never used"
+    /// e.g., "imports that are never used"
     pub desc: &'static str,
 
     /// Starting at the given edition, default to the given lint level. If this is `None`, then use
@@ -173,7 +173,7 @@
 pub trait LintPass {
     /// Get descriptions of the lints this `LintPass` object can emit.
     ///
-    /// NB: there is no enforcement that the object only emits lints it registered.
+    /// N.B., there is no enforcement that the object only emits lints it registered.
     /// And some `rustc` internal `LintPass`es register lints to be emitted by other
     /// parts of the compiler. If you want enforced access restrictions for your
     /// `Lint`, make it a private `static` item in its own module.
@@ -643,7 +643,7 @@
         levels: LintLevelSets::builder(tcx.sess),
         tcx: tcx,
     };
-    let krate = tcx.hir.krate();
+    let krate = tcx.hir().krate();
 
     builder.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |builder| {
         intravisit::walk_crate(builder, krate);
@@ -665,7 +665,7 @@
         where F: FnOnce(&mut Self)
     {
         let push = self.levels.push(attrs);
-        self.levels.register_id(self.tcx.hir.definitions().node_to_hir_id(id));
+        self.levels.register_id(self.tcx.hir().definitions().node_to_hir_id(id));
         f(self);
         self.levels.pop(push);
     }
@@ -673,7 +673,7 @@
 
 impl<'a, 'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
-        intravisit::NestedVisitorMap::All(&self.tcx.hir)
+        intravisit::NestedVisitorMap::All(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, it: &'tcx hir::Item) {
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 4720bb2..c7f9351 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -59,7 +59,7 @@
     /// A dependency that is only used for its macros.
     MacrosOnly,
     /// A dependency that is always injected into the dependency list and so
-    /// doesn't need to be linked to an rlib, e.g. the injected allocator.
+    /// doesn't need to be linked to an rlib, e.g., the injected allocator.
     Implicit,
     /// A dependency that is required by an rlib version of this crate.
     /// Ordinary `extern crate`s result in `Explicit` dependencies.
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index bb7a6a6..934d7c1 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -35,7 +35,7 @@
 // may need to be marked as live.
 fn should_explore<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             node_id: ast::NodeId) -> bool {
-    match tcx.hir.find(node_id) {
+    match tcx.hir().find(node_id) {
         Some(Node::Item(..)) |
         Some(Node::ImplItem(..)) |
         Some(Node::ForeignItem(..)) |
@@ -59,7 +59,7 @@
 
 impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
     fn check_def_id(&mut self, def_id: DefId) {
-        if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
+        if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
             if should_explore(self.tcx, node_id) {
                 self.worklist.push(node_id);
             }
@@ -68,7 +68,7 @@
     }
 
     fn insert_def_id(&mut self, def_id: DefId) {
-        if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
+        if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
             debug_assert!(!should_explore(self.tcx, node_id));
             self.live_symbols.insert(node_id);
         }
@@ -137,7 +137,7 @@
                 continue
             }
 
-            if let Some(ref node) = self.tcx.hir.find(id) {
+            if let Some(ref node) = self.tcx.hir().find(id) {
                 self.live_symbols.insert(id);
                 self.visit_node(node);
             }
@@ -153,7 +153,7 @@
             Node::Item(item) => {
                 match item.node {
                     hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
-                        let def_id = self.tcx.hir.local_def_id(item.id);
+                        let def_id = self.tcx.hir().local_def_id(item.id);
                         let def = self.tcx.adt_def(def_id);
                         self.repr_has_repr_c = def.repr.c();
 
@@ -206,7 +206,7 @@
     fn visit_nested_body(&mut self, body: hir::BodyId) {
         let old_tables = self.tables;
         self.tables = self.tcx.body_tables(body);
-        let body = self.tcx.hir.body(body);
+        let body = self.tcx.hir().body(body);
         self.visit_body(body);
         self.tables = old_tables;
     }
@@ -307,11 +307,11 @@
         return true;
     }
 
-    let def_id = tcx.hir.local_def_id(id);
+    let def_id = tcx.hir().local_def_id(id);
     let cg_attrs = tcx.codegen_fn_attrs(def_id);
 
     // #[used], #[no_mangle], #[export_name], etc also keeps the item alive
-    // forcefully, e.g. for placing it in a specific section.
+    // forcefully, e.g., for placing it in a specific section.
     if cg_attrs.contains_extern_indicator() ||
         cg_attrs.flags.contains(CodegenFnAttrFlags::USED) {
         return true;
@@ -469,7 +469,7 @@
     }
 
     fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
-        let field_type = self.tcx.type_of(self.tcx.hir.local_def_id(field.id));
+        let field_type = self.tcx.type_of(self.tcx.hir().local_def_id(field.id));
         !field.is_positional()
             && !self.symbol_is_live(field.id, None)
             && !field_type.is_phantom_data()
@@ -510,11 +510,11 @@
         // This is done to handle the case where, for example, the static
         // method of a private type is used, but the type itself is never
         // called directly.
-        let def_id = self.tcx.hir.local_def_id(id);
+        let def_id = self.tcx.hir().local_def_id(id);
         let inherent_impls = self.tcx.inherent_impls(def_id);
         for &impl_did in inherent_impls.iter() {
             for &item_did in &self.tcx.associated_item_def_ids(impl_did)[..] {
-                if let Some(item_node_id) = self.tcx.hir.as_local_node_id(item_did) {
+                if let Some(item_node_id) = self.tcx.hir().as_local_node_id(item_did) {
                     if self.live_symbols.contains(&item_node_id) {
                         return true;
                     }
@@ -547,7 +547,7 @@
     /// an error. We could do this also by checking the parents, but
     /// this is how the code is setup and it seems harmless enough.
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.tcx.hir)
+        NestedVisitorMap::All(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
@@ -648,7 +648,7 @@
 
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
-    let krate = tcx.hir.krate();
+    let krate = tcx.hir().krate();
     let live_symbols = find_live(tcx, access_levels, krate);
     let mut visitor = DeadVisitor {
         tcx,
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index 549a848..5e75f11 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -201,7 +201,7 @@
     // static libraries.
     //
     // If the crate hasn't been included yet and it's not actually required
-    // (e.g. it's an allocator) then we skip it here as well.
+    // (e.g., it's an allocator) then we skip it here as well.
     for &cnum in tcx.crates().iter() {
         let src = tcx.used_crate_source(cnum);
         if src.dylib.is_none() &&
@@ -306,7 +306,7 @@
 
 // Given a list of how to link upstream dependencies so far, ensure that an
 // injected dependency is activated. This will not do anything if one was
-// transitively included already (e.g. via a dylib or explicitly so).
+// transitively included already (e.g., via a dylib or explicitly so).
 //
 // If an injected dependency was not found then we're guaranteed the
 // metadata::creader module has injected that dependency (not listed as
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 93fe607..60ddf60 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -87,7 +87,7 @@
     configure_main(&mut ctxt, crate_name);
 }
 
-// Beware, this is duplicated in libsyntax/entry.rs, make sure to keep
+// Beware, this is duplicated in `libsyntax/entry.rs`, so make sure to keep
 // them in sync.
 fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
     match item.node {
@@ -98,7 +98,7 @@
                 EntryPointType::MainAttr
             } else if item.name == "main" {
                 if at_root {
-                    // This is a top-level function so can be 'main'
+                    // This is a top-level function so can be 'main'.
                     EntryPointType::MainNamed
                 } else {
                     EntryPointType::OtherMain
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 5b92bfe..f1bc37d 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -622,7 +622,7 @@
         match local.init {
             None => {
                 local.pat.each_binding(|_, hir_id, span, _| {
-                    let node_id = self.mc.tcx.hir.hir_to_node_id(hir_id);
+                    let node_id = self.mc.tcx.hir().hir_to_node_id(hir_id);
                     self.delegate.decl_without_init(node_id, span);
                 })
             }
@@ -813,7 +813,7 @@
         self.consume_expr(&arm.body);
     }
 
-    /// Walks a pat that occurs in isolation (i.e. top-level of fn
+    /// Walks a pat that occurs in isolation (i.e., top-level of fn
     /// arg or let binding.  *Not* a match arm or nested pat.)
     fn walk_irrefutable_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat) {
         let mut mode = Unknown;
@@ -851,7 +851,7 @@
     }
 
     /// The core driver for walking a pattern; `match_mode` must be
-    /// established up front, e.g. via `determine_pat_move_mode` (see
+    /// established up front, e.g., via `determine_pat_move_mode` (see
     /// also `walk_irrefutable_pat` for patterns that stand alone).
     fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
         debug!("walk_pat(cmt_discr={:?}, pat={:?})", cmt_discr, pat);
@@ -935,8 +935,8 @@
 
         self.tcx().with_freevars(closure_expr.id, |freevars| {
             for freevar in freevars {
-                let var_hir_id = self.tcx().hir.node_to_hir_id(freevar.var_id());
-                let closure_def_id = self.tcx().hir.local_def_id(closure_expr.id);
+                let var_hir_id = self.tcx().hir().node_to_hir_id(freevar.var_id());
+                let closure_def_id = self.tcx().hir().local_def_id(closure_expr.id);
                 let upvar_id = ty::UpvarId {
                     var_path: ty::UpvarPath { hir_id: var_hir_id },
                     closure_expr_id: closure_def_id.to_local(),
@@ -973,7 +973,7 @@
                         -> mc::McResult<mc::cmt_<'tcx>> {
         // Create the cmt for the variable being borrowed, from the
         // caller's perspective
-        let var_hir_id = self.tcx().hir.node_to_hir_id(upvar.var_id());
+        let var_hir_id = self.tcx().hir().node_to_hir_id(upvar.var_id());
         let var_ty = self.mc.node_ty(var_hir_id)?;
         self.mc.cat_def(closure_hir_id, closure_span, var_ty, upvar.def)
     }
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index d2be0e4..fa34c2e 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -23,7 +23,7 @@
     let mut visitor = ItemVisitor {
         tcx,
     };
-    tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
+    tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
 }
 
 struct ItemVisitor<'a, 'tcx: 'a> {
@@ -134,8 +134,8 @@
     }
 
     fn visit_nested_body(&mut self, body_id: hir::BodyId) {
-        let owner_def_id = self.tcx.hir.body_owner_def_id(body_id);
-        let body = self.tcx.hir.body(body_id);
+        let owner_def_id = self.tcx.hir().body_owner_def_id(body_id);
+        let body = self.tcx.hir().body(body_id);
         let param_env = self.tcx.param_env(owner_def_id);
         let tables = self.tcx.typeck_tables_of(owner_def_id);
         ExprVisitor { tcx: self.tcx, param_env, tables }.visit_body(body);
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index e7a8baf..23ec24d 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -13,9 +13,9 @@
 // Language items are items that represent concepts intrinsic to the language
 // itself. Examples are:
 //
-// * Traits that specify "kinds"; e.g. "Sync", "Send".
+// * Traits that specify "kinds"; e.g., "Sync", "Send".
 //
-// * Traits that represent operators; e.g. "Add", "Sub", "Index".
+// * Traits that represent operators; e.g., "Add", "Sub", "Index".
 //
 // * Functions called by the compiler itself.
 
@@ -108,7 +108,7 @@
             match self.item_refs.get(&*value.as_str()).cloned() {
                 // Known lang item with attribute on correct target.
                 Some((item_index, expected_target)) if actual_target == expected_target => {
-                    let def_id = self.tcx.hir.local_def_id(item.id);
+                    let def_id = self.tcx.hir().local_def_id(item.id);
                     self.collect_item(item_index, def_id);
                 },
                 // Known lang item with attribute on incorrect target.
@@ -171,7 +171,7 @@
         if let Some(original_def_id) = self.items.items[item_index] {
             if original_def_id != item_def_id {
                 let name = LangItem::from_u32(item_index as u32).unwrap().name();
-                let mut err = match self.tcx.hir.span_if_local(item_def_id) {
+                let mut err = match self.tcx.hir().span_if_local(item_def_id) {
                     Some(span) => struct_span_err!(
                         self.tcx.sess,
                         span,
@@ -183,7 +183,7 @@
                             self.tcx.crate_name(item_def_id.krate),
                             name)),
                 };
-                if let Some(span) = self.tcx.hir.span_if_local(original_def_id) {
+                if let Some(span) = self.tcx.hir().span_if_local(original_def_id) {
                     span_note!(&mut err, span, "first defined here.");
                 } else {
                     err.note(&format!("first defined in crate `{}`.",
@@ -221,7 +221,7 @@
             collector.collect_item(item_index, def_id);
         }
     }
-    tcx.hir.krate().visit_all_item_likes(&mut collector);
+    tcx.hir().krate().visit_all_item_likes(&mut collector);
     let LanguageItemCollector { mut items, .. } = collector;
     weak_lang_items::check_crate(tcx, &mut items);
     items
diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs
index 7d65d41..8934c7e 100644
--- a/src/librustc/middle/lib_features.rs
+++ b/src/librustc/middle/lib_features.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Detecting lib features (i.e. features that are not lang features).
+// Detecting lib features (i.e., features that are not lang features).
 //
-// These are declared using stability attributes (e.g. `#[stable (..)]`
+// These are declared using stability attributes (e.g., `#[stable (..)]`
 // and `#[unstable (..)]`), but are not declared in one single location
 // (unlike lang features), which means we need to collect them instead.
 
@@ -61,7 +61,7 @@
     fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
         let stab_attrs = vec!["stable", "unstable", "rustc_const_unstable"];
 
-        // Find a stability attribute (i.e. `#[stable (..)]`, `#[unstable (..)]`,
+        // Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`,
         // `#[rustc_const_unstable (..)]`).
         if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| {
             attr.check_name(stab_attr)
@@ -140,7 +140,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for LibFeatureCollector<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.tcx.hir)
+        NestedVisitorMap::All(&self.tcx.hir())
     }
 
     fn visit_attribute(&mut self, attr: &'tcx Attribute) {
@@ -152,6 +152,6 @@
 
 pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LibFeatures {
     let mut collector = LibFeatureCollector::new(tcx);
-    intravisit::walk_crate(&mut collector, tcx.hir.krate());
+    intravisit::walk_crate(&mut collector, tcx.hir().krate());
     collector.lib_features
 }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 54a0192..e576951 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -176,7 +176,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
@@ -190,7 +190,7 @@
 }
 
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    tcx.hir.krate().visit_all_item_likes(&mut IrMaps::new(tcx).as_deep_visitor());
+    tcx.hir().krate().visit_all_item_likes(&mut IrMaps::new(tcx).as_deep_visitor());
     tcx.sess.abort_if_errors();
 }
 
@@ -362,8 +362,8 @@
 
     // Don't run unused pass for #[derive()]
     if let FnKind::Method(..) = fk {
-        let parent = ir.tcx.hir.get_parent(id);
-        if let Some(Node::Item(i)) = ir.tcx.hir.find(parent) {
+        let parent = ir.tcx.hir().get_parent(id);
+        if let Some(Node::Item(i)) = ir.tcx.hir().find(parent) {
             if i.attrs.iter().any(|a| a.check_name("automatically_derived")) {
                 return;
             }
@@ -372,7 +372,7 @@
 
     debug!("creating fn_maps: {:?}", &fn_maps as *const IrMaps<'_, '_>);
 
-    let body = ir.tcx.hir.body(body_id);
+    let body = ir.tcx.hir().body(body_id);
 
     for arg in &body.arguments {
         arg.pat.each_binding(|_bm, hir_id, _x, ident| {
@@ -476,7 +476,7 @@
             call_caps.extend(freevars.iter().filter_map(|fv| {
                 if let Def::Local(rv) = fv.def {
                     let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
-                    let var_hid = ir.tcx.hir.node_to_hir_id(rv);
+                    let var_hid = ir.tcx.hir().node_to_hir_id(rv);
                     Some(CaptureInfo { ln: fv_ln, var_hid })
                 } else {
                     None
@@ -554,7 +554,7 @@
     /// 65 bits of data into 32; in the uncommon cases, it expands the 65 bits
     /// in 96.
     ///
-    /// More compact representations are possible -- e.g. use only 2 bits per
+    /// More compact representations are possible -- e.g., use only 2 bits per
     /// packed `RWU` and make the secondary table a HashMap that maps from
     /// indices to `RWU`s -- but this one strikes a good balance between size
     /// and speed.
@@ -924,7 +924,7 @@
         // effectively a return---this only occurs in `for` loops,
         // where the body is really a closure.
 
-        debug!("compute: using id for body, {}", self.ir.tcx.hir.node_to_pretty_string(body.id));
+        debug!("compute: using id for body, {}", self.ir.tcx.hir().node_to_pretty_string(body.id));
 
         let exit_ln = self.s.exit_ln;
 
@@ -1021,7 +1021,7 @@
 
     fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
                               -> LiveNode {
-        debug!("propagate_through_expr: {}", self.ir.tcx.hir.node_to_pretty_string(expr.id));
+        debug!("propagate_through_expr: {}", self.ir.tcx.hir().node_to_pretty_string(expr.id));
 
         match expr.node {
             // Interesting cases with control flow or which gen/kill
@@ -1035,7 +1035,7 @@
 
             hir::ExprKind::Closure(.., blk_id, _, _) => {
                 debug!("{} is an ExprKind::Closure",
-                       self.ir.tcx.hir.node_to_pretty_string(expr.id));
+                       self.ir.tcx.hir().node_to_pretty_string(expr.id));
 
                 // The next-node for a break is the successor of the entire
                 // loop. The next-node for a continue is the top of this loop.
@@ -1356,7 +1356,7 @@
         let ln = self.live_node(hir_id, span);
         if acc != 0 {
             self.init_from_succ(ln, succ);
-            let var_hid = self.ir.tcx.hir.node_to_hir_id(nid);
+            let var_hid = self.ir.tcx.hir().node_to_hir_id(nid);
             let var = self.variable(var_hid, span);
             self.acc(ln, var, acc);
         }
@@ -1413,7 +1413,7 @@
             }
         }
         debug!("propagate_through_loop: using id for loop body {} {}",
-               expr.id, self.ir.tcx.hir.node_to_pretty_string(body.id));
+               expr.id, self.ir.tcx.hir().node_to_pretty_string(body.id));
 
         let break_ln = succ;
         let cont_ln = ln;
@@ -1547,7 +1547,7 @@
                     // mutable, then check for a reassignment to flag the mutability
                     // as being used.
                     let ln = self.live_node(expr.hir_id, expr.span);
-                    let var_hid = self.ir.tcx.hir.node_to_hir_id(nid);
+                    let var_hid = self.ir.tcx.hir().node_to_hir_id(nid);
                     let var = self.variable(var_hid, expr.span);
                     self.warn_about_dead_assign(expr.span, expr.hir_id, ln, var);
                 }
@@ -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/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index cadf0c4..a04914e 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -127,7 +127,7 @@
 }
 
 // We use the term "interior" to mean "something reachable from the
-// base without a pointer dereference", e.g. a field
+// base without a pointer dereference", e.g., a field
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
 pub enum InteriorKind {
     InteriorField(FieldIndex),
@@ -153,8 +153,8 @@
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub enum InteriorOffsetKind {
-    Index,   // e.g. `array_expr[index_expr]`
-    Pattern, // e.g. `fn foo([_, a, _, _]: [A; 4]) { ... }`
+    Index,   // e.g., `array_expr[index_expr]`
+    Pattern, // e.g., `fn foo([_, a, _, _]: [A; 4]) { ... }`
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
@@ -348,7 +348,7 @@
 
     fn from_local(tcx: TyCtxt<'_, '_, '_>, tables: &ty::TypeckTables<'_>,
                   id: ast::NodeId) -> MutabilityCategory {
-        let ret = match tcx.hir.get(id) {
+        let ret = match tcx.hir().get(id) {
             Node::Binding(p) => match p.node {
                 PatKind::Binding(..) => {
                     let bm = *tables.pat_binding_modes()
@@ -362,7 +362,7 @@
                 }
                 _ => span_bug!(p.span, "expected identifier pattern")
             },
-            _ => span_bug!(tcx.hir.span(id), "expected identifier pattern")
+            _ => span_bug!(tcx.hir().span(id), "expected identifier pattern")
         };
         debug!("MutabilityCategory::{}(tcx, id={:?}) => {:?}",
                "from_local", id, ret);
@@ -495,9 +495,9 @@
             // FIXME
             None if self.is_tainted_by_errors() => Err(()),
             None => {
-                let id = self.tcx.hir.hir_to_node_id(id);
+                let id = self.tcx.hir().hir_to_node_id(id);
                 bug!("no type for node {}: {} in mem_categorization",
-                     id, self.tcx.hir.node_to_string(id));
+                     id, self.tcx.hir().node_to_string(id));
             }
         }
     }
@@ -770,7 +770,7 @@
                  fn_node_id: ast::NodeId)
                  -> McResult<cmt_<'tcx>>
     {
-        let fn_hir_id = self.tcx.hir.node_to_hir_id(fn_node_id);
+        let fn_hir_id = self.tcx.hir().node_to_hir_id(fn_node_id);
 
         // An upvar can have up to 3 components. We translate first to a
         // `Categorization::Upvar`, which is itself a fiction -- it represents the reference to the
@@ -815,8 +815,8 @@
             ref t => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", t),
         };
 
-        let closure_expr_def_id = self.tcx.hir.local_def_id(fn_node_id);
-        let var_hir_id = self.tcx.hir.node_to_hir_id(var_id);
+        let closure_expr_def_id = self.tcx.hir().local_def_id(fn_node_id);
+        let var_hir_id = self.tcx.hir().node_to_hir_id(var_id);
         let upvar_id = ty::UpvarId {
             var_path: ty::UpvarPath { hir_id: var_hir_id },
             closure_expr_id: closure_expr_def_id.to_local(),
@@ -961,7 +961,7 @@
 
         debug!("cat_rvalue_node: promotable = {:?}", promotable);
 
-        // Always promote `[T; 0]` (even when e.g. borrowed mutably).
+        // Always promote `[T; 0]` (even when e.g., borrowed mutably).
         let promotable = match expr_ty.sty {
             ty::Array(_, len) if len.assert_usize(self.tcx) == Some(0) => true,
             _ => promotable,
@@ -1504,7 +1504,7 @@
                 "non-place".into()
             }
             Categorization::Local(vid) => {
-                if tcx.hir.is_argument(vid) {
+                if tcx.hir().is_argument(vid) {
                     "argument"
                 } else {
                     "local variable"
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index ab0094d..89814dd 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -47,7 +47,7 @@
     match item.node {
         hir::ItemKind::Impl(..) |
         hir::ItemKind::Fn(..) => {
-            let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
+            let generics = tcx.generics_of(tcx.hir().local_def_id(item.id));
             generics.requires_monomorphization(tcx)
         }
         _ => false,
@@ -58,12 +58,12 @@
                                      impl_item: &hir::ImplItem,
                                      impl_src: DefId) -> bool {
     let codegen_fn_attrs = tcx.codegen_fn_attrs(impl_item.hir_id.owner_def_id());
-    let generics = tcx.generics_of(tcx.hir.local_def_id(impl_item.id));
+    let generics = tcx.generics_of(tcx.hir().local_def_id(impl_item.id));
     if codegen_fn_attrs.requests_inline() || generics.requires_monomorphization(tcx) {
         return true
     }
-    if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) {
-        match tcx.hir.find(impl_node_id) {
+    if let Some(impl_node_id) = tcx.hir().as_local_node_id(impl_src) {
+        match tcx.hir().find(impl_node_id) {
             Some(Node::Item(item)) =>
                 item_might_be_inlined(tcx, &item, codegen_fn_attrs),
             Some(..) | None =>
@@ -96,7 +96,7 @@
     fn visit_nested_body(&mut self, body: hir::BodyId) {
         let old_tables = self.tables;
         self.tables = self.tcx.body_tables(body);
-        let body = self.tcx.hir.body(body);
+        let body = self.tcx.hir().body(body);
         self.visit_body(body);
         self.tables = old_tables;
     }
@@ -118,7 +118,7 @@
             }
             Some(def) => {
                 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))
+                    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);
@@ -151,12 +151,12 @@
     // Returns true if the given def ID represents a local item that is
     // eligible for inlining and false otherwise.
     fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool {
-        let node_id = match self.tcx.hir.as_local_node_id(def_id) {
+        let node_id = match self.tcx.hir().as_local_node_id(def_id) {
             Some(node_id) => node_id,
             None => { return false; }
         };
 
-        match self.tcx.hir.find(node_id) {
+        match self.tcx.hir().find(node_id) {
             Some(Node::Item(item)) => {
                 match item.node {
                     hir::ItemKind::Fn(..) =>
@@ -182,13 +182,13 @@
                             true
                         } else {
                             let impl_did = self.tcx
-                                               .hir
+                                               .hir()
                                                .get_parent_did(node_id);
                             // Check the impl. If the generics on the self
                             // type of the impl require inlining, this method
                             // does too.
-                            let impl_node_id = self.tcx.hir.as_local_node_id(impl_did).unwrap();
-                            match self.tcx.hir.expect_item(impl_node_id).node {
+                            let impl_node_id = self.tcx.hir().as_local_node_id(impl_did).unwrap();
+                            match self.tcx.hir().expect_item(impl_node_id).node {
                                 hir::ItemKind::Impl(..) => {
                                     let generics = self.tcx.generics_of(impl_did);
                                     generics.requires_monomorphization(self.tcx)
@@ -214,7 +214,7 @@
                 continue
             }
 
-            if let Some(ref item) = self.tcx.hir.find(search_item) {
+            if let Some(ref item) = self.tcx.hir().find(search_item) {
                 self.propagate_node(item, search_item);
             }
         }
@@ -231,7 +231,7 @@
                 } else {
                     false
                 };
-                let def_id = self.tcx.hir.local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id(item.id);
                 let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
                 let is_extern = codegen_attrs.contains_extern_indicator();
                 let std_internal = codegen_attrs.flags.contains(
@@ -252,7 +252,7 @@
             Node::Item(item) => {
                 match item.node {
                     hir::ItemKind::Fn(.., body) => {
-                        let def_id = self.tcx.hir.local_def_id(item.id);
+                        let def_id = self.tcx.hir().local_def_id(item.id);
                         if item_might_be_inlined(self.tcx,
                                                  &item,
                                                  self.tcx.codegen_fn_attrs(def_id)) {
@@ -305,7 +305,7 @@
                         self.visit_nested_body(body);
                     }
                     hir::ImplItemKind::Method(_, body) => {
-                        let did = self.tcx.hir.get_parent_did(search_item);
+                        let did = self.tcx.hir().get_parent_did(search_item);
                         if method_might_be_inlined(self.tcx, impl_item, did) {
                             self.visit_nested_body(body)
                         }
@@ -326,7 +326,7 @@
             Node::MacroDef(_) => {}
             _ => {
                 bug!("found unexpected thingy in worklist: {}",
-                     self.tcx.hir.node_to_string(search_item))
+                     self.tcx.hir().node_to_string(search_item))
             }
         }
     }
@@ -351,7 +351,7 @@
         // Anything which has custom linkage gets thrown on the worklist no
         // matter where it is in the crate, along with "special std symbols"
         // which are currently akin to allocator symbols.
-        let def_id = self.tcx.hir.local_def_id(item.id);
+        let def_id = self.tcx.hir().local_def_id(item.id);
         let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
         if codegen_attrs.contains_extern_indicator() ||
             codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
@@ -376,7 +376,7 @@
                 self.worklist.reserve(provided_trait_methods.len());
                 for default_method in provided_trait_methods {
                     let node_id = self.tcx
-                                      .hir
+                                      .hir()
                                       .as_local_node_id(default_method.def_id)
                                       .unwrap();
                     self.worklist.push(node_id);
@@ -422,7 +422,7 @@
     reachable_context.worklist.extend(access_levels.map.iter().map(|(id, _)| *id));
     for item in tcx.lang_items().items().iter() {
         if let Some(did) = *item {
-            if let Some(node_id) = tcx.hir.as_local_node_id(did) {
+            if let Some(node_id) = tcx.hir().as_local_node_id(did) {
                 reachable_context.worklist.push(node_id);
             }
         }
@@ -433,7 +433,7 @@
             access_levels,
             worklist: &mut reachable_context.worklist,
         };
-        tcx.hir.krate().visit_all_item_likes(&mut collect_private_impl_items);
+        tcx.hir().krate().visit_all_item_likes(&mut collect_private_impl_items);
     }
 
     // Step 2: Mark all symbols that the symbols on the worklist touch.
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 3c2551f..9977faf 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -84,7 +84,7 @@
 ///  (D9.): DestructionScope for temporaries created during M8.
 /// (R10.): Remainder scope for block `'b:`, stmt 1 (let y = ...).
 /// (D11.): DestructionScope for temporaries and bindings from block `'b:`.
-/// (D12.): DestructionScope for temporaries created during M1 (e.g. f()).
+/// (D12.): DestructionScope for temporaries created during M1 (e.g., f()).
 /// ```
 ///
 /// Note that while the above picture shows the destruction scopes
@@ -155,7 +155,7 @@
 ///   everything after that first `let`. (If you want a scope that
 ///   includes EXPR_1 as well, then do not use `Scope::Remainder`,
 ///   but instead another `Scope` that encompasses the whole block,
-///   e.g. `Scope::Node`.
+///   e.g., `Scope::Node`.
 ///
 /// * the subscope with `first_statement_index == 1` is scope of `c`,
 ///   and thus does not include EXPR_2, but covers the `...`.
@@ -172,7 +172,7 @@
 impl Scope {
     /// Returns a item-local id associated with this scope.
     ///
-    /// NB: likely to be replaced as API is refined; e.g. pnkfelix
+    /// N.B., likely to be replaced as API is refined; e.g., pnkfelix
     /// anticipates `fn entry_node_id` and `fn each_exit_node_id`.
     pub fn item_local_id(&self) -> hir::ItemLocalId {
         self.id
@@ -181,7 +181,7 @@
     pub fn node_id(&self, tcx: TyCtxt<'_, '_, '_>, scope_tree: &ScopeTree) -> ast::NodeId {
         match scope_tree.root_body {
             Some(hir_id) => {
-                tcx.hir.hir_to_node_id(hir::HirId {
+                tcx.hir().hir_to_node_id(hir::HirId {
                     owner: hir_id.owner,
                     local_id: self.item_local_id()
                 })
@@ -198,9 +198,9 @@
         if node_id == ast::DUMMY_NODE_ID {
             return DUMMY_SP;
         }
-        let span = tcx.hir.span(node_id);
+        let span = tcx.hir().span(node_id);
         if let ScopeData::Remainder(first_statement_index) = self.data {
-            if let Node::Block(ref blk) = tcx.hir.get(node_id) {
+            if let Node::Block(ref blk) = tcx.hir().get(node_id) {
                 // Want span for scope starting after the
                 // indexed statement and ending at end of
                 // `blk`; reuse span of `blk` and shift `lo`
@@ -660,9 +660,9 @@
                                       -> Scope {
         let param_owner = tcx.parent_def_id(br.def_id).unwrap();
 
-        let param_owner_id = tcx.hir.as_local_node_id(param_owner).unwrap();
-        let scope = tcx.hir.maybe_body_owned_by(param_owner_id).map(|body_id| {
-            tcx.hir.body(body_id).value.hir_id.local_id
+        let param_owner_id = tcx.hir().as_local_node_id(param_owner).unwrap();
+        let scope = tcx.hir().maybe_body_owned_by(param_owner_id).map(|body_id| {
+            tcx.hir().body(body_id).value.hir_id.local_id
         }).unwrap_or_else(|| {
             // The lifetime was defined on node that doesn't own a body,
             // which in practice can only mean a trait or an impl, that
@@ -671,7 +671,7 @@
                        "free_scope: {:?} not recognized by the \
                         region scope tree for {:?} / {:?}",
                        param_owner,
-                       self.root_parent.map(|id| tcx.hir.local_def_id(id)),
+                       self.root_parent.map(|id| tcx.hir().local_def_id(id)),
                        self.root_body.map(|hir_id| DefId::local(hir_id.owner)));
 
             // The trait/impl lifetime is in scope for the method's body.
@@ -696,9 +696,9 @@
         // on the same function that they ended up being freed in.
         assert_eq!(param_owner, fr.scope);
 
-        let param_owner_id = tcx.hir.as_local_node_id(param_owner).unwrap();
-        let body_id = tcx.hir.body_owned_by(param_owner_id);
-        Scope { id: tcx.hir.body(body_id).value.hir_id.local_id, data: ScopeData::CallSite }
+        let param_owner_id = tcx.hir().as_local_node_id(param_owner).unwrap();
+        let body_id = tcx.hir().body_owned_by(param_owner_id);
+        Scope { id: tcx.hir().body(body_id).value.hir_id.local_id, data: ScopeData::CallSite }
     }
 
     /// Checks whether the given scope contains a `yield`. If so,
@@ -770,10 +770,10 @@
     //    }, other_argument());
     //
     // Each of the statements within the block is a terminating
-    // scope, and thus a temporary (e.g. the result of calling
+    // scope, and thus a temporary (e.g., the result of calling
     // `bar()` in the initializer expression for `let inner = ...;`)
     // will be cleaned up immediately after its corresponding
-    // statement (i.e. `let inner = ...;`) executes.
+    // statement (i.e., `let inner = ...;`) executes.
     //
     // On the other hand, temporaries associated with evaluating the
     // tail expression for the block are assigned lifetimes so that
@@ -845,7 +845,7 @@
 }
 
 fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, stmt: &'tcx hir::Stmt) {
-    let stmt_id = visitor.tcx.hir.node_to_hir_id(stmt.node.id()).local_id;
+    let stmt_id = visitor.tcx.hir().node_to_hir_id(stmt.node.id()).local_id;
     debug!("resolve_stmt(stmt.id={:?})", stmt_id);
 
     // Every statement will clean up the temporaries created during
@@ -942,7 +942,7 @@
         // Manually recurse over closures, because they are the only
         // case of nested bodies that share the parent environment.
         hir::ExprKind::Closure(.., body, _, _) => {
-            let body = visitor.tcx.hir.body(body);
+            let body = visitor.tcx.hir().body(body);
             visitor.visit_body(body);
         }
 
@@ -984,7 +984,7 @@
 
     // As an exception to the normal rules governing temporary
     // lifetimes, initializers in a let have a temporary lifetime
-    // of the enclosing block. This means that e.g. a program
+    // of the enclosing block. This means that e.g., a program
     // like the following is legal:
     //
     //     let ref x = HashMap::new();
@@ -1183,7 +1183,7 @@
         loop {
             // Note: give all the expressions matching `ET` with the
             // extended temporary lifetime, not just the innermost rvalue,
-            // because in codegen if we must compile e.g. `*rvalue()`
+            // because in codegen if we must compile e.g., `*rvalue()`
             // into a temporary, we request the temporary scope of the
             // outer expression.
             visitor.scope_tree.record_rvalue_scope(expr.hir_id.local_id, blk_scope);
@@ -1244,7 +1244,7 @@
 
     fn visit_body(&mut self, body: &'tcx hir::Body) {
         let body_id = body.id();
-        let owner_id = self.tcx.hir.body_owner(body_id);
+        let owner_id = self.tcx.hir().body_owner(body_id);
 
         debug!("visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})",
                owner_id,
@@ -1273,7 +1273,7 @@
 
         // The body of the every fn is a root scope.
         self.cx.parent = self.cx.var_parent;
-        if let hir::BodyOwnerKind::Fn = self.tcx.hir.body_owner_kind(owner_id) {
+        if let hir::BodyOwnerKind::Fn = self.tcx.hir().body_owner_kind(owner_id) {
             self.visit_expr(&body.value);
         } else {
             // Only functions have an outer terminating (drop) scope, while
@@ -1281,7 +1281,7 @@
             // according to rvalue lifetime semantics, using the same
             // syntactical rules used for let initializers.
             //
-            // E.g. in `let x = &f();`, the temporary holding the result from
+            // e.g., in `let x = &f();`, the temporary holding the result from
             // the `f()` call lives for the entirety of the surrounding block.
             //
             // Similarly, `const X: ... = &f();` would have the result of `f()`
@@ -1292,7 +1292,7 @@
             //
             // However, `const Y: ... = g(&f());`, like `let y = g(&f());`,
             // would *not* let the `f()` temporary escape into an outer scope
-            // (i.e. `'static`), which means that after `g` returns, it drops,
+            // (i.e., `'static`), which means that after `g` returns, it drops,
             // and all the associated destruction scope rules apply.
             self.cx.var_parent = None;
             resolve_local(self, None, Some(&body.value));
@@ -1333,8 +1333,8 @@
         return tcx.region_scope_tree(closure_base_def_id);
     }
 
-    let id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let scope_tree = if let Some(body_id) = tcx.hir.maybe_body_owned_by(id) {
+    let id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let scope_tree = if let Some(body_id) = tcx.hir().maybe_body_owned_by(id) {
         let mut visitor = RegionResolutionVisitor {
             tcx,
             scope_tree: ScopeTree::default(),
@@ -1347,16 +1347,16 @@
             terminating_scopes: Default::default(),
         };
 
-        let body = tcx.hir.body(body_id);
+        let body = tcx.hir().body(body_id);
         visitor.scope_tree.root_body = Some(body.value.hir_id);
 
         // If the item is an associated const or a method,
         // record its impl/trait parent, as it can also have
         // lifetime parameters free in this body.
-        match tcx.hir.get(id) {
+        match tcx.hir().get(id) {
             Node::ImplItem(_) |
             Node::TraitItem(_) => {
-                visitor.scope_tree.root_parent = Some(tcx.hir.get_parent(id));
+                visitor.scope_tree.root_parent = Some(tcx.hir().get_parent(id));
             }
             _ => {}
         }
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 07054ee..571f718 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -303,14 +303,14 @@
     /// Lifetimes introduced by a fn are scoped to the call-site for that fn,
     /// if this is a fn body, otherwise the original definitions are used.
     /// Unspecified lifetimes are inferred, unless an elision scope is nested,
-    /// e.g. `(&T, fn(&T) -> &T);` becomes `(&'_ T, for<'a> fn(&'a T) -> &'a T)`.
+    /// e.g., `(&T, fn(&T) -> &T);` becomes `(&'_ T, for<'a> fn(&'a T) -> &'a T)`.
     Body {
         id: hir::BodyId,
         s: ScopeRef<'a>,
     },
 
     /// A scope which either determines unspecified lifetimes or errors
-    /// on them (e.g. due to ambiguity). For more details, see `Elide`.
+    /// on them (e.g., due to ambiguity). For more details, see `Elide`.
     Elision {
         elide: Elide,
         s: ScopeRef<'a>,
@@ -398,19 +398,19 @@
     let mut rl = ResolveLifetimes::default();
 
     for (k, v) in named_region_map.defs {
-        let hir_id = tcx.hir.node_to_hir_id(k);
+        let hir_id = tcx.hir().node_to_hir_id(k);
         let map = rl.defs.entry(hir_id.owner_local_def_id()).or_default();
         Lrc::get_mut(map).unwrap().insert(hir_id.local_id, v);
     }
     for k in named_region_map.late_bound {
-        let hir_id = tcx.hir.node_to_hir_id(k);
+        let hir_id = tcx.hir().node_to_hir_id(k);
         let map = rl.late_bound
             .entry(hir_id.owner_local_def_id())
             .or_default();
         Lrc::get_mut(map).unwrap().insert(hir_id.local_id);
     }
     for (k, v) in named_region_map.object_lifetime_defaults {
-        let hir_id = tcx.hir.node_to_hir_id(k);
+        let hir_id = tcx.hir().node_to_hir_id(k);
         let map = rl.object_lifetime_defaults
             .entry(hir_id.owner_local_def_id())
             .or_default();
@@ -423,7 +423,7 @@
 }
 
 fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap {
-    let krate = tcx.hir.krate();
+    let krate = tcx.hir().krate();
     let mut map = NamedRegionMap {
         defs: Default::default(),
         late_bound: Default::default(),
@@ -460,7 +460,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.tcx.hir)
+        NestedVisitorMap::All(&self.tcx.hir())
     }
 
     // We want to nest trait/impl items in their parent, but nothing else.
@@ -469,7 +469,7 @@
     fn visit_nested_body(&mut self, body: hir::BodyId) {
         // Each body has their own set of labels, save labels.
         let saved = replace(&mut self.labels_in_fn, vec![]);
-        let body = self.tcx.hir.body(body);
+        let body = self.tcx.hir().body(body);
         extract_labels(self, body);
         self.with(
             Scope::Body {
@@ -545,7 +545,7 @@
                     .iter()
                     .filter_map(|param| match param.kind {
                         GenericParamKind::Lifetime { .. } => {
-                            Some(Region::early(&self.tcx.hir, &mut index, param))
+                            Some(Region::early(&self.tcx.hir(), &mut index, param))
                         }
                         GenericParamKind::Type { .. } => {
                             type_count += 1;
@@ -596,7 +596,7 @@
                         .iter()
                         .filter_map(|param| match param.kind {
                             GenericParamKind::Lifetime { .. } => {
-                                Some(Region::late(&self.tcx.hir, param))
+                                Some(Region::late(&self.tcx.hir(), param))
                             }
                             _ => None,
                         })
@@ -622,13 +622,13 @@
                     LifetimeName::Implicit => {
                         // If the user does not write *anything*, we
                         // use the object lifetime defaulting
-                        // rules. So e.g. `Box<dyn Debug>` becomes
+                        // rules. So e.g., `Box<dyn Debug>` becomes
                         // `Box<dyn Debug + 'static>`.
                         self.resolve_object_lifetime_default(lifetime)
                     }
                     LifetimeName::Underscore => {
                         // If the user writes `'_`, we use the *ordinary* elision
-                        // rules. So the `'_` in e.g. `Box<dyn Debug + '_>` will be
+                        // rules. So the `'_` in e.g., `Box<dyn Debug + '_>` will be
                         // resolved the same as the `'_` in `&'_ Foo`.
                         //
                         // cc #48468
@@ -655,7 +655,7 @@
                 // `abstract type MyAnonTy<'b>: MyTrait<'b>;`
                 //                          ^            ^ this gets resolved in the scope of
                 //                                         the exist_ty generics
-                let (generics, bounds) = match self.tcx.hir.expect_item(item_id.id).node {
+                let (generics, bounds) = match self.tcx.hir().expect_item(item_id.id).node {
                     // named existential types are reached via TyKind::Path
                     // this arm is for `impl Trait` in the types of statics, constants and locals
                     hir::ItemKind::Existential(hir::ExistTy {
@@ -689,12 +689,12 @@
                         // In the future, this should be fixed and this error should be removed.
                         let def = self.map.defs.get(&lifetime.id).cloned();
                         if let Some(Region::LateBound(_, def_id, _)) = def {
-                            if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
+                            if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
                                 // Ensure that the parent of the def is an item, not HRTB
-                                let parent_id = self.tcx.hir.get_parent_node(node_id);
+                                let parent_id = self.tcx.hir().get_parent_node(node_id);
                                 let parent_impl_id = hir::ImplItemId { node_id: parent_id };
                                 let parent_trait_id = hir::TraitItemId { node_id: parent_id };
-                                let krate = self.tcx.hir.forest.krate();
+                                let krate = self.tcx.hir().forest.krate();
                                 if !(krate.items.contains_key(&parent_id)
                                     || krate.impl_items.contains_key(&parent_impl_id)
                                     || krate.trait_items.contains_key(&parent_trait_id))
@@ -724,7 +724,7 @@
                 for param in &generics.params {
                     match param.kind {
                         GenericParamKind::Lifetime { .. } => {
-                            let (name, reg) = Region::early(&self.tcx.hir, &mut index, &param);
+                            let (name, reg) = Region::early(&self.tcx.hir(), &mut index, &param);
                             if let hir::ParamName::Plain(param_name) = name {
                                 if param_name.name == keywords::UnderscoreLifetime.name() {
                                     // Pick the elided lifetime "definition" if one exists
@@ -790,7 +790,7 @@
             Method(ref sig, _) => {
                 let tcx = self.tcx;
                 self.visit_early_late(
-                    Some(tcx.hir.get_parent(trait_item.id)),
+                    Some(tcx.hir().get_parent(trait_item.id)),
                     &sig.decl,
                     &trait_item.generics,
                     |this| intravisit::walk_trait_item(this, trait_item),
@@ -806,7 +806,7 @@
                     .iter()
                     .filter_map(|param| match param.kind {
                         GenericParamKind::Lifetime { .. } => {
-                            Some(Region::early(&self.tcx.hir, &mut index, param))
+                            Some(Region::early(&self.tcx.hir(), &mut index, param))
                         }
                         GenericParamKind::Type { .. } => {
                             type_count += 1;
@@ -845,7 +845,7 @@
             Method(ref sig, _) => {
                 let tcx = self.tcx;
                 self.visit_early_late(
-                    Some(tcx.hir.get_parent(impl_item.id)),
+                    Some(tcx.hir().get_parent(impl_item.id)),
                     &sig.decl,
                     &impl_item.generics,
                     |this| intravisit::walk_impl_item(this, impl_item),
@@ -861,7 +861,7 @@
                     .iter()
                     .filter_map(|param| match param.kind {
                         GenericParamKind::Lifetime { .. } => {
-                            Some(Region::early(&self.tcx.hir, &mut index, param))
+                            Some(Region::early(&self.tcx.hir(), &mut index, param))
                         }
                         GenericParamKind::Type { .. } => {
                             next_early_index += 1;
@@ -891,7 +891,7 @@
                     .iter()
                     .filter_map(|param| match param.kind {
                         GenericParamKind::Lifetime { .. } => {
-                            Some(Region::early(&self.tcx.hir, &mut index, param))
+                            Some(Region::early(&self.tcx.hir(), &mut index, param))
                         }
                         GenericParamKind::Type { .. } => {
                             next_early_index += 1;
@@ -976,7 +976,7 @@
                         .iter()
                         .filter_map(|param| match param.kind {
                             GenericParamKind::Lifetime { .. } => {
-                                Some(Region::late(&self.tcx.hir, param))
+                                Some(Region::late(&self.tcx.hir(), param))
                             }
                             _ => None,
                         })
@@ -1051,7 +1051,7 @@
                     .iter()
                     .filter_map(|param| match param.kind {
                         GenericParamKind::Lifetime { .. } => {
-                            Some(Region::late(&self.tcx.hir, param))
+                            Some(Region::late(&self.tcx.hir(), param))
                         }
                         _ => None,
                     })
@@ -1258,12 +1258,12 @@
                 } => {
                     // FIXME (#24278): non-hygienic comparison
                     if let Some(def) = lifetimes.get(&hir::ParamName::Plain(label.modern())) {
-                        let node_id = tcx.hir.as_local_node_id(def.id().unwrap()).unwrap();
+                        let node_id = tcx.hir().as_local_node_id(def.id().unwrap()).unwrap();
 
                         signal_shadowing_problem(
                             tcx,
                             label.name,
-                            original_lifetime(tcx.hir.span(node_id)),
+                            original_lifetime(tcx.hir().span(node_id)),
                             shadower_label(label.span),
                         );
                         return;
@@ -1279,7 +1279,7 @@
     tcx: TyCtxt<'_, '_, '_>,
 ) -> NodeMap<Vec<ObjectLifetimeDefault>> {
     let mut map = NodeMap::default();
-    for item in tcx.hir.krate().items.values() {
+    for item in tcx.hir().krate().items.values() {
         match item.node {
             hir::ItemKind::Struct(_, ref generics)
             | hir::ItemKind::Union(_, ref generics)
@@ -1355,7 +1355,7 @@
 
                 add_bounds(&mut set, &param.bounds);
 
-                let param_def_id = tcx.hir.local_def_id(param.id);
+                let param_def_id = tcx.hir().local_def_id(param.id);
                 for predicate in &generics.where_clause.predicates {
                     // Look for `type: ...` where clauses.
                     let data = match *predicate {
@@ -1399,7 +1399,7 @@
                                 .enumerate()
                                 .find(|&(_, (_, lt_name, _))| lt_name == name)
                                 .map_or(Set1::Many, |(i, (id, _, origin))| {
-                                    let def_id = tcx.hir.local_def_id(id);
+                                    let def_id = tcx.hir().local_def_id(id);
                                     Set1::One(Region::EarlyBound(i as u32, def_id, origin))
                                 })
                         }
@@ -1492,7 +1492,7 @@
         let name = lifetime.name.ident();
         let mut remove_decl = None;
         if let Some(parent_def_id) = self.tcx.parent(def_id) {
-            if let Some(generics) = self.tcx.hir.get_generics(parent_def_id) {
+            if let Some(generics) = self.tcx.hir().get_generics(parent_def_id) {
                 remove_decl = self.lifetime_deletion_span(name, generics);
             }
         }
@@ -1513,8 +1513,8 @@
                 }
             }
         };
-        if let Node::Lifetime(hir_lifetime) = self.tcx.hir.get(lifetime.id) {
-            if let Some(parent) = self.tcx.hir.find(self.tcx.hir.get_parent(hir_lifetime.id)) {
+        if let Node::Lifetime(hir_lifetime) = self.tcx.hir().get(lifetime.id) {
+            if let Some(parent) = self.tcx.hir().find(self.tcx.hir().get_parent(hir_lifetime.id)) {
                 match parent {
                     Node::Item(item) => {
                         if let hir::ItemKind::Fn(decl, _, _, _) = &item.node {
@@ -1590,9 +1590,9 @@
 
             match lifetimeuseset {
                 Some(LifetimeUseSet::One(lifetime)) => {
-                    let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
+                    let node_id = self.tcx.hir().as_local_node_id(def_id).unwrap();
                     debug!("node id first={:?}", node_id);
-                    if let Some((id, span, name)) = match self.tcx.hir.get(node_id) {
+                    if let Some((id, span, name)) = match self.tcx.hir().get(node_id) {
                         Node::Lifetime(hir_lifetime) => Some((
                             hir_lifetime.id,
                             hir_lifetime.span,
@@ -1631,8 +1631,8 @@
                     debug!("Not one use lifetime");
                 }
                 None => {
-                    let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
-                    if let Some((id, span, name)) = match self.tcx.hir.get(node_id) {
+                    let node_id = self.tcx.hir().as_local_node_id(def_id).unwrap();
+                    if let Some((id, span, name)) = match self.tcx.hir().get(node_id) {
                         Node::Lifetime(hir_lifetime) => Some((
                             hir_lifetime.id,
                             hir_lifetime.span,
@@ -1651,7 +1651,7 @@
                             &format!("lifetime parameter `{}` never used", name),
                         );
                         if let Some(parent_def_id) = self.tcx.parent(def_id) {
-                            if let Some(generics) = self.tcx.hir.get_generics(parent_def_id) {
+                            if let Some(generics) = self.tcx.hir().get_generics(parent_def_id) {
                                 let unused_lt_span = self.lifetime_deletion_span(name, generics);
                                 if let Some(span) = unused_lt_span {
                                     err.span_suggestion_with_applicability(
@@ -1699,10 +1699,10 @@
     {
         insert_late_bound_lifetimes(self.map, decl, generics);
 
-        // Find the start of nested early scopes, e.g. in methods.
+        // Find the start of nested early scopes, e.g., in methods.
         let mut index = 0;
         if let Some(parent_id) = parent_id {
-            let parent = self.tcx.hir.expect_item(parent_id);
+            let parent = self.tcx.hir().expect_item(parent_id);
             if sub_items_have_self_param(&parent.node) {
                 index += 1; // Self comes before lifetimes
             }
@@ -1722,9 +1722,9 @@
             .filter_map(|param| match param.kind {
                 GenericParamKind::Lifetime { .. } => {
                     if self.map.late_bound.contains(&param.id) {
-                        Some(Region::late(&self.tcx.hir, param))
+                        Some(Region::late(&self.tcx.hir(), param))
                     } else {
-                        Some(Region::early(&self.tcx.hir, &mut index, param))
+                        Some(Region::early(&self.tcx.hir(), &mut index, param))
                     }
                 }
                 GenericParamKind::Type { .. } => {
@@ -1837,8 +1837,8 @@
             if let Region::EarlyBound(..) = def {
                 // Do not free early-bound regions, only late-bound ones.
             } else if let Some(body_id) = outermost_body {
-                let fn_id = self.tcx.hir.body_owner(body_id);
-                match self.tcx.hir.get(fn_id) {
+                let fn_id = self.tcx.hir().body_owner(body_id);
+                match self.tcx.hir().get(fn_id) {
                     Node::Item(&hir::Item {
                         node: hir::ItemKind::Fn(..),
                         ..
@@ -1851,7 +1851,7 @@
                         node: hir::ImplItemKind::Method(..),
                         ..
                     }) => {
-                        let scope = self.tcx.hir.local_def_id(fn_id);
+                        let scope = self.tcx.hir().local_def_id(fn_id);
                         def = Region::Free(scope, def.id().unwrap());
                     }
                     _ => {}
@@ -1967,7 +1967,7 @@
             };
 
             let map = &self.map;
-            let unsubst = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
+            let unsubst = if let Some(id) = self.tcx.hir().as_local_node_id(def_id) {
                 &map.object_lifetime_defaults[&id]
             } else {
                 let tcx = self.tcx;
@@ -2061,8 +2061,8 @@
         // and whether there's a `self` argument (treated specially).
         let mut assoc_item_kind = None;
         let mut impl_self = None;
-        let parent = self.tcx.hir.get_parent_node(output.id);
-        let body = match self.tcx.hir.get(parent) {
+        let parent = self.tcx.hir().get_parent_node(output.id);
+        let body = match self.tcx.hir().get(parent) {
             // `fn` definitions and methods.
             Node::Item(&hir::Item {
                 node: hir::ItemKind::Fn(.., body),
@@ -2074,8 +2074,8 @@
                 ..
             }) => {
                 if let hir::ItemKind::Trait(.., ref trait_items) = self.tcx
-                    .hir
-                    .expect_item(self.tcx.hir.get_parent(parent))
+                    .hir()
+                    .expect_item(self.tcx.hir().get_parent(parent))
                     .node
                 {
                     assoc_item_kind = trait_items
@@ -2094,8 +2094,8 @@
                 ..
             }) => {
                 if let hir::ItemKind::Impl(.., ref self_ty, ref impl_items) = self.tcx
-                    .hir
-                    .expect_item(self.tcx.hir.get_parent(parent))
+                    .hir()
+                    .expect_item(self.tcx.hir().get_parent(parent))
                     .node
                 {
                     impl_self = Some(self_ty);
@@ -2396,8 +2396,8 @@
             } = info;
 
             let help_name = if let Some(body) = parent {
-                let arg = &self.tcx.hir.body(body).arguments[index];
-                format!("`{}`", self.tcx.hir.node_to_pretty_string(arg.pat.id))
+                let arg = &self.tcx.hir().body(body).arguments[index];
+                format!("`{}`", self.tcx.hir().node_to_pretty_string(arg.pat.id))
             } else {
                 format!("argument {}", index + 1)
             };
@@ -2603,12 +2603,12 @@
                     ref lifetimes, s, ..
                 } => {
                     if let Some(&def) = lifetimes.get(&param.name.modern()) {
-                        let node_id = self.tcx.hir.as_local_node_id(def.id().unwrap()).unwrap();
+                        let node_id = self.tcx.hir().as_local_node_id(def.id().unwrap()).unwrap();
 
                         signal_shadowing_problem(
                             self.tcx,
                             param.name.ident().name,
-                            original_lifetime(self.tcx.hir.span(node_id)),
+                            original_lifetime(self.tcx.hir().span(node_id)),
                             shadower_lifetime(&param),
                         );
                         return;
@@ -2675,7 +2675,7 @@
 
         debug!(
             "insert_lifetime: {} resolved to {:?} span={:?}",
-            self.tcx.hir.node_to_string(lifetime_ref.id),
+            self.tcx.hir().node_to_string(lifetime_ref.id),
             def,
             self.tcx.sess.source_map().span_to_string(lifetime_ref.span)
         );
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 543d105..ab379c9 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -14,9 +14,10 @@
 pub use self::StabilityLevel::*;
 
 use lint;
+use hir::{self, Item, Generics, StructField, Variant, HirId};
 use hir::def::Def;
 use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
-use ty::{self, TyCtxt};
+use hir::intravisit::{self, Visitor, NestedVisitorMap};
 use middle::privacy::AccessLevels;
 use session::{DiagnosticMessageId, Session};
 use syntax::symbol::Symbol;
@@ -25,12 +26,9 @@
 use syntax::ast::{NodeId, Attribute};
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::attr::{self, Stability, Deprecation};
+use ty::{self, TyCtxt};
 use util::nodemap::{FxHashSet, FxHashMap};
 
-use hir;
-use hir::{Item, Generics, StructField, Variant, HirId};
-use hir::intravisit::{self, Visitor, NestedVisitorMap};
-
 use std::mem::replace;
 use std::cmp::Ordering;
 
@@ -188,7 +186,7 @@
                     }
                 }
 
-                let hir_id = self.tcx.hir.node_to_hir_id(id);
+                let hir_id = self.tcx.hir().node_to_hir_id(id);
                 self.index.stab_map.insert(hir_id, stab);
 
                 let orig_parent_stab = replace(&mut self.parent_stab, Some(stab));
@@ -198,7 +196,7 @@
                 debug!("annotate: not found, parent = {:?}", self.parent_stab);
                 if let Some(stab) = self.parent_stab {
                     if stab.level.is_unstable() {
-                        let hir_id = self.tcx.hir.node_to_hir_id(id);
+                        let hir_id = self.tcx.hir().node_to_hir_id(id);
                         self.index.stab_map.insert(hir_id, stab);
                     }
                 }
@@ -219,7 +217,7 @@
             // -Zforce-unstable-if-unmarked is set.
             if let Some(stab) = self.parent_stab {
                 if stab.level.is_unstable() {
-                    let hir_id = self.tcx.hir.node_to_hir_id(id);
+                    let hir_id = self.tcx.hir().node_to_hir_id(id);
                     self.index.stab_map.insert(hir_id, stab);
                 }
             }
@@ -230,7 +228,7 @@
                 }
 
                 // `Deprecation` is just two pointers, no need to intern it
-                let hir_id = self.tcx.hir.node_to_hir_id(id);
+                let hir_id = self.tcx.hir().node_to_hir_id(id);
                 let depr_entry = DeprecationEntry::local(depr, hir_id);
                 self.index.depr_map.insert(hir_id, depr_entry.clone());
 
@@ -239,7 +237,7 @@
                 visit_children(self);
                 self.parent_depr = orig_parent_depr;
             } else if let Some(parent_depr) = self.parent_depr.clone() {
-                let hir_id = self.tcx.hir.node_to_hir_id(id);
+                let hir_id = self.tcx.hir().node_to_hir_id(id);
                 self.index.depr_map.insert(hir_id, parent_depr);
                 visit_children(self);
             } else {
@@ -254,7 +252,7 @@
     /// nested items in the context of the outer item, so enable
     /// deep-walking.
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.tcx.hir)
+        NestedVisitorMap::All(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, i: &'tcx Item) {
@@ -333,7 +331,7 @@
 
 impl<'a, 'tcx: 'a> MissingStabilityAnnotations<'a, 'tcx> {
     fn check_missing_stability(&self, id: NodeId, span: Span) {
-        let hir_id = self.tcx.hir.node_to_hir_id(id);
+        let hir_id = self.tcx.hir().node_to_hir_id(id);
         let stab = self.tcx.stability().local_stability(hir_id);
         let is_error = !self.tcx.sess.opts.test &&
                         stab.is_none() &&
@@ -346,7 +344,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, i: &'tcx Item) {
@@ -369,7 +367,7 @@
     }
 
     fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
-        let impl_def_id = self.tcx.hir.local_def_id(self.tcx.hir.get_parent(ii.id));
+        let impl_def_id = self.tcx.hir().local_def_id(self.tcx.hir().get_parent(ii.id));
         if self.tcx.impl_trait_ref(impl_def_id).is_none() {
             self.check_missing_stability(ii.id, ii.span);
         }
@@ -416,7 +414,7 @@
         index.active_features = active_lib_features.iter().map(|&(ref s, _)| s.clone()).collect();
 
         {
-            let krate = tcx.hir.krate();
+            let krate = tcx.hir().krate();
             let mut annotator = Annotator {
                 tcx,
                 index: &mut index,
@@ -470,14 +468,14 @@
 /// features and possibly prints errors.
 pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut checker = Checker { tcx };
-    tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
+    tcx.hir().krate().visit_all_item_likes(&mut checker.as_deep_visitor());
 }
 
 /// Check whether an item marked with `deprecated(since="X")` is currently
-/// deprecated (i.e. whether X is not greater than the current rustc version).
+/// deprecated (i.e., whether X is not greater than the current rustc version).
 pub fn deprecation_in_effect(since: &str) -> bool {
     fn parse_version(ver: &str) -> Vec<u32> {
-        // We ignore non-integer components of the version (e.g. "nightly").
+        // We ignore non-integer components of the version (e.g., "nightly").
         ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
     }
 
@@ -518,7 +516,7 @@
 }
 
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-    // (See issue #38412)
+    // See issue #38412.
     fn skip_stability_check_due_to_privacy(self, mut def_id: DefId) -> bool {
         // Check if `def_id` is a trait method.
         match self.describe_def(def_id) {
@@ -528,8 +526,8 @@
                 if let ty::TraitContainer(trait_def_id) = self.associated_item(def_id).container {
                     // Trait methods do not declare visibility (even
                     // for visibility info in cstore). Use containing
-                    // trait instead, so methods of pub traits are
-                    // themselves considered pub.
+                    // trait instead, so methods of `pub` traits are
+                    // themselves considered `pub`.
                     def_id = trait_def_id;
                 }
             }
@@ -539,10 +537,10 @@
         let visibility = self.visibility(def_id);
 
         match visibility {
-            // must check stability for pub items.
+            // Must check stability for `pub` items.
             ty::Visibility::Public => false,
 
-            // these are not visible outside crate; therefore
+            // These are not visible outside crate; therefore
             // stability markers are irrelevant, if even present.
             ty::Visibility::Restricted(..) |
             ty::Visibility::Invisible => true,
@@ -591,7 +589,7 @@
                     false
                 };
 
-                let parent_def_id = self.hir.local_def_id(self.hir.get_parent(id));
+                let parent_def_id = self.hir().local_def_id(self.hir().get_parent(id));
                 let skip = deprecated_in_future_version ||
                            self.lookup_deprecation_entry(parent_def_id)
                                .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
@@ -628,7 +626,7 @@
             return EvalResult::Allow;
         }
 
-        // Issue 38412: private items lack stability markers.
+        // Issue #38412: private items lack stability markers.
         if self.skip_stability_check_due_to_privacy(def_id) {
             return EvalResult::Allow;
         }
@@ -644,7 +642,7 @@
                 // crates also pulled in from crates.io. We want to ideally be
                 // able to compile everything without requiring upstream
                 // modifications, so in the case that this looks like a
-                // rustc_private crate (e.g. a compiler crate) and we also have
+                // `rustc_private` crate (e.g., a compiler crate) and we also have
                 // the `-Z force-unstable-if-unmarked` flag present (we're
                 // compiling a compiler crate), then let this missing feature
                 // annotation slide.
@@ -717,7 +715,7 @@
     /// nested items in the context of the outer item, so enable
     /// deep-walking.
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
@@ -726,7 +724,7 @@
                 // compiler-generated `extern crate` items have a dummy span.
                 if item.span.is_dummy() { return }
 
-                let def_id = self.tcx.hir.local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id(item.id);
                 let cnum = match self.tcx.extern_mod_stmt_cnum(def_id) {
                     Some(cnum) => cnum,
                     None => return,
@@ -741,7 +739,7 @@
             hir::ItemKind::Impl(.., Some(ref t), _, ref impl_item_refs) => {
                 if let Def::Trait(trait_did) = t.path.def {
                     for impl_item_ref in impl_item_refs {
-                        let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
+                        let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                         let trait_item_def_id = self.tcx.associated_items(trait_did)
                             .find(|item| item.ident.name == impl_item.ident.name)
                             .map(|item| item.def_id);
@@ -756,7 +754,7 @@
             // There's no good place to insert stability check for non-Copy unions,
             // so semi-randomly perform it here in stability.rs
             hir::ItemKind::Union(..) if !self.tcx.features().untagged_unions => {
-                let def_id = self.tcx.hir.local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id(item.id);
                 let adt_def = self.tcx.adt_def(def_id);
                 let ty = self.tcx.type_of(def_id);
 
@@ -780,7 +778,7 @@
     }
 
     fn visit_path(&mut self, path: &'tcx hir::Path, id: hir::HirId) {
-        let id = self.tcx.hir.hir_to_node_id(id);
+        let id = self.tcx.hir().hir_to_node_id(id);
         if let Some(def_id) = path.def.opt_def_id() {
             self.tcx.check_stability(def_id, Some(id), path.span)
         }
@@ -794,14 +792,14 @@
     }
 }
 
-/// Given the list of enabled features that were not language features (i.e. that
+/// Given the list of enabled features that were not language features (i.e., that
 /// were expected to be library features), and the list of features used from
 /// libraries, identify activated features that don't exist and error about them.
 pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
 
     if tcx.stability().staged_api[&LOCAL_CRATE] {
-        let krate = tcx.hir.krate();
+        let krate = tcx.hir().krate();
         let mut missing = MissingStabilityAnnotations {
             tcx,
             access_levels,
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index 0d40776..824ccda 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -49,7 +49,7 @@
 
     {
         let mut cx = Context { tcx, items };
-        tcx.hir.krate().visit_all_item_likes(&mut cx.as_deep_visitor());
+        tcx.hir().krate().visit_all_item_likes(&mut cx.as_deep_visitor());
     }
     verify(tcx, items);
 }
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 503e0ab..8b16aaf 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -183,50 +183,14 @@
 impl<'tcx> EvalError<'tcx> {
     pub fn print_backtrace(&mut self) {
         if let Some(ref mut backtrace) = self.backtrace {
-            eprintln!("{}", print_backtrace(&mut *backtrace));
+            print_backtrace(&mut *backtrace);
         }
     }
 }
 
-fn print_backtrace(backtrace: &mut Backtrace) -> String {
-    use std::fmt::Write;
-
+fn print_backtrace(backtrace: &mut Backtrace) {
     backtrace.resolve();
-
-    let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
-    write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap();
-    'frames: for (i, frame) in backtrace.frames().iter().enumerate() {
-        if frame.symbols().is_empty() {
-            write!(trace_text, "  {}: no symbols\n", i).unwrap();
-        }
-        let mut first = true;
-        for symbol in frame.symbols() {
-            if first {
-                write!(trace_text, "  {}: ", i).unwrap();
-                first = false;
-            } else {
-                let len = i.to_string().len();
-                write!(trace_text, "  {}  ", " ".repeat(len)).unwrap();
-            }
-            if let Some(name) = symbol.name() {
-                write!(trace_text, "{}\n", name).unwrap();
-            } else {
-                write!(trace_text, "<unknown>\n").unwrap();
-            }
-            write!(trace_text, "           at ").unwrap();
-            if let Some(file_path) = symbol.filename() {
-                write!(trace_text, "{}", file_path.display()).unwrap();
-            } else {
-                write!(trace_text, "<unknown_file>").unwrap();
-            }
-            if let Some(line) = symbol.lineno() {
-                write!(trace_text, ":{}\n", line).unwrap();
-            } else {
-                write!(trace_text, "\n").unwrap();
-            }
-        }
-    }
-    trace_text
+    eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
 }
 
 impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
@@ -238,7 +202,7 @@
 
                 if val == "immediate" {
                     // Print it now
-                    eprintln!("{}", print_backtrace(&mut backtrace));
+                    print_backtrace(&mut backtrace);
                     None
                 } else {
                     Some(Box::new(backtrace))
@@ -378,7 +342,7 @@
                 "tried to read from foreign (extern) static",
             InvalidPointerMath =>
                 "attempted to do invalid arithmetic on pointers that would leak base addresses, \
-                e.g. comparing pointers into different allocations",
+                e.g., comparing pointers into different allocations",
             ReadUndefBytes(_) =>
                 "attempted to read undefined bytes",
             DeadLocal =>
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index 9369b6e..d54a1c9 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -41,7 +41,6 @@
 use ty::layout::{self, Size};
 use middle::region;
 use std::io;
-use std::hash::Hash;
 use rustc_serialize::{Encoder, Decodable, Encodable};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{Lock as Mutex, HashMapExt};
@@ -90,7 +89,7 @@
 impl ::rustc_serialize::UseSpecializedDecodable for AllocId {}
 
 #[derive(RustcDecodable, RustcEncodable)]
-enum AllocKind {
+enum AllocDiscriminant {
     Alloc,
     Fn,
     Static,
@@ -104,23 +103,23 @@
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     alloc_id: AllocId,
 ) -> Result<(), E::Error> {
-    let alloc_type: AllocType<'tcx, &'tcx Allocation> =
+    let alloc_kind: AllocKind<'tcx> =
         tcx.alloc_map.lock().get(alloc_id).expect("no value for AllocId");
-    match alloc_type {
-        AllocType::Memory(alloc) => {
+    match alloc_kind {
+        AllocKind::Memory(alloc) => {
             trace!("encoding {:?} with {:#?}", alloc_id, alloc);
-            AllocKind::Alloc.encode(encoder)?;
+            AllocDiscriminant::Alloc.encode(encoder)?;
             alloc.encode(encoder)?;
         }
-        AllocType::Function(fn_instance) => {
+        AllocKind::Function(fn_instance) => {
             trace!("encoding {:?} with {:#?}", alloc_id, fn_instance);
-            AllocKind::Fn.encode(encoder)?;
+            AllocDiscriminant::Fn.encode(encoder)?;
             fn_instance.encode(encoder)?;
         }
-        AllocType::Static(did) => {
+        AllocKind::Static(did) => {
             // referring to statics doesn't need to know about their allocations,
             // just about its DefId
-            AllocKind::Static.encode(encoder)?;
+            AllocDiscriminant::Static.encode(encoder)?;
             did.encode(encoder)?;
         }
     }
@@ -189,10 +188,10 @@
         let idx = decoder.read_u32()? as usize;
         let pos = self.state.data_offsets[idx] as usize;
 
-        // Decode the AllocKind now so that we know if we have to reserve an
+        // Decode the AllocDiscriminant now so that we know if we have to reserve an
         // AllocId.
         let (alloc_kind, pos) = decoder.with_position(pos, |decoder| {
-            let alloc_kind = AllocKind::decode(decoder)?;
+            let alloc_kind = AllocDiscriminant::decode(decoder)?;
             Ok((alloc_kind, decoder.position()))
         })?;
 
@@ -208,7 +207,7 @@
                 ref mut entry @ State::Empty => {
                     // We are allowed to decode
                     match alloc_kind {
-                        AllocKind::Alloc => {
+                        AllocDiscriminant::Alloc => {
                             // If this is an allocation, we need to reserve an
                             // AllocId so we can decode cyclic graphs.
                             let alloc_id = decoder.tcx().alloc_map.lock().reserve();
@@ -217,7 +216,7 @@
                                 alloc_id);
                             Some(alloc_id)
                         },
-                        AllocKind::Fn | AllocKind::Static => {
+                        AllocDiscriminant::Fn | AllocDiscriminant::Static => {
                             // Fns and statics cannot be cyclic and their AllocId
                             // is determined later by interning
                             *entry = State::InProgressNonAlloc(
@@ -251,15 +250,15 @@
         // Now decode the actual data
         let alloc_id = decoder.with_position(pos, |decoder| {
             match alloc_kind {
-                AllocKind::Alloc => {
+                AllocDiscriminant::Alloc => {
                     let allocation = <&'tcx Allocation as Decodable>::decode(decoder)?;
                     // We already have a reserved AllocId.
                     let alloc_id = alloc_id.unwrap();
                     trace!("decoded alloc {:?} {:#?}", alloc_id, allocation);
-                    decoder.tcx().alloc_map.lock().set_id_same_memory(alloc_id, allocation);
+                    decoder.tcx().alloc_map.lock().set_alloc_id_same_memory(alloc_id, allocation);
                     Ok(alloc_id)
                 },
-                AllocKind::Fn => {
+                AllocDiscriminant::Fn => {
                     assert!(alloc_id.is_none());
                     trace!("creating fn alloc id");
                     let instance = ty::Instance::decode(decoder)?;
@@ -267,7 +266,7 @@
                     let alloc_id = decoder.tcx().alloc_map.lock().create_fn_alloc(instance);
                     Ok(alloc_id)
                 },
-                AllocKind::Static => {
+                AllocDiscriminant::Static => {
                     assert!(alloc_id.is_none());
                     trace!("creating extern static alloc id at");
                     let did = DefId::decode(decoder)?;
@@ -292,39 +291,42 @@
 }
 
 #[derive(Debug, Clone, Eq, PartialEq, Hash, RustcDecodable, RustcEncodable)]
-pub enum AllocType<'tcx, M> {
+pub enum AllocKind<'tcx> {
     /// The alloc id is used as a function pointer
     Function(Instance<'tcx>),
     /// The alloc id points to a "lazy" static variable that did not get computed (yet).
     /// This is also used to break the cycle in recursive statics.
     Static(DefId),
     /// The alloc id points to memory
-    Memory(M)
+    Memory(&'tcx Allocation),
 }
 
-pub struct AllocMap<'tcx, M> {
+pub struct AllocMap<'tcx> {
     /// Lets you know what an AllocId refers to
-    id_to_type: FxHashMap<AllocId, AllocType<'tcx, M>>,
+    id_to_kind: FxHashMap<AllocId, AllocKind<'tcx>>,
 
-    /// Used to ensure that functions and statics only get one associated AllocId
-    type_interner: FxHashMap<AllocType<'tcx, M>, AllocId>,
+    /// Used to ensure that statics only get one associated AllocId
+    type_interner: FxHashMap<AllocKind<'tcx>, AllocId>,
 
     /// The AllocId to assign to the next requested id.
     /// Always incremented, never gets smaller.
     next_id: AllocId,
 }
 
-impl<'tcx, M: fmt::Debug + Eq + Hash + Clone> AllocMap<'tcx, M> {
+impl<'tcx> AllocMap<'tcx> {
     pub fn new() -> Self {
         AllocMap {
-            id_to_type: Default::default(),
+            id_to_kind: Default::default(),
             type_interner: Default::default(),
             next_id: AllocId(0),
         }
     }
 
-    /// obtains a new allocation ID that can be referenced but does not
+    /// Obtains a new allocation ID that can be referenced but does not
     /// yet have an allocation backing it.
+    ///
+    /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such
+    /// an `AllocId` from a query.
     pub fn reserve(
         &mut self,
     ) -> AllocId {
@@ -337,53 +339,73 @@
         next
     }
 
-    fn intern(&mut self, alloc_type: AllocType<'tcx, M>) -> AllocId {
-        if let Some(&alloc_id) = self.type_interner.get(&alloc_type) {
+    fn intern(&mut self, alloc_kind: AllocKind<'tcx>) -> AllocId {
+        if let Some(&alloc_id) = self.type_interner.get(&alloc_kind) {
             return alloc_id;
         }
         let id = self.reserve();
-        debug!("creating alloc_type {:?} with id {}", alloc_type, id);
-        self.id_to_type.insert(id, alloc_type.clone());
-        self.type_interner.insert(alloc_type, id);
+        debug!("creating alloc_kind {:?} with id {}", alloc_kind, id);
+        self.id_to_kind.insert(id, alloc_kind.clone());
+        self.type_interner.insert(alloc_kind, id);
         id
     }
 
-    // FIXME: Check if functions have identity. If not, we should not intern these,
-    // but instead create a new id per use.
-    // Alternatively we could just make comparing function pointers an error.
+    /// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
+    /// by the linker and functions can be duplicated across crates.
+    /// We thus generate a new `AllocId` for every mention of a function. This means that
+    /// `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
     pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> AllocId {
-        self.intern(AllocType::Function(instance))
+        let id = self.reserve();
+        self.id_to_kind.insert(id, AllocKind::Function(instance));
+        id
     }
 
-    pub fn get(&self, id: AllocId) -> Option<AllocType<'tcx, M>> {
-        self.id_to_type.get(&id).cloned()
+    /// Returns `None` in case the `AllocId` is dangling. An `EvalContext` can still have a
+    /// local `Allocation` for that `AllocId`, but having such an `AllocId` in a constant is
+    /// illegal and will likely ICE.
+    /// This function exists to allow const eval to detect the difference between evaluation-
+    /// local dangling pointers and allocations in constants/statics.
+    pub fn get(&self, id: AllocId) -> Option<AllocKind<'tcx>> {
+        self.id_to_kind.get(&id).cloned()
     }
 
-    pub fn unwrap_memory(&self, id: AllocId) -> M {
+    /// Panics if the `AllocId` does not refer to an `Allocation`
+    pub fn unwrap_memory(&self, id: AllocId) -> &'tcx Allocation {
         match self.get(id) {
-            Some(AllocType::Memory(mem)) => mem,
+            Some(AllocKind::Memory(mem)) => mem,
             _ => bug!("expected allocation id {} to point to memory", id),
         }
     }
 
+    /// Generate an `AllocId` for a static or return a cached one in case this function has been
+    /// called on the same static before.
     pub fn intern_static(&mut self, static_id: DefId) -> AllocId {
-        self.intern(AllocType::Static(static_id))
+        self.intern(AllocKind::Static(static_id))
     }
 
-    pub fn allocate(&mut self, mem: M) -> AllocId {
+    /// Intern the `Allocation` and return a new `AllocId`, even if there's already an identical
+    /// `Allocation` with a different `AllocId`.
+    // FIXME: is this really necessary? Can we ensure `FOO` and `BAR` being different after codegen
+    // in `static FOO: u32 = 42; static BAR: u32 = 42;` even if they reuse the same allocation
+    // inside rustc?
+    pub fn allocate(&mut self, mem: &'tcx Allocation) -> AllocId {
         let id = self.reserve();
-        self.set_id_memory(id, mem);
+        self.set_alloc_id_memory(id, mem);
         id
     }
 
-    pub fn set_id_memory(&mut self, id: AllocId, mem: M) {
-        if let Some(old) = self.id_to_type.insert(id, AllocType::Memory(mem)) {
+    /// Freeze an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
+    /// call this function twice, even with the same `Allocation` will ICE the compiler.
+    pub fn set_alloc_id_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
+        if let Some(old) = self.id_to_kind.insert(id, AllocKind::Memory(mem)) {
             bug!("tried to set allocation id {}, but it was already existing as {:#?}", id, old);
         }
     }
 
-    pub fn set_id_same_memory(&mut self, id: AllocId, mem: M) {
-       self.id_to_type.insert_same(id, AllocType::Memory(mem));
+    /// Freeze an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called
+    /// twice for the same `(AllocId, Allocation)` pair.
+    fn set_alloc_id_same_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
+        self.id_to_kind.insert_same(id, AllocKind::Memory(mem));
     }
 }
 
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 500bd47..b8d4c5a 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -18,7 +18,7 @@
 /// Represents the result of a raw const operation, pre-validation.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
 pub struct RawConst<'tcx> {
-    // the value lives here, at offset 0, and that allocation definitely is a `AllocType::Memory`
+    // the value lives here, at offset 0, and that allocation definitely is a `AllocKind::Memory`
     // (so you can use `AllocMap::unwrap_memory`).
     pub alloc_id: AllocId,
     pub ty: Ty<'tcx>,
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 9166355..68b5c3e 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -339,7 +339,7 @@
     #[inline]
     pub fn args_iter(&self) -> impl Iterator<Item = Local> {
         let arg_count = self.arg_count;
-        (1..arg_count + 1).map(Local::new)
+        (1..=arg_count).map(Local::new)
     }
 
     /// Returns an iterator over all user-defined variables and compiler-generated temporaries (all
@@ -556,7 +556,7 @@
     /// Data is mutable and not aliasable.
     Mut {
         /// True if this borrow arose from method-call auto-ref
-        /// (i.e. `adjustment::Adjust::Borrow`)
+        /// (i.e., `adjustment::Adjust::Borrow`)
         allow_two_phase_borrow: bool,
     },
 }
@@ -692,7 +692,7 @@
 /// expression; that is, a block like `{ STMT_1; STMT_2; EXPR }`.
 ///
 /// It is used to improve diagnostics when such temporaries are
-/// involved in borrow_check errors, e.g. explanations of where the
+/// involved in borrow_check errors, e.g., explanations of where the
 /// temporaries come from, when their destructors are run, and/or how
 /// one might revise the code to satisfy the borrow checker's rules.
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
@@ -701,7 +701,7 @@
     /// expression is ignored by the block's expression context.
     ///
     /// Examples include `{ ...; tail };` and `let _ = { ...; tail };`
-    /// but not e.g. `let _x = { ...; tail };`
+    /// but not e.g., `let _x = { ...; tail };`
     pub tail_result_is_ignored: bool,
 }
 
@@ -756,7 +756,7 @@
     pub ty: Ty<'tcx>,
 
     /// If the user manually ascribed a type to this variable,
-    /// e.g. via `let x: T`, then we carry that type here. The MIR
+    /// e.g., via `let x: T`, then we carry that type here. The MIR
     /// borrow checker needs this information since it can affect
     /// region inference.
     pub user_ty: UserTypeProjections<'tcx>,
@@ -767,7 +767,7 @@
     /// to generate better debuginfo.
     pub name: Option<Name>,
 
-    /// The *syntactic* (i.e. not visibility) source scope the local is defined
+    /// The *syntactic* (i.e., not visibility) source scope the local is defined
     /// in. If the local was defined in a let-statement, this
     /// is *within* the let-statement, rather than outside
     /// of it.
@@ -1745,7 +1745,7 @@
     Assign(Place<'tcx>, Box<Rvalue<'tcx>>),
 
     /// This represents all the reading that a pattern match may do
-    /// (e.g. inspecting constants and discriminant values), and the
+    /// (e.g., inspecting constants and discriminant values), and the
     /// kind of pattern it comes from. This is in order to adapt potential
     /// error messages to these specific patterns.
     FakeRead(FakeReadCause, Place<'tcx>),
@@ -2180,7 +2180,7 @@
 
     /// Read the discriminant of an ADT.
     ///
-    /// Undefined (i.e. no effort is made to make it defined, but there’s no reason why it cannot
+    /// Undefined (i.e., no effort is made to make it defined, but there’s no reason why it cannot
     /// be defined to return, say, a 0) if ADT is not an enum.
     Discriminant(Place<'tcx>),
 
@@ -2222,7 +2222,7 @@
     /// The second field is the variant index. It's equal to 0 for struct
     /// and union expressions. The fourth field is
     /// active field number and is present only for union expressions
-    /// -- e.g. for a union expression `SomeUnion { c: .. }`, the
+    /// -- e.g., for a union expression `SomeUnion { c: .. }`, the
     /// active field index would identity the field `c`
     Adt(
         &'tcx AdtDef,
@@ -2376,17 +2376,17 @@
                     }
 
                     AggregateKind::Closure(def_id, _) => ty::tls::with(|tcx| {
-                        if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
+                        if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
                             let name = if tcx.sess.opts.debugging_opts.span_free_formats {
                                 format!("[closure@{:?}]", node_id)
                             } else {
-                                format!("[closure@{:?}]", tcx.hir.span(node_id))
+                                format!("[closure@{:?}]", tcx.hir().span(node_id))
                             };
                             let mut struct_fmt = fmt.debug_struct(&name);
 
                             tcx.with_freevars(node_id, |freevars| {
                                 for (freevar, place) in freevars.iter().zip(places) {
-                                    let var_name = tcx.hir.name(freevar.var_id());
+                                    let var_name = tcx.hir().name(freevar.var_id());
                                     struct_fmt.field(&var_name.as_str(), place);
                                 }
                             });
@@ -2398,13 +2398,13 @@
                     }),
 
                     AggregateKind::Generator(def_id, _, _) => ty::tls::with(|tcx| {
-                        if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-                            let name = format!("[generator@{:?}]", tcx.hir.span(node_id));
+                        if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
+                            let name = format!("[generator@{:?}]", tcx.hir().span(node_id));
                             let mut struct_fmt = fmt.debug_struct(&name);
 
                             tcx.with_freevars(node_id, |freevars| {
                                 for (freevar, place) in freevars.iter().zip(places) {
-                                    let var_name = tcx.hir.name(freevar.var_id());
+                                    let var_name = tcx.hir().name(freevar.var_id());
                                     struct_fmt.field(&var_name.as_str(), place);
                                 }
                                 struct_fmt.field("$state", &places[freevars.len()]);
@@ -2637,7 +2637,7 @@
                 if let Ref(_, &ty::TyS { sty: Str, .. }, _) = ty.sty {
                     return ty::tls::with(|tcx| {
                         let alloc = tcx.alloc_map.lock().get(ptr.alloc_id);
-                        if let Some(interpret::AllocType::Memory(alloc)) = alloc {
+                        if let Some(interpret::AllocKind::Memory(alloc)) = alloc {
                             assert_eq!(len as usize as u128, len);
                             let slice =
                                 &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
@@ -2905,6 +2905,7 @@
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub enum ConstraintCategory {
     Return,
+    Yield,
     UseAsConst,
     UseAsStatic,
     TypeAnnotation,
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index ff2bf3d..c96cbd4 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -272,7 +272,7 @@
     ///
     /// The '.' before `<special-suffix>` makes sure that names with a special
     /// suffix can never collide with a name built out of regular Rust
-    /// identifiers (e.g. module paths).
+    /// identifiers (e.g., module paths).
     pub fn build_cgu_name<I, C, S>(&mut self,
                                    cnum: CrateNum,
                                    components: I,
diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs
index f3a0b7d..4424ba0 100644
--- a/src/librustc/mir/traversal.rs
+++ b/src/librustc/mir/traversal.rs
@@ -253,7 +253,7 @@
 /// ```
 ///
 /// A reverse postorder traversal of this graph is either `A B C D` or `A C B D`
-/// Note that for a graph containing no loops (i.e. A DAG), this is equivalent to
+/// Note that for a graph containing no loops (i.e., A DAG), this is equivalent to
 /// a topological sort.
 ///
 /// Construction of a `ReversePostorder` traversal requires doing a full
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index d40d85a..237f6bc 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -33,7 +33,7 @@
 // in that circumstance.
 //
 // For the most part, we do not destructure things external to the
-// MIR, e.g. types, spans, etc, but simply visit them and stop. This
+// MIR, e.g., types, spans, etc, but simply visit them and stop. This
 // avoids duplication with other visitors like `TypeFoldable`.
 //
 // ## Updating
@@ -997,7 +997,7 @@
     ShallowBorrow(Region<'tcx>),
     /// Unique borrow.
     UniqueBorrow(Region<'tcx>),
-    /// Used as base for another place, e.g. `x` in `x.y`. Will not mutate the place.
+    /// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place.
     /// For example, the projection `x.y` is not marked as a mutation in these cases:
     ///
     ///     z = x.y;
@@ -1020,7 +1020,7 @@
     Drop,
     /// Mutable borrow.
     Borrow(Region<'tcx>),
-    /// Used as base for another place, e.g. `x` in `x.y`. Could potentially mutate the place.
+    /// Used as base for another place, e.g., `x` in `x.y`. Could potentially mutate the place.
     /// For example, the projection `x.y` is marked as a mutation in these cases:
     ///
     ///     x.y = ...;
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index c986623..b58d80e 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -14,7 +14,7 @@
 use std::str::FromStr;
 
 use session::{early_error, early_warn, Session};
-use session::search_paths::SearchPaths;
+use session::search_paths::SearchPath;
 
 use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel};
 use rustc_target::spec::{Target, TargetTriple};
@@ -374,7 +374,7 @@
         lint_cap: Option<lint::Level> [TRACKED],
         describe_lints: bool [UNTRACKED],
         output_types: OutputTypes [TRACKED],
-        search_paths: SearchPaths [UNTRACKED],
+        search_paths: Vec<SearchPath> [UNTRACKED],
         libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
         maybe_sysroot: Option<PathBuf> [TRACKED],
 
@@ -593,7 +593,7 @@
             lint_cap: None,
             describe_lints: false,
             output_types: OutputTypes(BTreeMap::new()),
-            search_paths: SearchPaths::new(),
+            search_paths: vec![],
             maybe_sysroot: None,
             target_triple: TargetTriple::from_triple(host_triple()),
             test: false,
@@ -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");
     }
@@ -1136,6 +1135,8 @@
         "enable incremental compilation"),
     default_linker_libraries: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
         "allow the linker to link its default libraries"),
+    linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
+                                           "Linker flavor"),
 }
 
 options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
@@ -1273,7 +1274,13 @@
     arg_align_attributes: bool = (false, parse_bool, [TRACKED],
         "emit align metadata for reference arguments"),
     dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED],
-        "dump MIR state at various points in transforms"),
+        "dump MIR state to file.
+        `val` is used to select which passes and functions to dump. For example:
+        `all` matches all passes and functions,
+        `foo` matches all passes for functions whose name contains 'foo',
+        `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo',
+        `foo | bar` all passes for function names containing 'foo' or 'bar'."),
+
     dump_mir_dir: String = (String::from("mir_dump"), parse_string, [UNTRACKED],
         "the directory the MIR is dumped into"),
     dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED],
@@ -1281,7 +1288,7 @@
     dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED],
         "if set, exclude the pass number when dumping MIR (used in tests)"),
     mir_emit_retag: bool = (false, parse_bool, [TRACKED],
-        "emit Retagging MIR statements, interpreted e.g. by miri; implies -Zmir-opt-level=0"),
+        "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0"),
     perf_stats: bool = (false, parse_bool, [UNTRACKED],
         "print some performance-related statistics"),
     hir_stats: bool = (false, parse_bool, [UNTRACKED],
@@ -1292,8 +1299,6 @@
         "pass `-install_name @rpath/...` to the macOS linker"),
     sanitizer: Option<Sanitizer> = (None, parse_sanitizer, [TRACKED],
                                     "Use a sanitizer"),
-    linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
-                                           "Linker flavor"),
     fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
         "set the optimization fuel quota for a crate"),
     print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
@@ -1533,7 +1538,7 @@
 // adds extra rustc-specific metadata to each option; such metadata
 // is exposed by .  The public
 // functions below ending with `_u` are the functions that return
-// *unstable* options, i.e. options that are only enabled when the
+// *unstable* options, i.e., options that are only enabled when the
 // user also passes the `-Z unstable-options` debugging flag.
 mod opt {
     // The `fn opt_u` etc below are written so that we can use them
@@ -2110,9 +2115,9 @@
         }
     };
 
-    let mut search_paths = SearchPaths::new();
+    let mut search_paths = vec![];
     for s in &matches.opt_strs("L") {
-        search_paths.add_path(&s[..], error_format);
+        search_paths.push(SearchPath::from_cli_opt(&s[..], error_format));
     }
 
     let libs = matches
@@ -2381,7 +2386,7 @@
 /// tracking are hashed into a single value that determines whether the
 /// incremental compilation cache can be re-used or not. This hashing is done
 /// via the DepTrackingHash trait defined below, since the standard Hash
-/// implementation might not be suitable (e.g. arguments are stored in a Vec,
+/// implementation might not be suitable (e.g., arguments are stored in a Vec,
 /// the hash of which is order dependent, but we might not want the order of
 /// arguments to make a difference for the hash).
 ///
@@ -2530,6 +2535,7 @@
     use session::config::{build_configuration, build_session_options_and_crate_config};
     use session::config::{LtoCli, CrossLangLto};
     use session::build_session;
+    use session::search_paths::SearchPath;
     use std::collections::{BTreeMap, BTreeSet};
     use std::iter::FromIterator;
     use std::path::PathBuf;
@@ -2785,48 +2791,48 @@
 
         // Reference
         v1.search_paths
-            .add_path("native=abc", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
         v1.search_paths
-            .add_path("crate=def", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
         v1.search_paths
-            .add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
         v1.search_paths
-            .add_path("framework=jkl", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
         v1.search_paths
-            .add_path("all=mno", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));
 
         v2.search_paths
-            .add_path("native=abc", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
         v2.search_paths
-            .add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
         v2.search_paths
-            .add_path("crate=def", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
         v2.search_paths
-            .add_path("framework=jkl", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
         v2.search_paths
-            .add_path("all=mno", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));
 
         v3.search_paths
-            .add_path("crate=def", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
         v3.search_paths
-            .add_path("framework=jkl", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
         v3.search_paths
-            .add_path("native=abc", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
         v3.search_paths
-            .add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
         v3.search_paths
-            .add_path("all=mno", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));
 
         v4.search_paths
-            .add_path("all=mno", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));
         v4.search_paths
-            .add_path("native=abc", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
         v4.search_paths
-            .add_path("crate=def", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
         v4.search_paths
-            .add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
         v4.search_paths
-            .add_path("framework=jkl", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
 
         assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash());
         assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash());
diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs
index f410c27..c204556 100644
--- a/src/librustc/session/filesearch.rs
+++ b/src/librustc/session/filesearch.rs
@@ -12,13 +12,12 @@
 
 pub use self::FileMatch::*;
 
-use rustc_data_structures::fx::FxHashSet;
 use std::borrow::Cow;
 use std::env;
 use std::fs;
 use std::path::{Path, PathBuf};
 
-use session::search_paths::{SearchPaths, PathKind};
+use session::search_paths::{SearchPath, PathKind};
 use rustc_fs_util::fix_windows_verbatim_for_gcc;
 
 #[derive(Copy, Clone)]
@@ -30,31 +29,19 @@
 // A module for searching for libraries
 
 pub struct FileSearch<'a> {
-    pub sysroot: &'a Path,
-    pub search_paths: &'a SearchPaths,
-    pub triple: &'a str,
-    pub kind: PathKind,
+    sysroot: &'a Path,
+    triple: &'a str,
+    search_paths: &'a [SearchPath],
+    tlib_path: &'a SearchPath,
+    kind: PathKind,
 }
 
 impl<'a> FileSearch<'a> {
-    pub fn for_each_lib_search_path<F>(&self, mut f: F) where
-        F: FnMut(&Path, PathKind)
-    {
-        let mut visited_dirs = FxHashSet::default();
-        visited_dirs.reserve(self.search_paths.paths.len() + 1);
-        for (path, kind) in self.search_paths.iter(self.kind) {
-            f(path, kind);
-            visited_dirs.insert(path.to_path_buf());
-        }
-
-        debug!("filesearch: searching lib path");
-        let tlib_path = make_target_lib_path(self.sysroot,
-                                             self.triple);
-        if !visited_dirs.contains(&tlib_path) {
-            f(&tlib_path, PathKind::All);
-        }
-
-        visited_dirs.insert(tlib_path);
+    pub fn search_paths(&self) -> impl Iterator<Item = &'a SearchPath> {
+        let kind = self.kind;
+        self.search_paths.iter()
+            .filter(move |sp| sp.kind.matches(kind))
+            .chain(std::iter::once(self.tlib_path))
     }
 
     pub fn get_lib_path(&self) -> PathBuf {
@@ -64,14 +51,8 @@
     pub fn search<F>(&self, mut pick: F)
         where F: FnMut(&Path, PathKind) -> FileMatch
     {
-        self.for_each_lib_search_path(|lib_search_path, kind| {
-            debug!("searching {}", lib_search_path.display());
-            let files = match fs::read_dir(lib_search_path) {
-                Ok(files) => files,
-                Err(..) => return,
-            };
-            let files = files.filter_map(|p| p.ok().map(|s| s.path()))
-                             .collect::<Vec<_>>();
+        for search_path in self.search_paths() {
+            debug!("searching {}", search_path.dir.display());
             fn is_rlib(p: &Path) -> bool {
                 p.extension() == Some("rlib".as_ref())
             }
@@ -79,11 +60,11 @@
             // an rlib and a dylib we only read one of the files of
             // metadata, so in the name of speed, bring all rlib files to
             // the front of the search list.
-            let files1 = files.iter().filter(|p| is_rlib(p));
-            let files2 = files.iter().filter(|p| !is_rlib(p));
+            let files1 = search_path.files.iter().filter(|p| is_rlib(p));
+            let files2 = search_path.files.iter().filter(|p| !is_rlib(p));
             for path in files1.chain(files2) {
                 debug!("testing {}", path.display());
-                let maybe_picked = pick(path, kind);
+                let maybe_picked = pick(path, search_path.kind);
                 match maybe_picked {
                     FileMatches => {
                         debug!("picked {}", path.display());
@@ -93,29 +74,30 @@
                     }
                 }
             }
-        });
+        }
     }
 
     pub fn new(sysroot: &'a Path,
                triple: &'a str,
-               search_paths: &'a SearchPaths,
-               kind: PathKind) -> FileSearch<'a> {
+               search_paths: &'a Vec<SearchPath>,
+               tlib_path: &'a SearchPath,
+               kind: PathKind)
+               -> FileSearch<'a> {
         debug!("using sysroot = {}, triple = {}", sysroot.display(), triple);
         FileSearch {
             sysroot,
-            search_paths,
             triple,
+            search_paths,
+            tlib_path,
             kind,
         }
     }
 
-    // Returns a list of directories where target-specific dylibs might be located.
-    pub fn get_dylib_search_paths(&self) -> Vec<PathBuf> {
-        let mut paths = Vec::new();
-        self.for_each_lib_search_path(|lib_search_path, _| {
-            paths.push(lib_search_path.to_path_buf());
-        });
-        paths
+    // Returns just the directories within the search paths.
+    pub fn search_path_dirs(&self) -> Vec<PathBuf> {
+        self.search_paths()
+            .map(|sp| sp.dir.to_path_buf())
+            .collect()
     }
 
     // Returns a list of directories where target-specific tool binaries are located.
@@ -138,8 +120,7 @@
     p
 }
 
-fn make_target_lib_path(sysroot: &Path,
-                        target_triple: &str) -> PathBuf {
+pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
     sysroot.join(&relative_target_lib_path(sysroot, target_triple))
 }
 
@@ -176,15 +157,15 @@
     // of the directory where librustc is located, rather than where the rustc
     // binary is.
     // If --libdir is set during configuration to the value other than
-    // "lib" (i.e. non-default), this value is used (see issue #16552).
+    // "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 +179,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 d1c3acc..12b5646 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -19,8 +19,8 @@
 use lint::builtin::BuiltinLintDiagnostics;
 use middle::allocator::AllocatorKind;
 use middle::dependency_format;
-use session::search_paths::PathKind;
 use session::config::{OutputType, Lto};
+use session::search_paths::{PathKind, SearchPath};
 use util::nodemap::{FxHashMap, FxHashSet};
 use util::common::{duration_to_secs_str, ErrorReported};
 use util::common::ProfileQueriesMsg;
@@ -48,7 +48,7 @@
 use std::env;
 use std::fmt;
 use std::io::Write;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
 use std::time::Duration;
 use std::sync::mpsc;
 use std::sync::atomic::{AtomicUsize, Ordering};
@@ -64,12 +64,15 @@
     pub target: config::Config,
     pub host: Target,
     pub opts: config::Options,
+    pub host_tlib_path: SearchPath,
+    /// This is `None` if the host and target are the same.
+    pub target_tlib_path: Option<SearchPath>,
     pub parse_sess: ParseSess,
     /// 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 proc_macro_decls_static: Once<Option<ast::NodeId>>,
-    pub default_sysroot: Option<PathBuf>,
+    pub sysroot: PathBuf,
     /// The name of the root source file of the crate, in the local file system.
     /// `None` means that there is no source file.
     pub local_crate_source_file: Option<PathBuf>,
@@ -586,7 +589,7 @@
         // either return `No` or `ThinLocal`.
 
         // If processing command line options determined that we're incompatible
-        // with ThinLTO (e.g. `-C lto --emit llvm-ir`) then return that option.
+        // with ThinLTO (e.g., `-C lto --emit llvm-ir`) then return that option.
         if self.opts.cli_forced_thinlto_off {
             return config::Lto::No;
         }
@@ -694,27 +697,22 @@
         )
     }
 
-    pub fn sysroot<'a>(&'a self) -> &'a Path {
-        match self.opts.maybe_sysroot {
-            Some(ref sysroot) => sysroot,
-            None => self.default_sysroot
-                        .as_ref()
-                        .expect("missing sysroot and default_sysroot in Session"),
-        }
-    }
     pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
         filesearch::FileSearch::new(
-            self.sysroot(),
+            &self.sysroot,
             self.opts.target_triple.triple(),
             &self.opts.search_paths,
+            // target_tlib_path==None means it's the same as host_tlib_path.
+            self.target_tlib_path.as_ref().unwrap_or(&self.host_tlib_path),
             kind,
         )
     }
     pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
         filesearch::FileSearch::new(
-            self.sysroot(),
+            &self.sysroot,
             config::host_triple(),
             &self.opts.search_paths,
+            &self.host_tlib_path,
             kind,
         )
     }
@@ -826,7 +824,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);
         }
@@ -1109,9 +1107,18 @@
     let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
 
     let p_s = parse::ParseSess::with_span_handler(span_diagnostic, source_map);
-    let default_sysroot = match sopts.maybe_sysroot {
-        Some(_) => None,
-        None => Some(filesearch::get_or_default_sysroot()),
+    let sysroot = match &sopts.maybe_sysroot {
+        Some(sysroot) => sysroot.clone(),
+        None => filesearch::get_or_default_sysroot(),
+    };
+
+    let host_triple = config::host_triple();
+    let target_triple = sopts.target_triple.triple();
+    let host_tlib_path = SearchPath::from_sysroot_and_triple(&sysroot, host_triple);
+    let target_tlib_path = if host_triple == target_triple {
+        None
+    } else {
+        Some(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
     };
 
     let file_path_mapping = sopts.file_path_mapping();
@@ -1142,12 +1149,14 @@
         target: target_cfg,
         host,
         opts: sopts,
+        host_tlib_path,
+        target_tlib_path,
         parse_sess: p_s,
         // For a library crate, this is always none
         entry_fn: Once::new(),
         plugin_registrar_fn: Once::new(),
         proc_macro_decls_static: Once::new(),
-        default_sysroot,
+        sysroot,
         local_crate_source_file,
         working_dir,
         lint_store: RwLock::new(lint::LintStore::new()),
diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs
index 6b0a8a0..5c44a07 100644
--- a/src/librustc/session/search_paths.rs
+++ b/src/librustc/session/search_paths.rs
@@ -8,18 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::slice;
 use std::path::{Path, PathBuf};
 use session::{early_error, config};
+use session::filesearch::make_target_lib_path;
 
 #[derive(Clone, Debug)]
-pub struct SearchPaths {
-    crate paths: Vec<(PathKind, PathBuf)>,
-}
-
-pub struct Iter<'a> {
-    kind: PathKind,
-    iter: slice::Iter<'a, (PathKind, PathBuf)>,
+pub struct SearchPath {
+    pub kind: PathKind,
+    pub dir: PathBuf,
+    pub files: Vec<PathBuf>,
 }
 
 #[derive(Eq, PartialEq, Clone, Copy, Debug, PartialOrd, Ord, Hash)]
@@ -32,12 +29,17 @@
     All,
 }
 
-impl SearchPaths {
-    pub fn new() -> SearchPaths {
-        SearchPaths { paths: Vec::new() }
+impl PathKind {
+    pub fn matches(&self, kind: PathKind) -> bool {
+        match (self, kind) {
+            (PathKind::All, _) | (_, PathKind::All) => true,
+            _ => *self == kind,
+        }
     }
+}
 
-    pub fn add_path(&mut self, path: &str, output: config::ErrorOutputType) {
+impl SearchPath {
+    pub fn from_cli_opt(path: &str, output: config::ErrorOutputType) -> Self {
         let (kind, path) = if path.starts_with("native=") {
             (PathKind::Native, &path["native=".len()..])
         } else if path.starts_with("crate=") {
@@ -54,34 +56,28 @@
         if path.is_empty() {
             early_error(output, "empty search path given via `-L`");
         }
-        self.paths.push((kind, PathBuf::from(path)));
+
+        let dir = PathBuf::from(path);
+        Self::new(kind, dir)
     }
 
-    pub fn iter(&self, kind: PathKind) -> Iter<'_> {
-        Iter { kind: kind, iter: self.paths.iter() }
+    pub fn from_sysroot_and_triple(sysroot: &Path, triple: &str) -> Self {
+        Self::new(PathKind::All, make_target_lib_path(sysroot, triple))
     }
-}
 
-impl<'a> Iterator for Iter<'a> {
-    type Item = (&'a Path, PathKind);
-
-    fn next(&mut self) -> Option<(&'a Path, PathKind)> {
-        loop {
-            match *self.iter.next()? {
-                (kind, ref p) if self.kind == PathKind::All ||
-                                  kind == PathKind::All ||
-                                  kind == self.kind => {
-                    return Some((p, kind))
-                }
-                _ => {}
+    fn new(kind: PathKind, dir: PathBuf) -> Self {
+        // Get the files within the directory.
+        let files = match std::fs::read_dir(&dir) {
+            Ok(files) => {
+                files.filter_map(|p| {
+                    p.ok().map(|s| s.path())
+                })
+                .collect::<Vec<_>>()
             }
-        }
-    }
+            Err(..) => vec![],
+        };
 
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        // This iterator will never return more elements than the base iterator;
-        // but it can ignore all the remaining elements.
-        let (_, upper) = self.iter.size_hint();
-        (0, upper)
+        SearchPath { kind, dir, files }
     }
 }
+
diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs
index c3cca14..fff7781 100644
--- a/src/librustc/traits/auto_trait.rs
+++ b/src/librustc/traits/auto_trait.rs
@@ -138,7 +138,7 @@
             // the first evaluate_predicates call.
             //
             // The problem is this: most of rustc, including SelectionContext and traits::project,
-            // are designed to work with a concrete usage of a type (e.g. Vec<u8>
+            // are designed to work with a concrete usage of a type (e.g., Vec<u8>
             // fn<T>() { Vec<T> }. This information will generally never change - given
             // the 'T' in fn<T>() { ... }, we'll never know anything else about 'T'.
             // If we're unable to prove that 'T' implements a particular trait, we're done -
@@ -289,7 +289,7 @@
     //
     // One additional consideration is supertrait bounds. Normally, a ParamEnv is only ever
     // constructed once for a given type. As part of the construction process, the ParamEnv will
-    // have any supertrait bounds normalized - e.g. if we have a type 'struct Foo<T: Copy>', the
+    // have any supertrait bounds normalized - e.g., if we have a type 'struct Foo<T: Copy>', the
     // ParamEnv will contain 'T: Copy' and 'T: Clone', since 'Copy: Clone'. When we construct our
     // own ParamEnv, we need to do this ourselves, through traits::elaborate_predicates, or else
     // SelectionContext will choke on the missing predicates. However, this should never show up in
@@ -334,11 +334,16 @@
                 continue;
             }
 
-            let result = select.select(&Obligation::new(dummy_cause.clone(), new_env, pred));
+            // Call infcx.resolve_type_vars_if_possible to see if we can
+            // get rid of any inference variables.
+            let obligation = infcx.resolve_type_vars_if_possible(
+                &Obligation::new(dummy_cause.clone(), new_env, pred)
+            );
+            let result = select.select(&obligation);
 
             match &result {
                 &Ok(Some(ref vtable)) => {
-                    // If we see an explicit negative impl (e.g. 'impl !Send for MyStruct'),
+                    // If we see an explicit negative impl (e.g., 'impl !Send for MyStruct'),
                     // we immediately bail out, since it's impossible for us to continue.
                     match vtable {
                         Vtable::VtableImpl(VtableImplData { impl_def_id, .. }) => {
@@ -369,7 +374,7 @@
                 }
                 &Ok(None) => {}
                 &Err(SelectionError::Unimplemented) => {
-                    if self.is_of_param(pred.skip_binder().trait_ref.substs) {
+                    if self.is_param_no_infer(pred.skip_binder().trait_ref.substs) {
                         already_visited.remove(&pred);
                         self.add_user_pred(
                             &mut user_computed_preds,
@@ -427,11 +432,11 @@
     // If we put both of these predicates in our computed ParamEnv, we'll
     // confuse SelectionContext, since it will (correctly) view both as being applicable.
     //
-    // To solve this, we pick the 'more strict' lifetime bound - i.e. the HRTB
+    // To solve this, we pick the 'more strict' lifetime bound - i.e., the HRTB
     // Our end goal is to generate a user-visible description of the conditions
     // under which a type implements an auto trait. A trait predicate involving
     // a HRTB means that the type needs to work with any choice of lifetime,
-    // not just one specific lifetime (e.g. 'static).
+    // not just one specific lifetime (e.g., 'static).
     fn add_user_pred<'c>(
         &self,
         user_computed_preds: &mut FxHashSet<ty::Predicate<'c>>,
@@ -631,18 +636,28 @@
         finished_map
     }
 
-    pub fn is_of_param(&self, substs: &Substs<'_>) -> bool {
-        if substs.is_noop() {
-            return false;
-        }
+    fn is_param_no_infer(&self, substs: &Substs<'_>) -> bool {
+        return self.is_of_param(substs.type_at(0)) &&
+            !substs.types().any(|t| t.has_infer_types());
+    }
 
-        return match substs.type_at(0).sty {
+    pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
+        return match ty.sty {
             ty::Param(_) => true,
-            ty::Projection(p) => self.is_of_param(p.substs),
+            ty::Projection(p) => self.is_of_param(p.self_ty()),
             _ => false,
         };
     }
 
+    fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
+        match p.ty().skip_binder().sty {
+            ty::Projection(proj) if proj == p.skip_binder().projection_ty => {
+                true
+            },
+            _ => false
+        }
+    }
+
     pub fn evaluate_nested_obligations<
         'b,
         'c,
@@ -661,28 +676,77 @@
     ) -> bool {
         let dummy_cause = ObligationCause::misc(DUMMY_SP, ast::DUMMY_NODE_ID);
 
-        for (obligation, predicate) in nested
-            .filter(|o| o.recursion_depth == 1)
+        for (obligation, mut predicate) in nested
             .map(|o| (o.clone(), o.predicate.clone()))
         {
             let is_new_pred =
                 fresh_preds.insert(self.clean_pred(select.infcx(), predicate.clone()));
 
+            // Resolve any inference variables that we can, to help selection succeed
+            predicate = select.infcx().resolve_type_vars_if_possible(&predicate);
+
+            // We only add a predicate as a user-displayable bound if
+            // it involves a generic parameter, and doesn't contain
+            // any inference variables.
+            //
+            // Displaying a bound involving a concrete type (instead of a generic
+            // parameter) would be pointless, since it's always true
+            // (e.g. u8: Copy)
+            // Displaying an inference variable is impossible, since they're
+            // an internal compiler detail without a defined visual representation
+            //
+            // We check this by calling is_of_param on the relevant types
+            // from the various possible predicates
             match &predicate {
                 &ty::Predicate::Trait(ref p) => {
-                    let substs = &p.skip_binder().trait_ref.substs;
+                    if self.is_param_no_infer(p.skip_binder().trait_ref.substs)
+                        && !only_projections
+                        && is_new_pred {
 
-                    if self.is_of_param(substs) && !only_projections && is_new_pred {
                         self.add_user_pred(computed_preds, predicate);
                     }
                     predicates.push_back(p.clone());
                 }
                 &ty::Predicate::Projection(p) => {
-                    // If the projection isn't all type vars, then
-                    // we don't want to add it as a bound
-                    if self.is_of_param(p.skip_binder().projection_ty.substs) && is_new_pred {
-                        self.add_user_pred(computed_preds, predicate);
-                    } else {
+                    debug!("evaluate_nested_obligations: examining projection predicate {:?}",
+                           predicate);
+
+                    // As described above, we only want to display
+                    // bounds which include a generic parameter but don't include
+                    // an inference variable.
+                    // Additionally, we check if we've seen this predicate before,
+                    // to avoid rendering duplicate bounds to the user.
+                    if self.is_param_no_infer(p.skip_binder().projection_ty.substs)
+                        && !p.ty().skip_binder().is_ty_infer()
+                        && is_new_pred {
+                            debug!("evaluate_nested_obligations: adding projection predicate\
+                            to computed_preds: {:?}", predicate);
+
+                            // Under unusual circumstances, we can end up with a self-refeential
+                            // projection predicate. For example:
+                            // <T as MyType>::Value == <T as MyType>::Value
+                            // Not only is displaying this to the user pointless,
+                            // having it in the ParamEnv will cause an issue if we try to call
+                            // poly_project_and_unify_type on the predicate, since this kind of
+                            // predicate will normally never end up in a ParamEnv.
+                            //
+                            // For these reasons, we ignore these weird predicates,
+                            // ensuring that we're able to properly synthesize an auto trait impl
+                            if self.is_self_referential_projection(p) {
+                                debug!("evaluate_nested_obligations: encountered a projection
+                                 predicate equating a type with itself! Skipping");
+
+                            } else {
+                                self.add_user_pred(computed_preds, predicate);
+                            }
+                    }
+
+                    // We can only call poly_project_and_unify_type when our predicate's
+                    // Ty is an inference variable - otherwise, there won't be anything to
+                    // unify
+                    if p.ty().skip_binder().is_ty_infer() {
+                        debug!("Projecting and unifying projection predicate {:?}",
+                               predicate);
                         match poly_project_and_unify_type(select, &obligation.with(p.clone())) {
                             Err(e) => {
                                 debug!(
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index 4bf8ba0..f10f523 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -256,12 +256,12 @@
 /// The current rule is that a trait-ref orphan checks in a crate C:
 ///
 /// 1. Order the parameters in the trait-ref in subst order - Self first,
-///    others linearly (e.g. `<U as Foo<V, W>>` is U < V < W).
+///    others linearly (e.g., `<U as Foo<V, W>>` is U < V < W).
 /// 2. Of these type parameters, there is at least one type parameter
 ///    in which, walking the type as a tree, you can reach a type local
 ///    to C where all types in-between are fundamental types. Call the
 ///    first such parameter the "local key parameter".
-///     - e.g. `Box<LocalType>` is OK, because you can visit LocalType
+///     - e.g., `Box<LocalType>` is OK, because you can visit LocalType
 ///       going through `Box`, which is fundamental.
 ///     - similarly, `FundamentalPair<Vec<()>, Box<LocalType>>` is OK for
 ///       the same reason.
@@ -269,7 +269,7 @@
 ///       not local), `Vec<LocalType>` is bad, because `Vec<->` is between
 ///       the local type and the type parameter.
 /// 3. Every type parameter before the local key parameter is fully known in C.
-///     - e.g. `impl<T> T: Trait<LocalType>` is bad, because `T` might be
+///     - e.g., `impl<T> T: Trait<LocalType>` is bad, because `T` might be
 ///       an unknown type.
 ///     - but `impl<T> LocalType: Trait<T>` is OK, because `LocalType`
 ///       occurs before `T`.
@@ -277,7 +277,7 @@
 ///    through the parameter's type tree, must appear only as a subtree of
 ///    a type local to C, with only fundamental types between the type
 ///    local to C and the local key parameter.
-///     - e.g. `Vec<LocalType<T>>>` (or equivalently `Box<Vec<LocalType<T>>>`)
+///     - e.g., `Vec<LocalType<T>>>` (or equivalently `Box<Vec<LocalType<T>>>`)
 ///     is bad, because the only local type with `T` as a subtree is
 ///     `LocalType<T>`, and `Vec<->` is between it and the type parameter.
 ///     - similarly, `FundamentalPair<LocalType<T>, T>` is bad, because
@@ -288,7 +288,7 @@
 ///
 /// The orphan rules actually serve several different purposes:
 ///
-/// 1. They enable link-safety - i.e. 2 mutually-unknowing crates (where
+/// 1. They enable link-safety - i.e., 2 mutually-unknowing crates (where
 ///    every type local to one crate is unknown in the other) can't implement
 ///    the same trait-ref. This follows because it can be seen that no such
 ///    type can orphan-check in 2 such crates.
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 7e97dc3..4ef4f45 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -128,7 +128,7 @@
         }
     }
 
-    // returns if `cond` not occurring implies that `error` does not occur - i.e. that
+    // returns if `cond` not occurring implies that `error` does not occur - i.e., that
     // `error` occurring implies that `cond` occurs.
     fn error_implies(&self,
                      cond: &ty::Predicate<'tcx>,
@@ -580,7 +580,7 @@
 
         let mut err = struct_span_err!(self.tcx.sess, sp, E0276, "{}", msg);
 
-        if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
+        if let Some(trait_item_span) = self.tcx.hir().span_if_local(trait_item_def_id) {
             let span = self.tcx.sess.source_map().def_span(trait_item_span);
             err.span_label(span, format!("definition of `{}` from trait", item_name));
         }
@@ -765,8 +765,8 @@
                     ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
                         let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap();
                         let closure_span = self.tcx.sess.source_map()
-                            .def_span(self.tcx.hir.span_if_local(closure_def_id).unwrap());
-                        let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap();
+                            .def_span(self.tcx.hir().span_if_local(closure_def_id).unwrap());
+                        let node_id = self.tcx.hir().as_local_node_id(closure_def_id).unwrap();
                         let mut err = struct_span_err!(
                             self.tcx.sess, closure_span, E0525,
                             "expected a closure that implements the `{}` trait, \
@@ -785,7 +785,7 @@
                         // a particular trait.
                         if let Some(tables) = self.in_progress_tables {
                             let tables = tables.borrow();
-                            let closure_hir_id = self.tcx.hir.node_to_hir_id(node_id);
+                            let closure_hir_id = self.tcx.hir().node_to_hir_id(node_id);
                             match (found_kind, tables.closure_kind_origins().get(closure_hir_id)) {
                                 (ty::ClosureKind::FnOnce, Some((span, name))) => {
                                     err.span_label(*span, format!(
@@ -841,7 +841,7 @@
                 };
 
                 let found_span = found_did.and_then(|did|
-                    self.tcx.hir.span_if_local(did)
+                    self.tcx.hir().span_if_local(did)
                 ).map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def
 
                 let found = match found_trait_ref.skip_binder().substs.type_at(1).sty {
@@ -862,7 +862,7 @@
                                                      expected_trait_ref)
                 } else {
                     let (closure_span, found) = found_did
-                        .and_then(|did| self.tcx.hir.get_if_local(did))
+                        .and_then(|did| self.tcx.hir().get_if_local(did))
                         .map(|node| {
                             let (found_span, found) = self.get_fn_like_arguments(node);
                             (Some(found_span), found)
@@ -901,8 +901,8 @@
                                        code: &ObligationCauseCode<'tcx>,
                                        err: &mut DiagnosticBuilder<'tcx>) {
         if let &ObligationCauseCode::VariableType(node_id) = code {
-            let parent_node = self.tcx.hir.get_parent_node(node_id);
-            if let Some(Node::Local(ref local)) = self.tcx.hir.find(parent_node) {
+            let parent_node = self.tcx.hir().get_parent_node(node_id);
+            if let Some(Node::Local(ref local)) = self.tcx.hir().find(parent_node) {
                 if let Some(ref expr) = local.init {
                     if let hir::ExprKind::Index(_, _) = expr.node {
                         if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
@@ -976,7 +976,7 @@
                 node: hir::ExprKind::Closure(_, ref _decl, id, span, _),
                 ..
             }) => {
-                (self.tcx.sess.source_map().def_span(span), self.tcx.hir.body(id).arguments.iter()
+                (self.tcx.sess.source_map().def_span(span), self.tcx.hir().body(id).arguments.iter()
                     .map(|arg| {
                         if let hir::Pat {
                             node: hir::PatKind::Tuple(args, _),
@@ -1037,7 +1037,7 @@
                  ).collect::<Vec<_>>())
             }
             Node::StructCtor(ref variant_data) => {
-                (self.tcx.sess.source_map().def_span(self.tcx.hir.span(variant_data.id())),
+                (self.tcx.sess.source_map().def_span(self.tcx.hir().span(variant_data.id())),
                  vec![ArgKind::empty(); variant_data.fields().len()])
             }
             _ => panic!("non-FnLike node found: {:?}", node),
@@ -1236,7 +1236,7 @@
                                                    -> DiagnosticBuilder<'tcx>
     {
         assert!(type_def_id.is_local());
-        let span = self.hir.span_if_local(type_def_id).unwrap();
+        let span = self.hir().span_if_local(type_def_id).unwrap();
         let span = self.sess.source_map().def_span(span);
         let mut err = struct_span_err!(self.sess, span, E0072,
                                        "recursive type `{}` has infinite size",
@@ -1482,7 +1482,7 @@
                 let item_name = tcx.item_path_str(item_def_id);
                 let msg = format!("required by `{}`", item_name);
 
-                if let Some(sp) = tcx.hir.span_if_local(item_def_id) {
+                if let Some(sp) = tcx.hir().span_if_local(item_def_id) {
                     let sp = tcx.sess.source_map().def_span(sp);
                     err.span_note(sp, &msg);
                 } else {
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index ab2fa68..8d91132 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -8,52 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Trait Resolution. See [rustc guide] for more info on how this works.
+//! Trait Resolution. See the [rustc guide] for more information on how this works.
 //!
 //! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
 
-pub use self::SelectionError::*;
-pub use self::FulfillmentErrorCode::*;
-pub use self::Vtable::*;
-pub use self::ObligationCauseCode::*;
-
-use chalk_engine;
-use hir;
-use hir::def_id::DefId;
-use infer::SuppressRegionErrors;
-use infer::outlives::env::OutlivesEnvironment;
-use middle::region;
-use mir::interpret::ErrorHandled;
-use ty::subst::Substs;
-use ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
-use ty::error::{ExpectedFound, TypeError};
-use ty::fold::{TypeFolder, TypeFoldable, TypeVisitor};
-use infer::{InferCtxt};
-use util::common::ErrorReported;
-
-use rustc_data_structures::sync::Lrc;
-use std::fmt::Debug;
-use std::rc::Rc;
-use syntax::ast;
-use syntax_pos::{Span, DUMMY_SP};
-
-pub use self::coherence::{orphan_check, overlapping_impls, OrphanCheckErr, OverlapResult};
-pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
-pub use self::project::MismatchedProjectionTypes;
-pub use self::project::{normalize, normalize_projection_type, poly_project_and_unify_type};
-pub use self::project::{ProjectionCache, ProjectionCacheSnapshot, Reveal, Normalized};
-pub use self::object_safety::ObjectSafetyViolation;
-pub use self::object_safety::MethodViolationCode;
-pub use self::on_unimplemented::{OnUnimplementedDirective, OnUnimplementedNote};
-pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
-pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
-pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
-pub use self::specialize::find_associated_item;
-pub use self::engine::{TraitEngine, TraitEngineExt};
-pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
-pub use self::util::{supertraits, supertrait_def_ids, Supertraits, SupertraitDefIds};
-pub use self::util::transitive_bounds;
-
 #[allow(dead_code)]
 pub mod auto_trait;
 mod coherence;
@@ -68,9 +26,54 @@
 mod structural_impls;
 pub mod codegen;
 mod util;
-
 pub mod query;
 
+use chalk_engine;
+use hir;
+use hir::def_id::DefId;
+use infer::{InferCtxt, SuppressRegionErrors};
+use infer::outlives::env::OutlivesEnvironment;
+use middle::region;
+use mir::interpret::ErrorHandled;
+use rustc_data_structures::sync::Lrc;
+use syntax::ast;
+use syntax_pos::{Span, DUMMY_SP};
+use ty::subst::Substs;
+use ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
+use ty::error::{ExpectedFound, TypeError};
+use ty::fold::{TypeFolder, TypeFoldable, TypeVisitor};
+use util::common::ErrorReported;
+
+use std::fmt::Debug;
+use std::rc::Rc;
+
+pub use self::SelectionError::*;
+pub use self::FulfillmentErrorCode::*;
+pub use self::Vtable::*;
+pub use self::ObligationCauseCode::*;
+
+pub use self::coherence::{orphan_check, overlapping_impls, OrphanCheckErr, OverlapResult};
+pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
+pub use self::project::MismatchedProjectionTypes;
+pub use self::project::{normalize, normalize_projection_type, poly_project_and_unify_type};
+pub use self::project::{ProjectionCache, ProjectionCacheSnapshot, Reveal, Normalized};
+pub use self::object_safety::ObjectSafetyViolation;
+pub use self::object_safety::MethodViolationCode;
+pub use self::on_unimplemented::{OnUnimplementedDirective, OnUnimplementedNote};
+pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
+pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
+pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
+pub use self::specialize::find_associated_item;
+pub use self::engine::{TraitEngine, TraitEngineExt};
+pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
+pub use self::util::{supertraits, supertrait_def_ids, transitive_bounds,
+                     Supertraits, SupertraitDefIds};
+
+pub use self::ObligationCauseCode::*;
+pub use self::FulfillmentErrorCode::*;
+pub use self::SelectionError::*;
+pub use self::Vtable::*;
+
 // Whether to enable bug compatibility with issue #43355
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum IntercrateMode {
@@ -91,7 +94,7 @@
     Canonical,
 }
 
-/// An `Obligation` represents some trait reference (e.g. `int:Eq`) for
+/// An `Obligation` represents some trait reference (e.g., `int:Eq`) for
 /// which the vtable must be found.  The process of finding a vtable is
 /// called "resolving" the `Obligation`. This process consists of
 /// either identifying an `impl` (e.g., `impl Eq for int`) that
@@ -955,7 +958,7 @@
 
 /// Given a trait `trait_ref`, iterates the vtable entries
 /// that come from `trait_ref`, including its supertraits.
-#[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
+#[inline] // FIXME(#35870): avoid closures being unexported due to `impl Trait`.
 fn vtable_methods<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>)
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 2909daf..4b2f817 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -36,7 +36,7 @@
     SizedSelf,
 
     /// Supertrait reference references `Self` an in illegal location
-    /// (e.g. `trait Foo : Bar<Self>`)
+    /// (e.g., `trait Foo : Bar<Self>`)
     SupertraitSelf,
 
     /// Method has something illegal
@@ -81,7 +81,7 @@
     /// e.g., `fn foo(&self, x: Self)` or `fn foo(&self) -> Self`
     ReferencesSelf,
 
-    /// e.g. `fn foo(&self) where Self: Clone`
+    /// e.g., `fn foo(&self) where Self: Clone`
     WhereClauseReferencesSelf(Span),
 
     /// e.g., `fn foo<A>()`
@@ -343,7 +343,7 @@
                     }
                 };
 
-                // e.g. Rc<()>
+                // e.g., Rc<()>
                 let unit_receiver_ty = self.receiver_for_self_ty(
                     receiver_ty, self.mk_unit(), method.def_id
                 );
@@ -357,7 +357,7 @@
                     trait_def_id, self.mk_region(ty::ReStatic)
                 );
 
-                // e.g. Rc<dyn Trait>
+                // e.g., Rc<dyn Trait>
                 let trait_object_receiver = self.receiver_for_self_ty(
                     receiver_ty, trait_object_ty, method.def_id
                 );
@@ -376,7 +376,7 @@
     }
 
     /// performs a type substitution to produce the version of receiver_ty when `Self = self_ty`
-    /// e.g. for receiver_ty = `Rc<Self>` and self_ty = `Foo`, returns `Rc<Foo>`
+    /// e.g., for receiver_ty = `Rc<Self>` and self_ty = `Foo`, returns `Rc<Foo>`
     fn receiver_for_self_ty(
         self, receiver_ty: Ty<'tcx>, self_ty: Ty<'tcx>, method_def_id: DefId
     ) -> Ty<'tcx> {
@@ -451,7 +451,7 @@
     ///
     /// The only case where the receiver is not dispatchable, but is still a valid receiver
     /// type (just not object-safe), is when there is more than one level of pointer indirection.
-    /// e.g. `self: &&Self`, `self: &Rc<Self>`, `self: Box<Box<Self>>`. In these cases, there
+    /// e.g., `self: &&Self`, `self: &Rc<Self>`, `self: Box<Box<Self>>`. In these cases, there
     /// is no way, or at least no inexpensive way, to coerce the receiver from the version where
     /// `Self = dyn Trait` to the version where `Self = T`, where `T` is the unknown erased type
     /// contained by the trait object, because the object that needs to be coerced is behind
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 1d3d66e..5717a76 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -70,7 +70,7 @@
     /// be observable directly by the user, `Reveal::All`
     /// should not be used by checks which may expose
     /// type equality or type contents to the user.
-    /// There are some exceptions, e.g. around OIBITS and
+    /// There are some exceptions, e.g., around OIBITS and
     /// transmute-checking, which expose some details, but
     /// not the whole concrete type of the `impl Trait`.
     All,
@@ -608,7 +608,7 @@
             // created (and hence the new ones will quickly be
             // discarded as duplicated). But when doing trait
             // evaluation this is not the case, and dropping the trait
-            // evaluations can causes ICEs (e.g. #43132).
+            // evaluations can causes ICEs (e.g., #43132).
             debug!("opt_normalize_projection_type: \
                     found normalized ty `{:?}`",
                    ty);
@@ -1589,7 +1589,7 @@
 /// When working with a fulfillment context, the derived obligations of each
 /// projection cache entry will be registered on the fulfillcx, so any users
 /// that can wait for a fulfillcx fixed point need not care about this. However,
-/// users that don't wait for a fixed point (e.g. trait evaluation) have to
+/// users that don't wait for a fixed point (e.g., trait evaluation) have to
 /// resolve the obligations themselves to make sure the projected result is
 /// ok and avoid issues like #43132.
 ///
@@ -1637,7 +1637,7 @@
     NormalizedTy(NormalizedTy<'tcx>),
 }
 
-// NB: intentionally not Clone
+// N.B., intentionally not Clone
 pub struct ProjectionCacheSnapshot {
     snapshot: Snapshot,
 }
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index fb4c9f3..c438542 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! See [rustc guide] for more info on how this works.
+//! Candidate selection. See the [rustc guide] for more information on how this works.
 //!
 //! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html#selection
 
@@ -69,10 +69,10 @@
     /// require themselves.
     freshener: TypeFreshener<'cx, 'gcx, 'tcx>,
 
-    /// If true, indicates that the evaluation should be conservative
+    /// If `true`, indicates that the evaluation should be conservative
     /// and consider the possibility of types outside this crate.
     /// This comes up primarily when resolving ambiguity. Imagine
-    /// there is some trait reference `$0 : Bar` where `$0` is an
+    /// there is some trait reference `$0: Bar` where `$0` is an
     /// inference variable. If `intercrate` is true, then we can never
     /// say for sure that this reference is not implemented, even if
     /// there are *no impls at all for `Bar`*, because `$0` could be
@@ -80,7 +80,7 @@
     /// `Bar`. This is the suitable mode for coherence. Elsewhere,
     /// though, we set this to false, because we are only interested
     /// in types that the user could actually have written --- in
-    /// other words, we consider `$0 : Bar` to be unimplemented if
+    /// other words, we consider `$0: Bar` to be unimplemented if
     /// there is no type that the user could *actually name* that
     /// would satisfy it. This avoids crippling inference, basically.
     intercrate: Option<IntercrateMode>,
@@ -1170,7 +1170,7 @@
     //
     // The selection process begins by examining all in-scope impls,
     // caller obligations, and so forth and assembling a list of
-    // candidates. See [rustc guide] for more details.
+    // candidates. See the [rustc guide] for more details.
     //
     // [rustc guide]:
     // https://rust-lang.github.io/rustc-guide/traits/resolution.html#candidate-assembly
@@ -1615,7 +1615,7 @@
         };
 
         if obligation.predicate.skip_binder().self_ty().is_ty_var() {
-            // Self is a type variable (e.g. `_: AsRef<str>`).
+            // Self is a type variable (e.g., `_: AsRef<str>`).
             //
             // This is somewhat problematic, as the current scheme can't really
             // handle it turning to be a projection. This does end up as truly
@@ -1664,7 +1664,7 @@
             self.assemble_candidates_for_unsizing(obligation, &mut candidates);
         } else {
             if lang_items.clone_trait() == Some(def_id) {
-                // Same builtin conditions as `Copy`, i.e. every type which has builtin support
+                // Same builtin conditions as `Copy`, i.e., every type which has builtin support
                 // for `Copy` also has builtin support for `Clone`, + tuples and arrays of `Clone`
                 // types have builtin support for `Clone`.
                 let clone_conditions = self.copy_clone_conditions(obligation);
@@ -2023,7 +2023,7 @@
                     {
                         candidates.vec.push(ImplCandidate(impl_def_id));
 
-                        // NB: we can safely drop the placeholder map
+                        // N.B., we can safely drop the placeholder map
                         // since we are in a probe.
                         mem::drop(placeholder_map);
                     }
@@ -2069,7 +2069,7 @@
                     // that this obligation holds. That could be a
                     // where-clause or, in the case of an object type,
                     // it could be that the object type lists the
-                    // trait (e.g. `Foo+Send : Send`). See
+                    // trait (e.g., `Foo+Send : Send`). See
                     // `compile-fail/typeck-default-trait-impl-send-param.rs`
                     // for an example of a test case that exercises
                     // this path.
@@ -2097,7 +2097,7 @@
         );
 
         self.probe(|this, _snapshot| {
-            // the code below doesn't care about regions, and the
+            // The code below doesn't care about regions, and the
             // self-ty here doesn't escape this probe, so just erase
             // any LBR.
             let self_ty = this.tcx().erase_late_bound_regions(&obligation.self_ty());
@@ -2145,7 +2145,7 @@
                 .count();
 
             if upcast_trait_refs > 1 {
-                // can be upcast in many ways; need more type information
+                // Can be upcast in many ways; need more type information.
                 candidates.ambiguous = true;
             } else if upcast_trait_refs == 1 {
                 candidates.vec.push(ObjectCandidate);
@@ -2197,8 +2197,8 @@
             (&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
                 // Upcasts permit two things:
                 //
-                // 1. Dropping builtin bounds, e.g. `Foo+Send` to `Foo`
-                // 2. Tightening the region bound, e.g. `Foo+'a` to `Foo+'b` if `'a : 'b`
+                // 1. Dropping builtin bounds, e.g., `Foo+Send` to `Foo`
+                // 2. Tightening the region bound, e.g., `Foo+'a` to `Foo+'b` if `'a : 'b`
                 //
                 // Note that neither of these changes requires any
                 // change at runtime.  Eventually this will be
@@ -2354,7 +2354,7 @@
             ImplCandidate(other_def) => {
                 // See if we can toss out `victim` based on specialization.
                 // This requires us to know *for sure* that the `other` impl applies
-                // i.e. EvaluatedToOk:
+                // i.e., EvaluatedToOk:
                 if other.evaluation == EvaluatedToOk {
                     match victim.candidate {
                         ImplCandidate(victim_def) => {
@@ -2717,7 +2717,7 @@
     //
     // Confirmation unifies the output type parameters of the trait
     // with the values found in the obligation, possibly yielding a
-    // type error.  See [rustc guide] for more details.
+    // type error.  See the [rustc guide] for more details.
     //
     // [rustc guide]:
     // https://rust-lang.github.io/rustc-guide/traits/resolution.html#confirmation
@@ -3003,7 +3003,7 @@
         // are sufficient to determine the impl substs, without
         // relying on projections in the impl-trait-ref.
         //
-        // e.g. `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V`
+        // e.g., `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V`
         impl_obligations.append(&mut substs.obligations);
 
         VtableImplData {
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index 19ef317..96bb545 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -19,22 +19,21 @@
 //!
 //! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
 
-use super::{SelectionContext, FulfillmentContext};
-use super::util::impl_trait_ref_and_oblig;
+pub mod specialization_graph;
 
-use rustc_data_structures::fx::FxHashSet;
 use hir::def_id::DefId;
 use infer::{InferCtxt, InferOk};
-use ty::subst::{Subst, Substs};
+use lint;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::sync::Lrc;
+use syntax_pos::DUMMY_SP;
 use traits::{self, ObligationCause, TraitEngine};
 use traits::select::IntercrateAmbiguityCause;
 use ty::{self, TyCtxt, TypeFoldable};
-use syntax_pos::DUMMY_SP;
-use rustc_data_structures::sync::Lrc;
+use ty::subst::{Subst, Substs};
 
-use lint;
-
-pub mod specialization_graph;
+use super::{SelectionContext, FulfillmentContext};
+use super::util::impl_trait_ref_and_oblig;
 
 /// Information pertinent to an overlapping impl error.
 pub struct OverlapError {
@@ -85,6 +84,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 +120,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 +136,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);
@@ -179,7 +183,7 @@
     //
     // See RFC 1210 for more details and justification.
 
-    // Currently we do not allow e.g. a negative impl to specialize a positive one
+    // Currently we do not allow e.g., a negative impl to specialize a positive one
     if tcx.impl_polarity(impl1_def_id) != tcx.impl_polarity(impl2_def_id) {
         return false;
     }
@@ -219,12 +223,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)
@@ -285,17 +294,18 @@
 }
 
 // Query provider for `specialization_graph_of`.
-pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                                      trait_id: DefId)
-                                                      -> Lrc<specialization_graph::Graph> {
+pub(super) fn specialization_graph_provider<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    trait_id: DefId,
+) -> Lrc<specialization_graph::Graph> {
     let mut sg = specialization_graph::Graph::new();
 
     let mut trait_impls = tcx.all_impls(trait_id);
 
     // The coherence checking implementation seems to rely on impls being
     // iterated over (roughly) in definition order, so we are sorting by
-    // negated CrateNum (so remote definitions are visited first) and then
-    // by a flattened version of the DefIndex.
+    // negated `CrateNum` (so remote definitions are visited first) and then
+    // by a flattened version of the `DefIndex`.
     trait_impls.sort_unstable_by_key(|def_id| {
         (-(def_id.krate.as_u32() as i64),
          def_id.index.address_space().index(),
@@ -327,7 +337,7 @@
                 let mut err = if used_to_be_allowed {
                     tcx.struct_span_lint_node(
                         lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
-                        tcx.hir.as_local_node_id(impl_def_id).unwrap(),
+                        tcx.hir().as_local_node_id(impl_def_id).unwrap(),
                         impl_span,
                         &msg)
                 } else {
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index db0302f..b0ca2f6 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -29,7 +29,7 @@
 ///
 /// The graph provides two key services:
 ///
-/// - Construction, which implicitly checks for overlapping impls (i.e., impls
+/// - Construction. This implicitly checks for overlapping impls (i.e., impls
 ///   that overlap but where neither specializes the other -- an artifact of the
 ///   simple "chain" rule.
 ///
@@ -39,11 +39,11 @@
 ///   has at most one parent.
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct Graph {
-    // all impls have a parent; the "root" impls have as their parent the def_id
-    // of the trait
+    // All impls have a parent; the "root" impls have as their parent the `def_id`
+    // of the trait.
     parent: DefIdMap<DefId>,
 
-    // the "root" impls are found by looking up the trait's def_id.
+    // The "root" impls are found by looking up the trait's def_id.
     children: DefIdMap<Children>,
 }
 
@@ -81,7 +81,7 @@
 }
 
 impl<'a, 'gcx, 'tcx> Children {
-    /// Insert an impl into this set of children without comparing to any existing impls
+    /// Insert an impl into this set of children without comparing to any existing impls.
     fn insert_blindly(&mut self,
                       tcx: TyCtxt<'a, 'gcx, 'tcx>,
                       impl_def_id: DefId) {
@@ -132,10 +132,12 @@
             simplified_self,
         );
 
-        for possible_sibling in match simplified_self {
-            Some(sty) => self.filtered(sty),
-            None => self.iter(),
-        } {
+        let possible_siblings = match simplified_self {
+            Some(sty) => PotentialSiblings::Filtered(self.filtered(sty)),
+            None => PotentialSiblings::Unfiltered(self.iter()),
+        };
+
+        for possible_sibling in possible_siblings {
             debug!(
                 "insert: impl_def_id={:?}, simplified_self={:?}, possible_sibling={:?}",
                 impl_def_id,
@@ -144,13 +146,13 @@
             );
 
             let overlap_error = |overlap: traits::coherence::OverlapResult<'_>| {
-                // overlap, but no specialization; error out
+                // Found overlap, but no specialization; error out.
                 let trait_ref = overlap.impl_header.trait_ref.unwrap();
                 let self_ty = trait_ref.self_ty();
                 OverlapError {
                     with_impl: possible_sibling,
                     trait_desc: trait_ref.to_string(),
-                    // only report the Self type if it has at least
+                    // Only report the `Self` type if it has at least
                     // some outer concrete shell; otherwise, it's
                     // not adding much information.
                     self_desc: if self_ty.has_concrete_skeleton() {
@@ -189,7 +191,7 @@
                 debug!("descending as child of TraitRef {:?}",
                        tcx.impl_trait_ref(possible_sibling).unwrap());
 
-                // the impl specializes possible_sibling
+                // The impl specializes `possible_sibling`.
                 return Ok(Inserted::ShouldRecurseOn(possible_sibling));
             } else if ge && !le {
                 debug!("placing as parent of TraitRef {:?}",
@@ -216,20 +218,43 @@
             return Ok(Inserted::ReplaceChildren(replace_children));
         }
 
-        // no overlap with any potential siblings, so add as a new sibling
+        // No overlap with any potential siblings, so add as a new sibling.
         debug!("placing as new sibling");
         self.insert_blindly(tcx, impl_def_id);
         Ok(Inserted::BecameNewSibling(last_lint))
     }
 
-    fn iter(&mut self) -> Box<dyn Iterator<Item = DefId> + '_> {
+    fn iter(&mut self) -> impl Iterator<Item = DefId> + '_ {
         let nonblanket = self.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter());
-        Box::new(self.blanket_impls.iter().chain(nonblanket).cloned())
+        self.blanket_impls.iter().chain(nonblanket).cloned()
     }
 
-    fn filtered(&mut self, sty: SimplifiedType) -> Box<dyn Iterator<Item = DefId> + '_> {
+    fn filtered(&mut self, sty: SimplifiedType) -> impl Iterator<Item = DefId> + '_ {
         let nonblanket = self.nonblanket_impls.entry(sty).or_default().iter();
-        Box::new(self.blanket_impls.iter().chain(nonblanket).cloned())
+        self.blanket_impls.iter().chain(nonblanket).cloned()
+    }
+}
+
+// A custom iterator used by Children::insert
+enum PotentialSiblings<I, J>
+    where I: Iterator<Item = DefId>,
+          J: Iterator<Item = DefId>
+{
+    Unfiltered(I),
+    Filtered(J)
+}
+
+impl<I, J> Iterator for PotentialSiblings<I, J>
+    where I: Iterator<Item = DefId>,
+          J: Iterator<Item = DefId>
+{
+    type Item = DefId;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match *self {
+            PotentialSiblings::Unfiltered(ref mut iter) => iter.next(),
+            PotentialSiblings::Filtered(ref mut iter) => iter.next()
+        }
     }
 }
 
@@ -256,7 +281,7 @@
         debug!("insert({:?}): inserting TraitRef {:?} into specialization graph",
                impl_def_id, trait_ref);
 
-        // if the reference itself contains an earlier error (e.g., due to a
+        // If the reference itself contains an earlier error (e.g., due to a
         // resolution failure), then we just insert the impl at the top level of
         // the graph and claim that there's no overlap (in order to suppress
         // bogus errors).
@@ -275,7 +300,7 @@
         let mut last_lint = None;
         let simplified = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false);
 
-        // Descend the specialization tree, where `parent` is the current parent node
+        // Descend the specialization tree, where `parent` is the current parent node.
         loop {
             use self::Inserted::*;
 
@@ -313,7 +338,7 @@
                         siblings.insert_blindly(tcx, impl_def_id);
                     }
 
-                    // Set G's parent to N and N's parent to P
+                    // Set G's parent to N and N's parent to P.
                     for &grand_child_to_be in &grand_children_to_be {
                         self.parent.insert(grand_child_to_be, impl_def_id);
                     }
@@ -429,7 +454,8 @@
 impl<'a, 'gcx, 'tcx> Ancestors {
     /// Search the items from the given ancestors, returning each definition
     /// with the given name and the given kind.
-    #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
+    // FIXME(#35870): avoid closures being unexported due to `impl Trait`.
+    #[inline]
     pub fn defs(
         self,
         tcx: TyCtxt<'a, 'gcx, 'tcx>,
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/traits/util.rs b/src/librustc/traits/util.rs
index 3a88250..48db72c 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use hir;
 use hir::def_id::DefId;
-use ty::subst::{Kind, Subst, Substs};
+use traits::specialize::specialization_graph::NodeItem;
 use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef};
 use ty::outlives::Component;
+use ty::subst::{Kind, Subst, Substs};
 use util::nodemap::FxHashSet;
-use hir::{self};
-use traits::specialize::specialization_graph::NodeItem;
 
 use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized};
 
@@ -535,9 +535,9 @@
     }
 
     pub fn impl_is_default(self, node_item_def_id: DefId) -> bool {
-        match self.hir.as_local_node_id(node_item_def_id) {
+        match self.hir().as_local_node_id(node_item_def_id) {
             Some(node_id) => {
-                let item = self.hir.expect_item(node_id);
+                let item = self.hir().expect_item(node_id);
                 if let hir::ItemKind::Impl(_, _, defaultness, ..) = item.node {
                     defaultness.is_default()
                 } else {
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs
index 83521c5..d91ae7e 100644
--- a/src/librustc/ty/adjustment.rs
+++ b/src/librustc/ty/adjustment.rs
@@ -83,7 +83,7 @@
     /// Take the address and produce either a `&` or `*` pointer.
     Borrow(AutoBorrow<'tcx>),
 
-    /// Unsize a pointer/reference value, e.g. `&[T; n]` to
+    /// Unsize a pointer/reference value, e.g., `&[T; n]` to
     /// `&[T]`. Note that the source could be a thin or fat pointer.
     /// This will do things like convert thin pointers to fat
     /// pointers, or convert structs containing thin pointers to
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
index 8738f57..5ad7d24 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -92,7 +92,7 @@
     let leb128_bits = len * 7;
 
     // Check that the shorthand is a not longer than the
-    // full encoding itself, i.e. it's an obvious win.
+    // full encoding itself, i.e., it's an obvious win.
     if leb128_bits >= 64 || (shorthand as u64) < (1 << leb128_bits) {
         cache(encoder).insert(value.clone(), shorthand);
     }
diff --git a/src/librustc/ty/constness.rs b/src/librustc/ty/constness.rs
index bc06167..3741f40 100644
--- a/src/librustc/ty/constness.rs
+++ b/src/librustc/ty/constness.rs
@@ -67,10 +67,10 @@
 pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
     /// only checks whether the function has a `const` modifier
     fn is_const_fn_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
-        let node_id = tcx.hir.as_local_node_id(def_id)
+        let node_id = tcx.hir().as_local_node_id(def_id)
                              .expect("Non-local call to local provider is_const_fn");
 
-        if let Some(fn_like) = FnLikeNode::from_node(tcx.hir.get(node_id)) {
+        if let Some(fn_like) = FnLikeNode::from_node(tcx.hir().get(node_id)) {
             fn_like.constness() == hir::Constness::Const
         } else {
             false
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 42a4de1..e27d734 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -250,11 +250,11 @@
         if let Some(local_id_root) = local_id_root {
             if hir_id.owner != local_id_root.index {
                 ty::tls::with(|tcx| {
-                    let node_id = tcx.hir.hir_to_node_id(hir_id);
+                    let node_id = tcx.hir().hir_to_node_id(hir_id);
 
                     bug!("node {} with HirId::owner {:?} cannot be placed in \
                           TypeckTables with local_id_root {:?}",
-                         tcx.hir.node_to_string(node_id),
+                         tcx.hir().node_to_string(node_id),
                          DefId::local(hir_id.owner),
                          local_id_root)
                 });
@@ -530,8 +530,8 @@
         self.node_id_to_type_opt(id).unwrap_or_else(||
             bug!("node_id_to_type: no type for node `{}`",
                  tls::with(|tcx| {
-                     let id = tcx.hir.hir_to_node_id(id);
-                     tcx.hir.node_to_string(id)
+                     let id = tcx.hir().hir_to_node_id(id);
+                     tcx.hir().node_to_string(id)
                  }))
         )
     }
@@ -587,7 +587,7 @@
     // auto-ref.  The type returned by this function does not consider such
     // adjustments.  See `expr_ty_adjusted()` instead.
     //
-    // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
+    // NB (2): This type doesn't provide type parameter substitutions; e.g., if you
     // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
     // instead of "fn(ty) -> T with T = isize".
     pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
@@ -903,7 +903,7 @@
     /// Export map produced by name resolution.
     export_map: FxHashMap<DefId, Lrc<Vec<Export>>>,
 
-    pub hir: hir_map::Map<'tcx>,
+    hir_map: hir_map::Map<'tcx>,
 
     /// A map from DefPathHash -> DefId. Includes DefIds from the local crate
     /// as well as all upstream crates. Only populated in incremental mode.
@@ -946,7 +946,7 @@
     /// Stores the value of constants (and deduplicates the actual memory)
     allocation_interner: Lock<FxHashMap<&'tcx Allocation, ()>>,
 
-    pub alloc_map: Lock<interpret::AllocMap<'tcx, &'tcx Allocation>>,
+    pub alloc_map: Lock<interpret::AllocMap<'tcx>>,
 
     layout_interner: Lock<FxHashMap<&'tcx LayoutDetails, ()>>,
 
@@ -971,6 +971,11 @@
         }
     }
 
+    #[inline(always)]
+    pub fn hir(self) -> &'a hir_map::Map<'gcx> {
+        &self.hir_map
+    }
+
     pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics {
         self.global_arenas.generics.alloc(generics)
     }
@@ -1186,7 +1191,7 @@
                     .map(|(id, sp)| (hir.local_def_id(id), sp))
                     .collect(),
             extern_prelude: resolutions.extern_prelude,
-            hir,
+            hir_map: hir,
             def_path_hash_to_def_id,
             queries: query::Queries::new(
                 providers,
@@ -1272,7 +1277,7 @@
 
     pub fn def_key(self, id: DefId) -> hir_map::DefKey {
         if id.is_local() {
-            self.hir.def_key(id)
+            self.hir().def_key(id)
         } else {
             self.cstore.def_key(id)
         }
@@ -1285,7 +1290,7 @@
     ///  be a non-local `DefPath`.
     pub fn def_path(self, id: DefId) -> hir_map::DefPath {
         if id.is_local() {
-            self.hir.def_path(id)
+            self.hir().def_path(id)
         } else {
             self.cstore.def_path(id)
         }
@@ -1294,7 +1299,7 @@
     #[inline]
     pub fn def_path_hash(self, def_id: DefId) -> hir_map::DefPathHash {
         if def_id.is_local() {
-            self.hir.definitions().def_path_hash(def_id.index)
+            self.hir().definitions().def_path_hash(def_id.index)
         } else {
             self.cstore.def_path_hash(def_id)
         }
@@ -1332,11 +1337,11 @@
     }
 
     pub fn create_stable_hashing_context(self) -> StableHashingContext<'a> {
-        let krate = self.dep_graph.with_ignore(|| self.gcx.hir.krate());
+        let krate = self.dep_graph.with_ignore(|| self.hir().krate());
 
         StableHashingContext::new(self.sess,
                                   krate,
-                                  self.hir.definitions(),
+                                  self.hir().definitions(),
                                   self.cstore)
     }
 
@@ -1493,12 +1498,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,
             },
         }
     }
@@ -1530,10 +1529,10 @@
             _ => return None, // not a free region
         };
 
-        let node_id = self.hir
+        let node_id = self.hir()
             .as_local_node_id(suitable_region_binding_scope)
             .unwrap();
-        let is_impl_item = match self.hir.find(node_id) {
+        let is_impl_item = match self.hir().find(node_id) {
             Some(Node::Item(..)) | Some(Node::TraitItem(..)) => false,
             Some(Node::ImplItem(..)) => {
                 self.is_bound_region_in_impl_item(suitable_region_binding_scope)
@@ -1553,8 +1552,8 @@
         scope_def_id: DefId,
     ) -> Option<Ty<'tcx>> {
         // HACK: `type_of_def_id()` will fail on these (#55796), so return None
-        let node_id = self.hir.as_local_node_id(scope_def_id).unwrap();
-        match self.hir.get(node_id) {
+        let node_id = self.hir().as_local_node_id(scope_def_id).unwrap();
+        match self.hir().get(node_id) {
             Node::Item(item) => {
                 match item.node {
                     ItemKind::Fn(..) => { /* type_of_def_id() will work */ }
@@ -1655,7 +1654,7 @@
 /// For Ty, None can be returned if either the type interner doesn't
 /// contain the TyKind key or if the address of the interned
 /// pointer differs. The latter case is possible if a primitive type,
-/// e.g. `()` or `u8`, was interned in a different context.
+/// e.g., `()` or `u8`, was interned in a different context.
 pub trait Lift<'tcx>: fmt::Debug {
     type Lifted: fmt::Debug + 'tcx;
     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted>;
@@ -1948,8 +1947,12 @@
     /// This is a callback from libsyntax as it cannot access the implicit state
     /// in librustc otherwise
     fn span_debug(span: syntax_pos::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        with(|tcx| {
-            write!(f, "{}", tcx.sess.source_map().span_to_string(span))
+        with_opt(|tcx| {
+            if let Some(tcx) = tcx {
+                write!(f, "{}", tcx.sess.source_map().span_to_string(span))
+            } else {
+                syntax_pos::default_span_debug(span, f)
+            }
         })
     }
 
@@ -2229,7 +2232,7 @@
 }
 impl<'tcx, T: 'tcx+?Sized> Copy for Interned<'tcx, T> {}
 
-// NB: An Interned<Ty> compares and hashes as a sty.
+// N.B., 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 {
         self.0.sty == other.0.sty
@@ -2250,7 +2253,7 @@
     }
 }
 
-// NB: An Interned<List<T>> compares and hashes as its elements.
+// N.B., an `Interned<List<T>>` compares and hashes as its elements.
 impl<'tcx, T: PartialEq> PartialEq for Interned<'tcx, List<T>> {
     fn eq(&self, other: &Interned<'tcx, List<T>>) -> bool {
         self.0[..] == other.0[..]
@@ -2461,7 +2464,7 @@
 
     /// Given a closure signature `sig`, returns an equivalent `fn`
     /// type with the same signature. Detuples and so forth -- so
-    /// e.g. if we have a sig with `Fn<(u32, i32)>` then you would get
+    /// e.g., if we have a sig with `Fn<(u32, i32)>` then you would get
     /// a `fn(u32, i32)`.
     pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
         let converted_sig = sig.map_bound(|s| {
@@ -2710,7 +2713,7 @@
 
     #[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> {
@@ -2866,11 +2869,11 @@
     }
 
     pub fn lint_hir_note<S: Into<MultiSpan>>(self,
-                                              lint: &'static Lint,
-                                              hir_id: HirId,
-                                              span: S,
-                                              msg: &str,
-                                              note: &str) {
+                                             lint: &'static Lint,
+                                             hir_id: HirId,
+                                             span: S,
+                                             msg: &str,
+                                             note: &str) {
         let mut err = self.struct_span_lint_hir(lint, hir_id, span.into(), msg);
         err.note(note);
         err.emit()
@@ -2901,11 +2904,11 @@
         self.dep_graph.with_ignore(|| {
             let sets = self.lint_levels(LOCAL_CRATE);
             loop {
-                let hir_id = self.hir.definitions().node_to_hir_id(id);
+                let hir_id = self.hir().definitions().node_to_hir_id(id);
                 if let Some(pair) = sets.level_and_source(lint, hir_id, self.sess) {
                     return pair
                 }
-                let next = self.hir.get_parent_node(id);
+                let next = self.hir().get_parent_node(id);
                 if next == id {
                     bug!("lint traversal reached the root of the crate");
                 }
@@ -2921,7 +2924,7 @@
                                                     msg: &str)
         -> DiagnosticBuilder<'tcx>
     {
-        let node_id = self.hir.hir_to_node_id(hir_id);
+        let node_id = self.hir().hir_to_node_id(hir_id);
         let (level, src) = self.lint_level_at_node(lint, node_id);
         lint::struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg)
     }
@@ -3013,9 +3016,9 @@
 }
 
 pub fn provide(providers: &mut ty::query::Providers<'_>) {
-    // FIXME(#44234) - almost all of these queries have no sub-queries and
+    // FIXME(#44234): almost all of these queries have no sub-queries and
     // therefore no actual inputs, they're just reading tables calculated in
-    // resolve! Does this work? Unsure! That's what the issue is about
+    // resolve! Does this work? Unsure! That's what the issue is about.
     providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id).cloned();
     providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).cloned();
     providers.crate_name = |tcx, id| {
@@ -3045,16 +3048,16 @@
     };
     providers.lookup_stability = |tcx, id| {
         assert_eq!(id.krate, LOCAL_CRATE);
-        let id = tcx.hir.definitions().def_index_to_hir_id(id.index);
+        let id = tcx.hir().definitions().def_index_to_hir_id(id.index);
         tcx.stability().local_stability(id)
     };
     providers.lookup_deprecation_entry = |tcx, id| {
         assert_eq!(id.krate, LOCAL_CRATE);
-        let id = tcx.hir.definitions().def_index_to_hir_id(id.index);
+        let id = tcx.hir().definitions().def_index_to_hir_id(id.index);
         tcx.stability().local_deprecation_entry(id)
     };
     providers.extern_mod_stmt_cnum = |tcx, id| {
-        let id = tcx.hir.as_local_node_id(id).unwrap();
+        let id = tcx.hir().as_local_node_id(id).unwrap();
         tcx.cstore.extern_mod_stmt_cnum_untracked(id)
     };
     providers.all_crate_nums = |tcx, cnum| {
@@ -3075,10 +3078,10 @@
     };
     providers.is_panic_runtime = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        attr::contains_name(tcx.hir.krate_attrs(), "panic_runtime")
+        attr::contains_name(tcx.hir().krate_attrs(), "panic_runtime")
     };
     providers.is_compiler_builtins = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        attr::contains_name(tcx.hir.krate_attrs(), "compiler_builtins")
+        attr::contains_name(tcx.hir().krate_attrs(), "compiler_builtins")
     };
 }
diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs
index f53e634..a361ad0 100644
--- a/src/librustc/ty/erase_regions.rs
+++ b/src/librustc/ty/erase_regions.rs
@@ -19,7 +19,7 @@
 }
 
 fn erase_regions_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-    // NB: use `super_fold_with` here. If we used `fold_with`, it
+    // N.B., use `super_fold_with` here. If we used `fold_with`, it
     // could invoke the `erase_regions_ty` query recursively.
     ty.super_fold_with(&mut RegionEraserVisitor { tcx })
 }
diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs
index 8304e36..7005e14 100644
--- a/src/librustc/ty/fast_reject.rs
+++ b/src/librustc/ty/fast_reject.rs
@@ -110,7 +110,7 @@
                 // anything. when lazy normalization happens, this
                 // will change. It would still be nice to have a way
                 // to deal with known-not-to-unify-with-anything
-                // projections (e.g. the likes of <__S as Encoder>::Error).
+                // projections (e.g., the likes of <__S as Encoder>::Error).
                 Some(ParameterSimplifiedType)
             } else {
                 None
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index 20f6459..a40e1df 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -887,7 +887,7 @@
 
     /// If true, we only want regions that are known to be
     /// "constrained" when you equate this type with another type. In
-    /// particular, if you have e.g. `&'a u32` and `&'b u32`, equating
+    /// particular, if you have e.g., `&'a u32` and `&'b u32`, equating
     /// them constraints `'a == 'b`.  But if you have `<&'a u32 as
     /// Trait>::Foo` and `<&'b u32 as Trait>::Foo`, normalizing those
     /// types may mean that `'a` and `'b` don't appear in the results,
diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs
index 7bc77e1..163263b 100644
--- a/src/librustc/ty/inhabitedness/def_id_forest.rs
+++ b/src/librustc/ty/inhabitedness/def_id_forest.rs
@@ -43,7 +43,7 @@
     /// crate.
     #[inline]
     pub fn full(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> DefIdForest {
-        let crate_id = tcx.hir.local_def_id(CRATE_NODE_ID);
+        let crate_id = tcx.hir().local_def_id(CRATE_NODE_ID);
         DefIdForest::from_id(crate_id)
     }
 
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/item_path.rs b/src/librustc/ty/item_path.rs
index 350e552..a39eb00 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -83,7 +83,7 @@
 
     /// Returns a string identifying this local node-id.
     pub fn node_path_str(self, id: ast::NodeId) -> String {
-        self.item_path_str(self.hir.local_def_id(id))
+        self.item_path_str(self.hir().local_def_id(id))
     }
 
     /// Returns a string identifying this def-id. This string is
@@ -317,7 +317,7 @@
 
             // Unclear if there is any value in distinguishing these.
             // Probably eventually (and maybe we would even want
-            // finer-grained distinctions, e.g. between enum/struct).
+            // finer-grained distinctions, e.g., between enum/struct).
             data @ DefPathData::Misc |
             data @ DefPathData::TypeNs(..) |
             data @ DefPathData::Trait(..) |
@@ -464,8 +464,8 @@
         // only occur very early in the compiler pipeline.
         let parent_def_id = self.parent_def_id(impl_def_id).unwrap();
         self.push_item_path(buffer, parent_def_id, pushed_prelude_crate);
-        let node_id = self.hir.as_local_node_id(impl_def_id).unwrap();
-        let item = self.hir.expect_item(node_id);
+        let node_id = self.hir().as_local_node_id(impl_def_id).unwrap();
+        let item = self.hir().expect_item(node_id);
         let span_str = self.sess.source_map().span_to_string(item.span);
         buffer.push(&format!("<impl at {}>", span_str));
     }
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 5406495..87d745e 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -248,7 +248,7 @@
             AlwaysSized,
             /// A univariant, the last field of which may be coerced to unsized.
             MaybeUnsized,
-            /// A univariant, but with a prefix of an arbitrary size & alignment (e.g. enum tag).
+            /// A univariant, but with a prefix of an arbitrary size & alignment (e.g., enum tag).
             Prefixed(Size, Align),
         }
 
@@ -748,7 +748,7 @@
 
                 // A variant is absent if it's uninhabited and only has ZST fields.
                 // Present uninhabited variants only require space for their fields,
-                // but *not* an encoding of the discriminant (e.g. a tag value).
+                // but *not* an encoding of the discriminant (e.g., a tag value).
                 // See issue #49298 for more details on the need to leave space
                 // for non-ZST uninhabited data (mostly partial initialization).
                 let absent = |fields: &[TyLayout<'_>]| {
@@ -1252,7 +1252,7 @@
             }).collect();
 
             session::VariantInfo {
-                name: n.map(|n|n.to_string()),
+                name: n.map(|n| n.to_string()),
                 kind: if layout.is_unsized() {
                     session::SizeKind::Min
                 } else {
@@ -1311,7 +1311,7 @@
     }
 }
 
-/// Type size "skeleton", i.e. the only information determining a type's size.
+/// Type size "skeleton", i.e., the only information determining a type's size.
 /// While this is conservative, (aside from constant sizes, only pointers,
 /// newtypes thereof and null pointer optimized enums are allowed), it is
 /// enough to statically check common use cases of transmute.
@@ -1522,7 +1522,7 @@
             details
         };
 
-        // NB: This recording is normally disabled; when enabled, it
+        // N.B., this recording is normally disabled; when enabled, it
         // can however trigger recursive invocations of `layout_of`.
         // Therefore, we execute it *after* the main query has
         // completed, to avoid problems around recursive structures
@@ -1549,7 +1549,7 @@
             details
         };
 
-        // NB: This recording is normally disabled; when enabled, it
+        // N.B., this recording is normally disabled; when enabled, it
         // can however trigger recursive invocations of `layout_of`.
         // Therefore, we execute it *after* the main query has
         // completed, to avoid problems around recursive structures
@@ -1660,7 +1660,7 @@
                 assert!(i < this.fields.count());
 
                 // Reuse the fat *T type as its own thin pointer data field.
-                // This provides information about e.g. DST struct pointees
+                // This provides information about e.g., DST struct pointees
                 // (which may have no non-DST form), and will work as long
                 // as the `Abi` or `FieldPlacement` is checked by users.
                 if i == 0 {
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 4633ab1..a1fc949 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -125,7 +125,7 @@
 /// The complete set of all analyses described in this module. This is
 /// produced by the driver and fed to codegen and later passes.
 ///
-/// NB: These contents are being migrated into queries using the
+/// N.B., these contents are being migrated into queries using the
 /// *on-demand* infrastructure.
 #[derive(Clone)]
 pub struct CrateAnalysis {
@@ -289,7 +289,7 @@
                 def => Visibility::Restricted(def.def_id()),
             },
             hir::VisibilityKind::Inherited => {
-                Visibility::Restricted(tcx.hir.get_module_parent(id))
+                Visibility::Restricted(tcx.hir().get_module_parent(id))
             }
         }
     }
@@ -505,15 +505,15 @@
     ///     by some sub-binder.
     ///
     /// So, for a type without any late-bound things, like `u32`, this
-    /// will be INNERMOST, because that is the innermost binder that
+    /// will be *innermost*, because that is the innermost binder that
     /// captures nothing. But for a type `&'D u32`, where `'D` is a
-    /// late-bound region with debruijn index D, this would be D+1 --
-    /// the binder itself does not capture D, but D is captured by an
-    /// inner binder.
+    /// late-bound region with debruijn index `D`, this would be `D + 1`
+    /// -- the binder itself does not capture `D`, but `D` is captured
+    /// by an inner binder.
     ///
-    /// We call this concept an "exclusive" binder D (because all
+    /// We call this concept an "exclusive" binder `D` because all
     /// debruijn indices within the type are contained within `0..D`
-    /// (exclusive)).
+    /// (exclusive).
     outer_exclusive_binder: ty::DebruijnIndex,
 }
 
@@ -900,10 +900,10 @@
 }
 
 /// Information about the formal type/lifetime parameters associated
-/// with an item or method. Analogous to hir::Generics.
+/// with an item or method. Analogous to `hir::Generics`.
 ///
-/// The ordering of parameters is the same as in Subst (excluding child generics):
-/// Self (optionally), Lifetime params..., Type params...
+/// The ordering of parameters is the same as in `Subst` (excluding child generics):
+/// `Self` (optionally), `Lifetime` params..., `Type` params...
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct Generics {
     pub parent: Option<DefId>,
@@ -1681,7 +1681,7 @@
     /// pair it with the empty environment. This improves caching and is generally
     /// invisible.
     ///
-    /// NB: We preserve the environment when type-checking because it
+    /// N.B., we preserve the environment when type-checking because it
     /// is possible for the user to have wacky where-clauses like
     /// `where Box<u32>: Copy`, which are clearly never
     /// satisfiable. We generally want to behave as if they were true,
@@ -1778,8 +1778,8 @@
 
 #[derive(Debug)]
 pub struct VariantDef {
-    /// The variant's DefId. If this is a tuple-like struct,
-    /// this is the DefId of the struct's ctor.
+    /// The variant's `DefId`. If this is a tuple-like struct,
+    /// this is the `DefId` of the struct's ctor.
     pub did: DefId,
     pub name: Name, // struct's name if this is a struct
     pub discr: VariantDiscr,
@@ -1798,7 +1798,7 @@
     ///
     /// Note that we *could* use the constructor DefId, because the constructor attributes
     /// redirect to the base attributes, but compiling a small crate requires
-    /// loading the AdtDefs for all the structs in the universe (e.g. coherence for any
+    /// loading the AdtDefs for all the structs in the universe (e.g., coherence for any
     /// built-in trait), and we do not want to load attributes twice.
     ///
     /// If someone speeds up attribute loading to not be a performance concern, they can
@@ -1847,7 +1847,7 @@
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum VariantDiscr {
-    /// Explicit value for this variant, i.e. `X = 123`.
+    /// Explicit value for this variant, i.e., `X = 123`.
     /// The `DefId` corresponds to the embedded constant.
     Explicit(DefId),
 
@@ -1865,9 +1865,9 @@
     pub vis: Visibility,
 }
 
-/// The definition of an abstract data type - a struct or enum.
+/// The definition of an abstract data type -- a struct or enum.
 ///
-/// These are all interned (by intern_adt_def) into the adt_defs
+/// These are all interned (by `intern_adt_def`) into the `adt_defs`
 /// table.
 pub struct AdtDef {
     pub did: DefId,
@@ -2367,7 +2367,7 @@
     /// Self would prevent its containing ADT from being Sized.
     ///
     /// Due to normalization being eager, this applies even if
-    /// the associated type is behind a pointer, e.g. issue #31299.
+    /// the associated type is behind a pointer, e.g., issue #31299.
     pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx [Ty<'tcx>] {
         match tcx.try_adt_sized_constraint(DUMMY_SP, self.did) {
             Ok(tys) => tys,
@@ -2619,29 +2619,29 @@
 
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn body_tables(self, body: hir::BodyId) -> &'gcx TypeckTables<'gcx> {
-        self.typeck_tables_of(self.hir.body_owner_def_id(body))
+        self.typeck_tables_of(self.hir().body_owner_def_id(body))
     }
 
     /// Returns an iterator of the def-ids for all body-owners in this
     /// crate. If you would prefer to iterate over the bodies
-    /// themselves, you can do `self.hir.krate().body_ids.iter()`.
+    /// themselves, you can do `self.hir().krate().body_ids.iter()`.
     pub fn body_owners(
         self,
     ) -> impl Iterator<Item = DefId> + Captures<'tcx> + Captures<'gcx> + 'a {
-        self.hir.krate()
-                .body_ids
-                .iter()
-                .map(move |&body_id| self.hir.body_owner_def_id(body_id))
+        self.hir().krate()
+                  .body_ids
+                  .iter()
+                  .map(move |&body_id| self.hir().body_owner_def_id(body_id))
     }
 
     pub fn par_body_owners<F: Fn(DefId) + sync::Sync + sync::Send>(self, f: F) {
-        par_iter(&self.hir.krate().body_ids).for_each(|&body_id| {
-            f(self.hir.body_owner_def_id(body_id))
+        par_iter(&self.hir().krate().body_ids).for_each(|&body_id| {
+            f(self.hir().body_owner_def_id(body_id))
         });
     }
 
     pub fn expr_span(self, id: NodeId) -> Span {
-        match self.hir.find(id) {
+        match self.hir().find(id) {
             Some(Node::Expr(e)) => {
                 e.span
             }
@@ -2667,8 +2667,8 @@
     }
 
     pub fn opt_associated_item(self, def_id: DefId) -> Option<AssociatedItem> {
-        let is_associated_item = if let Some(node_id) = self.hir.as_local_node_id(def_id) {
-            match self.hir.get(node_id) {
+        let is_associated_item = if let Some(node_id) = self.hir().as_local_node_id(def_id) {
+            match self.hir().get(node_id) {
                 Node::TraitItem(_) | Node::ImplItem(_) => true,
                 _ => false,
             }
@@ -2691,7 +2691,7 @@
                                            parent_vis: &hir::Visibility,
                                            trait_item_ref: &hir::TraitItemRef)
                                            -> AssociatedItem {
-        let def_id = self.hir.local_def_id(trait_item_ref.id.node_id);
+        let def_id = self.hir().local_def_id(trait_item_ref.id.node_id);
         let (kind, has_self) = match trait_item_ref.kind {
             hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false),
             hir::AssociatedItemKind::Method { has_self } => {
@@ -2717,7 +2717,7 @@
                                           parent_def_id: DefId,
                                           impl_item_ref: &hir::ImplItemRef)
                                           -> AssociatedItem {
-        let def_id = self.hir.local_def_id(impl_item_ref.id.node_id);
+        let def_id = self.hir().local_def_id(impl_item_ref.id.node_id);
         let (kind, has_self) = match impl_item_ref.kind {
             hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false),
             hir::AssociatedItemKind::Method { has_self } => {
@@ -2740,7 +2740,7 @@
     }
 
     pub fn field_index(self, node_id: NodeId, tables: &TypeckTables<'_>) -> usize {
-        let hir_id = self.hir.node_to_hir_id(node_id);
+        let hir_id = self.hir().node_to_hir_id(node_id);
         tables.field_indices().get(hir_id).cloned().expect("no index for a field")
     }
 
@@ -2878,8 +2878,8 @@
 
     /// Get the attributes of a definition.
     pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> {
-        if let Some(id) = self.hir.as_local_node_id(did) {
-            Attributes::Borrowed(self.hir.attrs(id))
+        if let Some(id) = self.hir().as_local_node_id(did) {
+            Attributes::Borrowed(self.hir().attrs(id))
         } else {
             Attributes::Owned(self.item_attrs(did))
         }
@@ -2930,8 +2930,8 @@
     /// with the name of the crate containing the impl.
     pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
         if impl_did.is_local() {
-            let node_id = self.hir.as_local_node_id(impl_did).unwrap();
-            Ok(self.hir.span(node_id))
+            let node_id = self.hir().as_local_node_id(impl_did).unwrap();
+            Ok(self.hir().span(node_id))
         } else {
             Err(self.crate_name(impl_did.krate))
         }
@@ -2947,14 +2947,14 @@
     pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: NodeId) -> (Ident, DefId) {
         ident = ident.modern();
         let target_expansion = match scope.krate {
-            LOCAL_CRATE => self.hir.definitions().expansion_that_defined(scope.index),
+            LOCAL_CRATE => self.hir().definitions().expansion_that_defined(scope.index),
             _ => Mark::root(),
         };
         let scope = match ident.span.adjust(target_expansion) {
             Some(actual_expansion) =>
-                self.hir.definitions().parent_module_of_macro_def(actual_expansion),
+                self.hir().definitions().parent_module_of_macro_def(actual_expansion),
             None if block == DUMMY_NODE_ID => DefId::local(CRATE_DEF_INDEX), // Dummy DefId
-            None => self.hir.get_module_parent(block),
+            None => self.hir().get_module_parent(block),
         };
         (ident, scope)
     }
@@ -2980,7 +2980,7 @@
     pub fn with_freevars<T, F>(self, fid: NodeId, f: F) -> T where
         F: FnOnce(&[hir::Freevar]) -> T,
     {
-        let def_id = self.hir.local_def_id(fid);
+        let def_id = self.hir().local_def_id(fid);
         match self.freevars(def_id) {
             None => f(&[]),
             Some(d) => f(&d),
@@ -2989,10 +2989,10 @@
 }
 
 fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> AssociatedItem {
-    let id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let parent_id = tcx.hir.get_parent(id);
-    let parent_def_id = tcx.hir.local_def_id(parent_id);
-    let parent_item = tcx.hir.expect_item(parent_id);
+    let id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let parent_id = tcx.hir().get_parent(id);
+    let parent_def_id = tcx.hir().local_def_id(parent_id);
+    let parent_item = tcx.hir().expect_item(parent_id);
     match parent_item.node {
         hir::ItemKind::Impl(.., ref impl_item_refs) => {
             if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.node_id == id) {
@@ -3049,19 +3049,19 @@
 fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      def_id: DefId)
                                      -> Lrc<Vec<DefId>> {
-    let id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let item = tcx.hir.expect_item(id);
+    let id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let item = tcx.hir().expect_item(id);
     let vec: Vec<_> = match item.node {
         hir::ItemKind::Trait(.., ref trait_item_refs) => {
             trait_item_refs.iter()
                            .map(|trait_item_ref| trait_item_ref.id)
-                           .map(|id| tcx.hir.local_def_id(id.node_id))
+                           .map(|id| tcx.hir().local_def_id(id.node_id))
                            .collect()
         }
         hir::ItemKind::Impl(.., ref impl_item_refs) => {
             impl_item_refs.iter()
                           .map(|impl_item_ref| impl_item_ref.id)
-                          .map(|id| tcx.hir.local_def_id(id.node_id))
+                          .map(|id| tcx.hir().local_def_id(id.node_id))
                           .collect()
         }
         hir::ItemKind::TraitAlias(..) => vec![],
@@ -3071,7 +3071,7 @@
 }
 
 fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span {
-    tcx.hir.span_if_local(def_id).unwrap()
+    tcx.hir().span_if_local(def_id).unwrap()
 }
 
 /// If the given def ID describes an item belonging to a trait,
@@ -3089,8 +3089,8 @@
 
 /// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition.
 pub fn is_impl_trait_defn(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<DefId> {
-    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-        if let Node::Item(item) = tcx.hir.get(node_id) {
+    if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
+        if let Node::Item(item) = tcx.hir().get(node_id) {
             if let hir::ItemKind::Existential(ref exist_ty) = item.node {
                 return exist_ty.impl_trait_fn;
             }
@@ -3101,8 +3101,8 @@
 
 /// Returns `true` if `def_id` is a trait alias.
 pub fn is_trait_alias(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> bool {
-    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-        if let Node::Item(item) = tcx.hir.get(node_id) {
+    if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
+        if let Node::Item(item) = tcx.hir().get(node_id) {
             if let hir::ItemKind::TraitAlias(..) = item.node {
                 return true;
             }
@@ -3140,8 +3140,8 @@
     let unnormalized_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates),
                                              traits::Reveal::UserFacing);
 
-    let body_id = tcx.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| {
-        tcx.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id)
+    let body_id = tcx.hir().as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| {
+        tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.node_id)
     });
     let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
     traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
@@ -3163,7 +3163,7 @@
                         crate_num: CrateNum)
                         -> Svh {
     assert_eq!(crate_num, LOCAL_CRATE);
-    tcx.hir.crate_hash
+    tcx.hir().crate_hash
 }
 
 fn instance_def_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index 5d12aae..fd9143b 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -227,9 +227,9 @@
 
 impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, (_, def_id): (DefId, DefId)) -> Cow<'static, str> {
-        let id = tcx.hir.as_local_node_id(def_id).unwrap();
+        let id = tcx.hir().as_local_node_id(def_id).unwrap();
         format!("computing the bounds for type parameter `{}`",
-                tcx.hir.ty_param_name(id)).into()
+                tcx.hir().ty_param_name(id)).into()
     }
 }
 
diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs
index d588bc8..1439e41 100644
--- a/src/librustc/ty/query/job.rs
+++ b/src/librustc/ty/query/job.rs
@@ -103,8 +103,11 @@
                     condvar: Condvar::new(),
                 });
                 self.latch.await(&waiter);
-
-                match Lrc::get_mut(&mut waiter).unwrap().cycle.get_mut().take() {
+                // FIXME: Get rid of this lock. We have ownership of the QueryWaiter
+                // although another thread may still have a Lrc reference so we cannot
+                // use Lrc::get_mut
+                let mut cycle = waiter.cycle.lock();
+                match cycle.take() {
                     None => Ok(()),
                     Some(cycle) => Err(cycle)
                 }
@@ -326,19 +329,17 @@
     query: Lrc<QueryJob<'tcx>>,
     visited: &mut FxHashSet<*const QueryJob<'tcx>>
 ) -> bool {
-    // This query is connected to the root (it has no query parent), return true
-    if query.parent.is_none() {
-        return true;
-    }
-
     // We already visited this or we're deliberately ignoring it
     if visited.contains(&query.as_ptr()) {
         return false;
     }
 
-    visited.insert(query.as_ptr());
+    // This query is connected to the root (it has no query parent), return true
+    if query.parent.is_none() {
+        return true;
+    }
 
-    let mut connected = false;
+    visited.insert(query.as_ptr());
 
     visit_waiters(query, |_, successor| {
         if connected_to_root(successor, visited) {
@@ -349,6 +350,28 @@
     }).is_some()
 }
 
+// Deterministically pick an query from a list
+#[cfg(parallel_queries)]
+fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, Lrc<QueryJob<'tcx>>)>(
+    tcx: TyCtxt<'_, 'tcx, '_>,
+    queries: &'a [T],
+    f: F
+) -> &'a T {
+    // Deterministically pick an entry point
+    // FIXME: Sort this instead
+    let mut hcx = tcx.create_stable_hashing_context();
+    queries.iter().min_by_key(|v| {
+        let (span, query) = f(v);
+        let mut stable_hasher = StableHasher::<u64>::new();
+        query.info.query.hash_stable(&mut hcx, &mut stable_hasher);
+        // Prefer entry points which have valid spans for nicer error messages
+        // We add an integer to the tuple ensuring that entry points
+        // with valid spans are picked first
+        let span_cmp = if span == DUMMY_SP { 1 } else { 0 };
+        (span_cmp, stable_hasher.finish())
+    }).unwrap()
+}
+
 /// Looks for query cycles starting from the last query in `jobs`.
 /// If a cycle is found, all queries in the cycle is removed from `jobs` and
 /// the function return true.
@@ -388,41 +411,52 @@
 
         // Find the queries in the cycle which are
         // connected to queries outside the cycle
-        let entry_points = stack.iter().filter_map(|query| {
-            // Mark all the other queries in the cycle as already visited
-            let mut visited = FxHashSet::from_iter(stack.iter().filter_map(|q| {
-                if q.1.as_ptr() != query.1.as_ptr() {
-                    Some(q.1.as_ptr())
-                } else {
-                    None
-                }
-            }));
-
-            if connected_to_root(query.1.clone(), &mut visited) {
-                Some(query.1.clone())
+        let entry_points: Vec<_> = stack.iter().filter_map(|(span, query)| {
+            if query.parent.is_none() {
+                // This query is connected to the root (it has no query parent)
+                Some((*span, query.clone(), None))
             } else {
-                None
+                let mut waiters = Vec::new();
+                // Find all the direct waiters who lead to the root
+                visit_waiters(query.clone(), |span, waiter| {
+                    // Mark all the other queries in the cycle as already visited
+                    let mut visited = FxHashSet::from_iter(stack.iter().map(|q| q.1.as_ptr()));
+
+                    if connected_to_root(waiter.clone(), &mut visited) {
+                        waiters.push((span, waiter));
+                    }
+
+                    None
+                });
+                if waiters.is_empty() {
+                    None
+                } else {
+                    // Deterministically pick one of the waiters to show to the user
+                    let waiter = pick_query(tcx, &waiters, |s| s.clone()).clone();
+                    Some((*span, query.clone(), Some(waiter)))
+                }
             }
-        });
+        }).collect();
+
+        let entry_points: Vec<(Span, Lrc<QueryJob<'tcx>>, Option<(Span, Lrc<QueryJob<'tcx>>)>)>
+         = entry_points;
 
         // Deterministically pick an entry point
-        // FIXME: Sort this instead
-        let mut hcx = tcx.create_stable_hashing_context();
-        let entry_point = entry_points.min_by_key(|q| {
-            let mut stable_hasher = StableHasher::<u64>::new();
-            q.info.query.hash_stable(&mut hcx, &mut stable_hasher);
-            stable_hasher.finish()
-        }).unwrap().as_ptr();
+        let (_, entry_point, usage) = pick_query(tcx, &entry_points, |e| (e.0, e.1.clone()));
 
         // Shift the stack so that our entry point is first
-        let entry_point_pos = stack.iter().position(|(_, query)| query.as_ptr() == entry_point);
+        let entry_point_pos = stack.iter().position(|(_, query)| {
+            query.as_ptr() == entry_point.as_ptr()
+        });
         if let Some(pos) = entry_point_pos {
-            stack.rotate_right(pos);
+            stack.rotate_left(pos);
         }
 
+        let usage = usage.as_ref().map(|(span, query)| (*span, query.info.query.clone()));
+
         // Create the cycle error
         let mut error = CycleError {
-            usage: None,
+            usage,
             cycle: stack.iter().map(|&(s, ref q)| QueryInfo {
                 span: s,
                 query: q.info.query.clone(),
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index 699c2d1..5cd06fb 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -166,21 +166,21 @@
         ) -> Result<DtorckConstraint<'tcx>, NoSolution>,
 
         /// True if this is a const fn, use the `is_const_fn` to know whether your crate actually
-        /// sees it as const fn (e.g. the const-fn-ness might be unstable and you might not have
+        /// sees it as const fn (e.g., the const-fn-ness might be unstable and you might not have
         /// the feature gate active)
         ///
-        /// DO NOT CALL MANUALLY, it is only meant to cache the base data for the `is_const_fn`
-        /// function
+        /// **Do not call this function manually.** It is only meant to cache the base data for the
+        /// `is_const_fn` function.
         [] fn is_const_fn_raw: IsConstFn(DefId) -> bool,
 
 
         /// Returns true if calls to the function may be promoted
         ///
-        /// This is either because the function is e.g. a tuple-struct or tuple-variant constructor,
-        /// or because it has the `#[rustc_promotable]` attribute. The attribute should be removed
-        /// in the future in favour of some form of check which figures out whether the function
-        /// does not inspect the bits of any of its arguments (so is essentially just a constructor
-        /// function)
+        /// This is either because the function is e.g., a tuple-struct or tuple-variant
+        /// constructor, or because it has the `#[rustc_promotable]` attribute. The attribute should
+        /// be removed in the future in favour of some form of check which figures out whether the
+        /// function does not inspect the bits of any of its arguments (so is essentially just a
+        /// constructor function).
         [] fn is_promotable_const_fn: IsPromotableConstFn(DefId) -> bool,
 
         /// True if this is a foreign item (i.e., linked via `extern { ... }`).
@@ -539,7 +539,7 @@
         [] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Lrc<Vec<CrateNum>>,
 
         /// A vector of every trait accessible in the whole crate
-        /// (i.e. including those from subcrates). This is used only for
+        /// (i.e., including those from subcrates). This is used only for
         /// error reporting.
         [] fn all_traits: all_traits_node(CrateNum) -> Lrc<Vec<DefId>>,
     },
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 7d3ae64..04c8808 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -725,7 +725,7 @@
     #[inline]
     fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
         let hir_id = hir::HirId::decode(self)?;
-        Ok(self.tcx().hir.hir_to_node_id(hir_id))
+        Ok(self.tcx().hir().hir_to_node_id(hir_id))
     }
 }
 
@@ -926,7 +926,7 @@
             local_id,
         } = *id;
 
-        let def_path_hash = self.tcx.hir.definitions().def_path_hash(owner);
+        let def_path_hash = self.tcx.hir().definitions().def_path_hash(owner);
 
         def_path_hash.encode(self)?;
         local_id.encode(self)
@@ -968,7 +968,7 @@
 {
     #[inline]
     fn specialized_encode(&mut self, node_id: &NodeId) -> Result<(), Self::Error> {
-        let hir_id = self.tcx.hir.node_to_hir_id(*node_id);
+        let hir_id = self.tcx.hir().node_to_hir_id(*node_id);
         hir_id.encode(self)
     }
 }
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 1b64a68..7ad4fd5 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Generalized type relating mechanism. A type relation R relates a
-//! pair of values (A, B). A and B are usually types or regions but
-//! can be other things. Examples of type relations are subtyping,
-//! type equality, etc.
+//! Generalized type relating mechanism.
+//!
+//! A type relation `R` relates a pair of values `(A, B)`. `A and B` are usually
+//! types or regions but can be other things. Examples of type relations are
+//! subtyping, type equality, etc.
 
 use hir::def_id::DefId;
 use mir::interpret::ConstValue;
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 1416cb1..f757f48 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -8,8 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! This module contains TyKind and its major components
+//! This module contains `TyKind` and its major components.
 
+use hir;
 use hir::def_id::DefId;
 use infer::canonical::Canonical;
 use mir::interpret::ConstValue;
@@ -30,9 +31,6 @@
 use syntax::symbol::{keywords, InternedString};
 
 use serialize;
-
-use hir;
-
 use self::InferTy::*;
 use self::TyKind::*;
 
@@ -91,7 +89,7 @@
     }
 }
 
-/// N.B., If you change this, you'll probably want to change the corresponding
+/// N.B., if you change this, you'll probably want to change the corresponding
 /// AST structure in `libsyntax/ast.rs` as well.
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub enum TyKind<'tcx> {
@@ -531,11 +529,11 @@
 
 #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub enum ExistentialPredicate<'tcx> {
-    /// e.g. Iterator
+    /// e.g., Iterator
     Trait(ExistentialTraitRef<'tcx>),
-    /// e.g. Iterator::Item = T
+    /// e.g., Iterator::Item = T
     Projection(ExistentialProjection<'tcx>),
-    /// e.g. Send
+    /// e.g., Send
     AutoTrait(DefId),
 }
 
@@ -784,7 +782,7 @@
 /// Binder<TraitRef>`). Note that when we instantiate,
 /// erase, or otherwise "discharge" these bound vars, we change the
 /// type from `Binder<T>` to just `T` (see
-/// e.g. `liberate_late_bound_regions`).
+/// e.g., `liberate_late_bound_regions`).
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct Binder<T>(T);
 
@@ -1020,7 +1018,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 {
@@ -1035,7 +1033,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
     }
 }
 
@@ -1099,12 +1097,12 @@
 /// with some concrete region before being used. There are 2 kind of
 /// bound regions: early-bound, which are bound in an item's Generics,
 /// and are substituted by a Substs,  and late-bound, which are part of
-/// higher-ranked types (e.g. `for<'a> fn(&'a ())`) and are substituted by
+/// higher-ranked types (e.g., `for<'a> fn(&'a ())`) and are substituted by
 /// the likes of `liberate_late_bound_regions`. The distinction exists
 /// because higher-ranked lifetimes aren't supported in all places. See [1][2].
 ///
 /// Unlike Param-s, bound regions are not supposed to exist "in the wild"
-/// outside their binder, e.g. in types passed to type inference, and
+/// outside their binder, e.g., in types passed to type inference, and
 /// should first be substituted (by placeholder regions, free regions,
 /// or region variables).
 ///
@@ -1160,7 +1158,7 @@
     ReFree(FreeRegion),
 
     /// A concrete region naming some statically determined scope
-    /// (e.g. an expression or sequence of statements) within the
+    /// (e.g., an expression or sequence of statements) within the
     /// current function.
     ReScope(region::Scope),
 
@@ -1324,7 +1322,7 @@
 
 impl DebruijnIndex {
     /// Returns the resulting index when this value is moved into
-    /// `amount` number of new binders. So e.g. if you had
+    /// `amount` number of new binders. So e.g., if you had
     ///
     ///    for<'a> fn(&'a x)
     ///
@@ -1332,7 +1330,7 @@
     ///
     ///    for<'a> fn(for<'b> fn(&'a x))
     ///
-    /// you would need to shift the index for `'a` into 1 new binder.
+    /// you would need to shift the index for `'a` into a new binder.
     #[must_use]
     pub fn shifted_in(self, amount: u32) -> DebruijnIndex {
         DebruijnIndex::from_u32(self.as_u32() + amount)
@@ -1787,6 +1785,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,
@@ -1802,10 +1807,10 @@
         }
     }
 
-    /// Returns the type and mutability of *ty.
+    /// Returns the type and mutability of `*ty`.
     ///
     /// The parameter `explicit` indicates if this is an *explicit* dereference.
-    /// Some types---notably unsafe ptrs---can only be dereferenced explicitly.
+    /// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
     pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
         match self.sty {
             Adt(def, _) if def.is_box() => {
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index 3425203..cda281e 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -316,10 +316,10 @@
     }
 
     /// Transform from substitutions for a child of `source_ancestor`
-    /// (e.g. a trait or impl) to substitutions for the same child
+    /// (e.g., a trait or impl) to substitutions for the same child
     /// in a different item, with `target_substs` as the base for
     /// the target impl/trait, with the source child-specific
-    /// parameters (e.g. method parameters) on top of that base.
+    /// parameters (e.g., method parameters) on top of that base.
     pub fn rebase_onto(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                        source_ancestor: DefId,
                        target_substs: &Substs<'tcx>)
diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs
index af678c3..fadb1a1 100644
--- a/src/librustc/ty/trait_def.rs
+++ b/src/librustc/ty/trait_def.rs
@@ -189,8 +189,8 @@
             }
         }
 
-        for &node_id in tcx.hir.trait_impls(trait_id) {
-            add_impl(tcx.hir.local_def_id(node_id));
+        for &node_id in tcx.hir().trait_impls(trait_id) {
+            add_impl(tcx.hir().local_def_id(node_id));
         }
     }
 
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 51b197d..f9ce228 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -344,7 +344,7 @@
     /// themselves. This should really be a unique type; `FreshTy(0)` is a
     /// popular choice.
     ///
-    /// NB: in some cases, particularly around higher-ranked bounds,
+    /// N.B., in some cases, particularly around higher-ranked bounds,
     /// this function returns a kind of conservative approximation.
     /// That is, all regions returned by this function are definitely
     /// required, but there may be other region bounds that are not
@@ -451,9 +451,9 @@
         // destructor will not access borrowed data,
         // even if such data is otherwise reachable.
         //
-        // Such access can be in plain sight (e.g. dereferencing
+        // Such access can be in plain sight (e.g., dereferencing
         // `*foo.0` of `Foo<'a>(&'a u32)`) or indirectly hidden
-        // (e.g. calling `foo.0.clone()` of `Foo<T:Clone>`).
+        // (e.g., calling `foo.0.clone()` of `Foo<T:Clone>`).
         if self.has_attr(dtor, "unsafe_destructor_blind_to_params") {
             debug!("destructor_constraint({:?}) - blind", def.did);
             return vec![];
@@ -601,7 +601,7 @@
 
     /// Return whether the node pointed to by def_id is a static item, and its mutability
     pub fn is_static(&self, def_id: DefId) -> Option<hir::Mutability> {
-        if let Some(node) = self.hir.get_if_local(def_id) {
+        if let Some(node) = self.hir().get_if_local(def_id) {
             match node {
                 Node::Item(&hir::Item {
                     node: hir::ItemKind::Static(_, mutbl, _), ..
@@ -656,7 +656,7 @@
 
     /// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely
     /// non-copy and *might* have a destructor attached; if it returns
-    /// `false`, then `ty` definitely has no destructor (i.e. no drop glue).
+    /// `false`, then `ty` definitely has no destructor (i.e., no drop glue).
     ///
     /// (Note that this implies that if `ty` has a destructor attached,
     /// then `needs_drop` will definitely return `true` for `ty`.)
@@ -711,7 +711,7 @@
                     // Find non representable fields with their spans
                     fold_repr(def.all_fields().map(|field| {
                         let ty = field.ty(tcx, substs);
-                        let span = tcx.hir.span_if_local(field.did).unwrap_or(sp);
+                        let span = tcx.hir().span_if_local(field.did).unwrap_or(sp);
                         match is_type_structurally_recursive(tcx, span, seen,
                                                              representable_cache, ty)
                         {
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 7a246af..68e1978 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -28,7 +28,7 @@
 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.
@@ -342,7 +342,7 @@
     /// If `key` is present in the map, return the value,
     /// otherwise invoke `op` and store the value in the map.
     ///
-    /// NB: if the receiver is a `DepTrackingMap`, special care is
+    /// N.B., if the receiver is a `DepTrackingMap`, special care is
     /// needed in the `op` to ensure that the correct edges are
     /// added into the dep graph. See the `DepTrackingMap` impl for
     /// more details!
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index eea3b54..e248f6b 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -523,7 +523,7 @@
                         }
                     };
                     let _ = write!(f, "{}", name);
-                    ty::BrNamed(tcx.hir.local_def_id(CRATE_NODE_ID), name)
+                    ty::BrNamed(tcx.hir().local_def_id(CRATE_NODE_ID), name)
                 }
             };
             tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br))
@@ -679,7 +679,7 @@
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "UpvarId({:?};`{}`;{:?})",
                self.var_path.hir_id,
-               ty::tls::with(|tcx| tcx.hir.name(tcx.hir.hir_to_node_id(self.var_path.hir_id))),
+               ty::tls::with(|tcx| tcx.hir().name(tcx.hir().hir_to_node_id(self.var_path.hir_id))),
                self.closure_expr_id)
     }
 }
@@ -1208,15 +1208,15 @@
                         write!(f, "[static generator")?;
                     }
 
-                    if let Some(node_id) = tcx.hir.as_local_node_id(did) {
-                        write!(f, "@{:?}", tcx.hir.span(node_id))?;
+                    if let Some(node_id) = tcx.hir().as_local_node_id(did) {
+                        write!(f, "@{:?}", tcx.hir().span(node_id))?;
                         let mut sep = " ";
                         tcx.with_freevars(node_id, |freevars| {
                             for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) {
                                 print!(f, cx,
                                        write("{}{}:",
                                              sep,
-                                             tcx.hir.name(freevar.var_id())),
+                                             tcx.hir().name(freevar.var_id())),
                                        print(upvar_ty))?;
                                 sep = ", ";
                             }
@@ -1244,11 +1244,11 @@
                     let upvar_tys = substs.upvar_tys(did, tcx);
                     write!(f, "[closure")?;
 
-                    if let Some(node_id) = tcx.hir.as_local_node_id(did) {
+                    if let Some(node_id) = tcx.hir().as_local_node_id(did) {
                         if tcx.sess.opts.debugging_opts.span_free_formats {
                             write!(f, "@{:?}", node_id)?;
                         } else {
-                            write!(f, "@{:?}", tcx.hir.span(node_id))?;
+                            write!(f, "@{:?}", tcx.hir().span(node_id))?;
                         }
                         let mut sep = " ";
                         tcx.with_freevars(node_id, |freevars| {
@@ -1256,7 +1256,7 @@
                                 print!(f, cx,
                                        write("{}{}:",
                                              sep,
-                                             tcx.hir.name(freevar.var_id())),
+                                             tcx.hir().name(freevar.var_id())),
                                        print(upvar_ty))?;
                                 sep = ", ";
                             }
diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs
index bea3453..c2bfa62 100644
--- a/src/librustc/util/profiling.rs
+++ b/src/librustc/util/profiling.rs
@@ -11,7 +11,7 @@
 use session::config::Options;
 
 use std::fs;
-use std::io::{self, StdoutLock, Write};
+use std::io::{self, StderrLock, Write};
 use std::time::{Duration, Instant};
 
 macro_rules! define_categories {
@@ -61,12 +61,16 @@
                 }
             }
 
-            fn print(&self, lock: &mut StdoutLock<'_>) {
-                writeln!(lock, "| Phase            | Time (ms)      | Queries        | Hits (%) |")
+            fn print(&self, lock: &mut StderrLock<'_>) {
+                writeln!(lock, "| Phase            | Time (ms)      \
+                                | Time (%) | Queries        | Hits (%)")
                     .unwrap();
-                writeln!(lock, "| ---------------- | -------------- | -------------- | -------- |")
+                writeln!(lock, "| ---------------- | -------------- \
+                                | -------- | -------------- | --------")
                     .unwrap();
 
+                let total_time = ($(self.times.$name + )* 0) as f32;
+
                 $(
                     let (hits, total) = self.query_counts.$name;
                     let (hits, total) = if total > 0 {
@@ -78,11 +82,12 @@
 
                     writeln!(
                         lock,
-                        "| {0: <16} | {1: <14} | {2: <14} | {3: <8} |",
+                        "| {0: <16} | {1: <14} | {2: <8.2} | {3: <14} | {4: <8}",
                         stringify!($name),
                         self.times.$name / 1_000_000,
+                        ((self.times.$name as f32) / total_time) * 100.0,
                         total,
-                        hits
+                        hits,
                     ).unwrap();
                 )*
             }
@@ -235,7 +240,7 @@
             self.timer_stack.is_empty(),
             "there were timers running when print_results() was called");
 
-        let out = io::stdout();
+        let out = io::stderr();
         let mut lock = out.lock();
 
         let crate_name =
diff --git a/src/librustc_allocator/Cargo.toml b/src/librustc_allocator/Cargo.toml
index cd3ef6a..03d33f4 100644
--- a/src/librustc_allocator/Cargo.toml
+++ b/src/librustc_allocator/Cargo.toml
@@ -16,4 +16,4 @@
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 log = "0.4"
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/librustc_apfloat/Cargo.toml b/src/librustc_apfloat/Cargo.toml
index a8a5da9..248f2d7 100644
--- a/src/librustc_apfloat/Cargo.toml
+++ b/src/librustc_apfloat/Cargo.toml
@@ -10,4 +10,4 @@
 [dependencies]
 bitflags = "1.0"
 rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/librustc_apfloat/ieee.rs b/src/librustc_apfloat/ieee.rs
index adcb985..60ddac1 100644
--- a/src/librustc_apfloat/ieee.rs
+++ b/src/librustc_apfloat/ieee.rs
@@ -571,7 +571,7 @@
             }
             // Fill with zeros up to precision.
             if !truncate_zero && precision > digits - 1 {
-                for _ in 0..precision - digits + 1 {
+                for _ in 0..=precision - digits {
                     f.write_char('0')?;
                 }
             }
@@ -926,7 +926,7 @@
 
         // In case MSB resides at the left-hand side of radix point, shift the
         // mantissa right by some amount to make sure the MSB reside right before
-        // the radix point (i.e. "MSB . rest-significant-bits").
+        // the radix point (i.e., "MSB . rest-significant-bits").
         if omsb > S::PRECISION {
             let bits = omsb - S::PRECISION;
             loss = sig::shift_right(&mut wide_sig, &mut self.exp, bits).combine(loss);
@@ -1969,7 +1969,7 @@
         // in a Limb. When this would overflow do we do a single
         // bignum multiplication, and then revert again to multiplication
         // in a Limb.
-        let mut chars = s[first_sig_digit..last_sig_digit + 1].chars();
+        let mut chars = s[first_sig_digit..=last_sig_digit].chars();
         loop {
             let mut val = 0;
             let mut multiplier = 1;
@@ -2674,7 +2674,7 @@
 
         // In case MSB resides at the left-hand side of radix point, shift the
         // mantissa right by some amount to make sure the MSB reside right before
-        // the radix point (i.e. "MSB . rest-significant-bits").
+        // the radix point (i.e., "MSB . rest-significant-bits").
         //
         // Note that the result is not normalized when "omsb < precision". So, the
         // caller needs to call IeeeFloat::normalize() if normalized value is
diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs
index 69c9f38..c901917 100644
--- a/src/librustc_apfloat/lib.rs
+++ b/src/librustc_apfloat/lib.rs
@@ -26,8 +26,8 @@
 //! Comments have been preserved where possible, only slightly adapted.
 //!
 //! Instead of keeping a pointer to a configuration struct and inspecting it
-//! dynamically on every operation, types (e.g. `ieee::Double`), traits
-//! (e.g. `ieee::Semantics`) and associated constants are employed for
+//! dynamically on every operation, types (e.g., `ieee::Double`), traits
+//! (e.g., `ieee::Semantics`) and associated constants are employed for
 //! increased type safety and performance.
 //!
 //! On-heap bigints are replaced everywhere (except in decimal conversion),
@@ -179,7 +179,7 @@
 /// implemented operations. Currently implemented operations are add, subtract,
 /// multiply, divide, fused-multiply-add, conversion-to-float,
 /// conversion-to-integer and conversion-from-integer. New rounding modes
-/// (e.g. away from zero) can be added with three or four lines of code.
+/// (e.g., away from zero) can be added with three or four lines of code.
 ///
 /// Four formats are built-in: IEEE single precision, double precision,
 /// quadruple precision, and x87 80-bit extended double (when operating with
@@ -589,7 +589,7 @@
 pub trait FloatConvert<T: Float>: Float {
     /// Convert a value of one floating point type to another.
     /// The return value corresponds to the IEEE754 exceptions. *loses_info
-    /// records whether the transformation lost information, i.e. whether
+    /// records whether the transformation lost information, i.e., whether
     /// converting the result back to the original type will produce the
     /// original value (this is almost the same as return value==Status::OK,
     /// but there are edge cases where this is not so).
diff --git a/src/librustc_apfloat/ppc.rs b/src/librustc_apfloat/ppc.rs
index e662088..aaf6b29 100644
--- a/src/librustc_apfloat/ppc.rs
+++ b/src/librustc_apfloat/ppc.rs
@@ -288,7 +288,7 @@
         //   \   /
         //   Normal
         //
-        // e.g. NaN * NaN = NaN
+        // e.g., NaN * NaN = NaN
         //      Zero * Inf = NaN
         //      Normal * Zero = Zero
         //      Normal * Inf = Inf
diff --git a/src/librustc_asan/Cargo.toml b/src/librustc_asan/Cargo.toml
index 734564c..836caf2 100644
--- a/src/librustc_asan/Cargo.toml
+++ b/src/librustc_asan/Cargo.toml
@@ -16,4 +16,4 @@
 [dependencies]
 alloc = { path = "../liballoc" }
 core = { path = "../libcore" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
+compiler_builtins = "0.1.0"
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index e47e95a..51afb43 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -105,7 +105,7 @@
         debug!("consume(consume_id={}, cmt={:?}, mode={:?})",
                consume_id, cmt, mode);
 
-        let hir_id = self.tcx().hir.node_to_hir_id(consume_id);
+        let hir_id = self.tcx().hir().node_to_hir_id(consume_id);
         self.consume_common(hir_id.local_id, consume_span, cmt, mode);
     }
 
@@ -139,7 +139,7 @@
                borrow_id, cmt, loan_region,
                bk, loan_cause);
 
-        let hir_id = self.tcx().hir.node_to_hir_id(borrow_id);
+        let hir_id = self.tcx().hir().node_to_hir_id(borrow_id);
         if let Some(lp) = opt_loan_path(cmt) {
             let moved_value_use_kind = match loan_cause {
                 euv::ClosureCapture(_) => MovedInCapture,
@@ -185,7 +185,7 @@
                 }
             }
         }
-        self.check_assignment(self.tcx().hir.node_to_hir_id(assignment_id).local_id,
+        self.check_assignment(self.tcx().hir().node_to_hir_id(assignment_id).local_id,
                               assignment_span, assignee_cmt);
     }
 
@@ -199,10 +199,10 @@
                                      body: &hir::Body) {
     debug!("check_loans(body id={})", body.value.id);
 
-    let def_id = bccx.tcx.hir.body_owner_def_id(body.id());
+    let def_id = bccx.tcx.hir().body_owner_def_id(body.id());
 
-    let node_id = bccx.tcx.hir.as_local_node_id(def_id).unwrap();
-    let movable_generator = !match bccx.tcx.hir.get(node_id) {
+    let node_id = bccx.tcx.hir().as_local_node_id(def_id).unwrap();
+    let movable_generator = !match bccx.tcx.hir().get(node_id) {
         Node::Expr(&hir::Expr {
             node: hir::ExprKind::Closure(.., Some(hir::GeneratorMovability::Static)),
             ..
@@ -907,7 +907,7 @@
             let lp = opt_loan_path(assignee_cmt).unwrap();
             self.move_data.each_assignment_of(assignment_id, &lp, |assign| {
                 if assignee_cmt.mutbl.is_mutable() {
-                    let hir_id = self.bccx.tcx.hir.node_to_hir_id(local_id);
+                    let hir_id = self.bccx.tcx.hir().node_to_hir_id(local_id);
                     self.bccx.used_mut_nodes.borrow_mut().insert(hir_id);
                 } else {
                     self.bccx.report_reassigned_immutable_variable(
diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
index 7bb5f41..9fa541c 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
@@ -57,9 +57,9 @@
 /// with a reference to the let
 fn get_pattern_source<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &Pat) -> PatternSource<'tcx> {
 
-    let parent = tcx.hir.get_parent_node(pat.id);
+    let parent = tcx.hir().get_parent_node(pat.id);
 
-    match tcx.hir.get(parent) {
+    match tcx.hir().get(parent) {
         Node::Expr(ref e) => {
             // the enclosing expression must be a `match` or something else
             assert!(match e.node {
@@ -79,7 +79,7 @@
                              var_id: ast::NodeId,
                              var_ty: Ty<'tcx>) {
     let loan_path = Rc::new(LoanPath::new(LpVar(var_id), var_ty));
-    let hir_id = bccx.tcx.hir.node_to_hir_id(var_id);
+    let hir_id = bccx.tcx.hir().node_to_hir_id(var_id);
     move_data.add_move(bccx.tcx, loan_path, hir_id.local_id, Declared);
 }
 
diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
index 6ef5d65..ccc091a 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
@@ -114,7 +114,7 @@
                 self.bccx.tcx.mk_region(ty::ReScope(self.item_scope))
             }
             Categorization::Local(local_id) => {
-                let hir_id = self.bccx.tcx.hir.node_to_hir_id(local_id);
+                let hir_id = self.bccx.tcx.hir().node_to_hir_id(local_id);
                 self.bccx.tcx.mk_region(ty::ReScope(
                     self.bccx.region_scope_tree.var_scope(hir_id.local_id)))
             }
diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
index 21fb0cd..7ed4d49 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
@@ -38,13 +38,13 @@
 pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                     body: hir::BodyId)
                                     -> (Vec<Loan<'tcx>>, move_data::MoveData<'tcx>) {
-    let def_id = bccx.tcx.hir.body_owner_def_id(body);
+    let def_id = bccx.tcx.hir().body_owner_def_id(body);
     let param_env = bccx.tcx.param_env(def_id);
     let mut glcx = GatherLoanCtxt {
         bccx,
         all_loans: Vec::new(),
         item_ub: region::Scope {
-            id: bccx.tcx.hir.body(body).value.hir_id.local_id,
+            id: bccx.tcx.hir().body(body).value.hir_id.local_id,
             data: region::ScopeData::Node
         },
         move_data: MoveData::default(),
@@ -88,7 +88,7 @@
             euv::Move(move_reason) => {
                 gather_moves::gather_move_from_expr(
                     self.bccx, &self.move_data, &mut self.move_error_collector,
-                    self.bccx.tcx.hir.node_to_hir_id(consume_id).local_id, cmt, move_reason);
+                    self.bccx.tcx.hir().node_to_hir_id(consume_id).local_id, cmt, move_reason);
             }
             euv::Copy => { }
         }
@@ -135,7 +135,7 @@
                bk={:?}, loan_cause={:?})",
                borrow_id, cmt, loan_region,
                bk, loan_cause);
-        let hir_id = self.bccx.tcx.hir.node_to_hir_id(borrow_id);
+        let hir_id = self.bccx.tcx.hir().node_to_hir_id(borrow_id);
         self.guarantee_valid(hir_id.local_id,
                              borrow_span,
                              cmt,
@@ -158,7 +158,7 @@
     fn decl_without_init(&mut self, id: ast::NodeId, _span: Span) {
         let ty = self.bccx
                      .tables
-                     .node_id_to_type(self.bccx.tcx.hir.node_to_hir_id(id));
+                     .node_id_to_type(self.bccx.tcx.hir().node_to_hir_id(id));
         gather_moves::gather_decl(self.bccx, &self.move_data, id, ty);
     }
 }
@@ -280,13 +280,13 @@
                     self.mark_loan_path_as_mutated(&lp);
                 }
                 gather_moves::gather_assignment(self.bccx, &self.move_data,
-                                                self.bccx.tcx.hir.node_to_hir_id(assignment_id)
+                                                self.bccx.tcx.hir().node_to_hir_id(assignment_id)
                                                     .local_id,
                                                 assignment_span,
                                                 lp);
             }
             None => {
-                // This can occur with e.g. `*foo() = 5`.  In such
+                // This can occur with e.g., `*foo() = 5`.  In such
                 // cases, there is no need to check for conflicts
                 // with moves etc, just ignore.
             }
@@ -448,7 +448,7 @@
             wrapped_path = match current_path.kind {
                 LpVar(local_id) => {
                     if !through_borrow {
-                        let hir_id = self.bccx.tcx.hir.node_to_hir_id(local_id);
+                        let hir_id = self.bccx.tcx.hir().node_to_hir_id(local_id);
                         self.bccx.used_mut_nodes.borrow_mut().insert(hir_id);
                     }
                     None
diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
index cfd530b..08c5b24 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
@@ -97,8 +97,8 @@
             }
         }
         if let NoteClosureEnv(upvar_id) = error.move_from.note {
-            let var_node_id = bccx.tcx.hir.hir_to_node_id(upvar_id.var_path.hir_id);
-            err.span_label(bccx.tcx.hir.span(var_node_id),
+            let var_node_id = bccx.tcx.hir().hir_to_node_id(upvar_id.var_path.hir_id);
+            err.span_label(bccx.tcx.hir().span(var_node_id),
                            "captured outer variable");
         }
         err.emit();
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index d189460..cb1200f 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -93,9 +93,9 @@
 
     debug!("borrowck(body_owner_def_id={:?})", owner_def_id);
 
-    let owner_id = tcx.hir.as_local_node_id(owner_def_id).unwrap();
+    let owner_id = tcx.hir().as_local_node_id(owner_def_id).unwrap();
 
-    match tcx.hir.get(owner_id) {
+    match tcx.hir().get(owner_id) {
         Node::StructCtor(_) |
         Node::Variant(_) => {
             // We get invoked with anything that has MIR, but some of
@@ -110,10 +110,10 @@
         _ => { }
     }
 
-    let body_id = tcx.hir.body_owned_by(owner_id);
+    let body_id = tcx.hir().body_owned_by(owner_id);
     let tables = tcx.typeck_tables_of(owner_def_id);
     let region_scope_tree = tcx.region_scope_tree(owner_def_id);
-    let body = tcx.hir.body(body_id);
+    let body = tcx.hir().body(body_id);
     let mut bccx = BorrowckCtxt {
         tcx,
         tables,
@@ -169,7 +169,7 @@
     // Check the body of fn items.
     let tcx = this.tcx;
     let id_range = {
-        let mut visitor = intravisit::IdRangeComputingVisitor::new(&tcx.hir);
+        let mut visitor = intravisit::IdRangeComputingVisitor::new(&tcx.hir());
         visitor.visit_body(this.body);
         visitor.result()
     };
@@ -217,18 +217,18 @@
 }
 
 /// Accessor for introspective clients inspecting `AnalysisData` and
-/// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
+/// the `BorrowckCtxt` itself , e.g., the flowgraph visualizer.
 pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     body_id: hir::BodyId,
     cfg: &cfg::CFG)
     -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>)
 {
-    let owner_id = tcx.hir.body_owner(body_id);
-    let owner_def_id = tcx.hir.local_def_id(owner_id);
+    let owner_id = tcx.hir().body_owner(body_id);
+    let owner_def_id = tcx.hir().local_def_id(owner_id);
     let tables = tcx.typeck_tables_of(owner_def_id);
     let region_scope_tree = tcx.region_scope_tree(owner_def_id);
-    let body = tcx.hir.body(body_id);
+    let body = tcx.hir().body(body_id);
     let mut bccx = BorrowckCtxt {
         tcx,
         tables,
@@ -418,8 +418,8 @@
 
 fn closure_to_block(closure_id: LocalDefId,
                     tcx: TyCtxt) -> ast::NodeId {
-    let closure_id = tcx.hir.local_def_id_to_node_id(closure_id);
-    match tcx.hir.get(closure_id) {
+    let closure_id = tcx.hir().local_def_id_to_node_id(closure_id);
+    match tcx.hir().get(closure_id) {
         Node::Expr(expr) => match expr.node {
             hir::ExprKind::Closure(.., body_id, _, _) => {
                 body_id.node_id
@@ -436,12 +436,12 @@
     pub fn kill_scope(&self, bccx: &BorrowckCtxt<'a, 'tcx>) -> region::Scope {
         match self.kind {
             LpVar(local_id) => {
-                let hir_id = bccx.tcx.hir.node_to_hir_id(local_id);
+                let hir_id = bccx.tcx.hir().node_to_hir_id(local_id);
                 bccx.region_scope_tree.var_scope(hir_id.local_id)
             }
             LpUpvar(upvar_id) => {
                 let block_id = closure_to_block(upvar_id.closure_expr_id, bccx.tcx);
-                let hir_id = bccx.tcx.hir.node_to_hir_id(block_id);
+                let hir_id = bccx.tcx.hir().node_to_hir_id(block_id);
                 region::Scope { id: hir_id.local_id, data: region::ScopeData::Node }
             }
             LpDowncast(ref base, _) |
@@ -700,8 +700,8 @@
                                                              Origin::Ast);
                 let need_note = match lp.ty.sty {
                     ty::Closure(id, _) => {
-                        let node_id = self.tcx.hir.as_local_node_id(id).unwrap();
-                        let hir_id = self.tcx.hir.node_to_hir_id(node_id);
+                        let node_id = self.tcx.hir().as_local_node_id(id).unwrap();
+                        let hir_id = self.tcx.hir().node_to_hir_id(node_id);
                         if let Some((span, name)) = self.tables.closure_kind_origins().get(hir_id) {
                             err.span_note(*span, &format!(
                                 "closure cannot be invoked more than once because \
@@ -721,7 +721,7 @@
 
         // Get type of value and span where it was previously
         // moved.
-        let node_id = self.tcx.hir.hir_to_node_id(hir::HirId {
+        let node_id = self.tcx.hir().hir_to_node_id(hir::HirId {
             owner: self.body.value.hir_id.owner,
             local_id: the_move.id
         });
@@ -731,10 +731,10 @@
             }
 
             move_data::MoveExpr |
-            move_data::MovePat => (self.tcx.hir.span(node_id), ""),
+            move_data::MovePat => (self.tcx.hir().span(node_id), ""),
 
             move_data::Captured =>
-                (match self.tcx.hir.expect_expr(node_id).node {
+                (match self.tcx.hir().expect_expr(node_id).node {
                     hir::ExprKind::Closure(.., fn_decl_span, _) => fn_decl_span,
                     ref r => bug!("Captured({:?}) maps to non-closure: {:?}",
                                   the_move.id, r),
@@ -846,8 +846,8 @@
                     MutabilityViolation => {
                         let mut db = self.cannot_assign(error_span, &descr, Origin::Ast);
                         if let mc::NoteClosureEnv(upvar_id) = err.cmt.note {
-                            let node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_path.hir_id);
-                            let sp = self.tcx.hir.span(node_id);
+                            let node_id = self.tcx.hir().hir_to_node_id(upvar_id.var_path.hir_id);
+                            let sp = self.tcx.hir().span(node_id);
                             let fn_closure_msg = "`Fn` closures cannot capture their enclosing \
                                                   environment for modifications";
                             match (self.tcx.sess.source_map().span_to_snippet(sp), &err.cmt.cat) {
@@ -916,8 +916,8 @@
                 // to implement two traits for "one operator" is not very intuitive for
                 // many programmers.
                 if err.cmt.note == mc::NoteIndex {
-                    let node_id = self.tcx.hir.hir_to_node_id(err.cmt.hir_id);
-                    let node =  self.tcx.hir.get(node_id);
+                    let node_id = self.tcx.hir().hir_to_node_id(err.cmt.hir_id);
+                    let node =  self.tcx.hir().get(node_id);
 
                     // This pattern probably always matches.
                     if let Node::Expr(
@@ -937,7 +937,7 @@
                 self.note_immutability_blame(
                     &mut db,
                     err.cmt.immutability_blame(),
-                    self.tcx.hir.hir_to_node_id(err.cmt.hir_id)
+                    self.tcx.hir().hir_to_node_id(err.cmt.hir_id)
                 );
                 db.emit();
                 self.signal_error();
@@ -1043,7 +1043,7 @@
 
                 if let ty::ReScope(scope) = *super_scope {
                     let node_id = scope.node_id(self.tcx, &self.region_scope_tree);
-                    match self.tcx.hir.find(node_id) {
+                    match self.tcx.hir().find(node_id) {
                         Some(Node::Stmt(_)) => {
                             if *sub_scope != ty::ReStatic {
                                 db.note("consider using a `let` binding to increase its lifetime");
@@ -1138,8 +1138,8 @@
                 } else {
                     "consider changing this closure to take self by mutable reference"
                 };
-                let node_id = self.tcx.hir.local_def_id_to_node_id(id);
-                let help_span = self.tcx.hir.span(node_id);
+                let node_id = self.tcx.hir().local_def_id_to_node_id(id);
+                let help_span = self.tcx.hir().span(node_id);
                 self.cannot_act_on_capture_in_sharable_fn(span,
                                                           prefix,
                                                           (help_span, help_msg),
@@ -1153,7 +1153,7 @@
         self.note_immutability_blame(
             &mut err,
             blame,
-            self.tcx.hir.hir_to_node_id(cmt.hir_id)
+            self.tcx.hir().hir_to_node_id(cmt.hir_id)
         );
 
         if is_closure {
@@ -1194,7 +1194,7 @@
     }
 
     fn local_binding_mode(&self, node_id: ast::NodeId) -> ty::BindingMode {
-        let pat = match self.tcx.hir.get(node_id) {
+        let pat = match self.tcx.hir().get(node_id) {
             Node::Binding(pat) => pat,
             node => bug!("bad node for local: {:?}", node)
         };
@@ -1211,13 +1211,13 @@
     }
 
     fn local_ty(&self, node_id: ast::NodeId) -> (Option<&hir::Ty>, bool) {
-        let parent = self.tcx.hir.get_parent_node(node_id);
-        let parent_node = self.tcx.hir.get(parent);
+        let parent = self.tcx.hir().get_parent_node(node_id);
+        let parent_node = self.tcx.hir().get(parent);
 
         // The parent node is like a fn
         if let Some(fn_like) = FnLikeNode::from_node(parent_node) {
             // `nid`'s parent's `Body`
-            let fn_body = self.tcx.hir.body(fn_like.body());
+            let fn_body = self.tcx.hir().body(fn_like.body());
             // Get the position of `node_id` in the arguments list
             let arg_pos = fn_body.arguments.iter().position(|arg| arg.pat.id == node_id);
             if let Some(i) = arg_pos {
@@ -1245,7 +1245,7 @@
             Some(ImmutabilityBlame::LocalDeref(node_id)) => {
                 match self.local_binding_mode(node_id) {
                     ty::BindByReference(..) => {
-                        let let_span = self.tcx.hir.span(node_id);
+                        let let_span = self.tcx.hir().span(node_id);
                         let suggestion = suggest_ref_mut(self.tcx, let_span);
                         if let Some(replace_str) = suggestion {
                             db.span_suggestion_with_applicability(
@@ -1272,12 +1272,12 @@
                 }
             }
             Some(ImmutabilityBlame::AdtFieldDeref(_, field)) => {
-                let node_id = match self.tcx.hir.as_local_node_id(field.did) {
+                let node_id = match self.tcx.hir().as_local_node_id(field.did) {
                     Some(node_id) => node_id,
                     None => return
                 };
 
-                if let Node::Field(ref field) = self.tcx.hir.get(node_id) {
+                if let Node::Field(ref field) = self.tcx.hir().get(node_id) {
                     if let Some(msg) = self.suggest_mut_for_immutable(&field.ty, false) {
                         db.span_label(field.ty.span, msg);
                     }
@@ -1293,7 +1293,7 @@
                             db: &mut DiagnosticBuilder,
                             borrowed_node_id: ast::NodeId,
                             binding_node_id: ast::NodeId) {
-        let let_span = self.tcx.hir.span(binding_node_id);
+        let let_span = self.tcx.hir().span(binding_node_id);
         if let ty::BindByValue(..) = self.local_binding_mode(binding_node_id) {
             if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(let_span) {
                 let (ty, is_implicit_self) = self.local_ty(binding_node_id);
@@ -1309,9 +1309,9 @@
                     },
                 )) = ty.map(|t| &t.node)
                 {
-                    let borrow_expr_id = self.tcx.hir.get_parent_node(borrowed_node_id);
+                    let borrow_expr_id = self.tcx.hir().get_parent_node(borrowed_node_id);
                     db.span_suggestion_with_applicability(
-                        self.tcx.hir.span(borrow_expr_id),
+                        self.tcx.hir().span(borrow_expr_id),
                         "consider removing the `&mut`, as it is an \
                         immutable binding to a mutable reference",
                         snippet,
@@ -1381,8 +1381,8 @@
                 };
                 if *kind == ty::ClosureKind::Fn {
                     let closure_node_id =
-                        self.tcx.hir.local_def_id_to_node_id(upvar_id.closure_expr_id);
-                    db.span_help(self.tcx.hir.span(closure_node_id),
+                        self.tcx.hir().local_def_id_to_node_id(upvar_id.closure_expr_id);
+                    db.span_help(self.tcx.hir().span(closure_node_id),
                                  "consider changing this closure to take \
                                   self by mutable reference");
                 }
@@ -1391,7 +1391,7 @@
                 if let Categorization::Deref(..) = err.cmt.cat {
                     db.span_label(*error_span, "cannot borrow as mutable");
                 } else if let Categorization::Local(local_id) = err.cmt.cat {
-                    let span = self.tcx.hir.span(local_id);
+                    let span = self.tcx.hir().span(local_id);
                     if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
                         if snippet.starts_with("ref mut ") || snippet.starts_with("&mut ") {
                             db.span_label(*error_span, "cannot reborrow mutably");
@@ -1416,10 +1416,10 @@
                                       out: &mut String) {
         match loan_path.kind {
             LpUpvar(ty::UpvarId { var_path: ty::UpvarPath { hir_id: id}, closure_expr_id: _ }) => {
-                out.push_str(&self.tcx.hir.name(self.tcx.hir.hir_to_node_id(id)).as_str());
+                out.push_str(&self.tcx.hir().name(self.tcx.hir().hir_to_node_id(id)).as_str());
             }
             LpVar(id) => {
-                out.push_str(&self.tcx.hir.name(id).as_str());
+                out.push_str(&self.tcx.hir().name(id).as_str());
             }
 
             LpDowncast(ref lp_base, variant_def_id) => {
@@ -1530,13 +1530,13 @@
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self.kind {
             LpVar(id) => {
-                write!(f, "$({})", ty::tls::with(|tcx| tcx.hir.node_to_string(id)))
+                write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().node_to_string(id)))
             }
 
             LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath {hir_id: var_id}, closure_expr_id }) => {
                 let s = ty::tls::with(|tcx| {
-                    let var_node_id = tcx.hir.hir_to_node_id(var_id);
-                    tcx.hir.node_to_string(var_node_id)
+                    let var_node_id = tcx.hir().hir_to_node_id(var_id);
+                    tcx.hir().node_to_string(var_node_id)
                 });
                 write!(f, "$({} captured by id={:?})", s, closure_expr_id)
             }
@@ -1565,13 +1565,13 @@
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self.kind {
             LpVar(id) => {
-                write!(f, "$({})", ty::tls::with(|tcx| tcx.hir.node_to_user_string(id)))
+                write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().node_to_user_string(id)))
             }
 
             LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath { hir_id }, closure_expr_id: _ }) => {
                 let s = ty::tls::with(|tcx| {
-                    let var_node_id = tcx.hir.hir_to_node_id(hir_id);
-                    tcx.hir.node_to_string(var_node_id)
+                    let var_node_id = tcx.hir().hir_to_node_id(hir_id);
+                    tcx.hir().node_to_string(var_node_id)
                 });
                 write!(f, "$({} captured by closure)", s)
             }
diff --git a/src/librustc_borrowck/borrowck/unused.rs b/src/librustc_borrowck/borrowck/unused.rs
index 85794c5..a9a33f3 100644
--- a/src/librustc_borrowck/borrowck/unused.rs
+++ b/src/librustc_borrowck/borrowck/unused.rs
@@ -100,7 +100,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for UnusedMutCx<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.bccx.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.bccx.tcx.hir())
     }
 
     fn visit_arm(&mut self, arm: &hir::Arm) {
@@ -114,12 +114,12 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for UsedMutFinder<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.bccx.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.bccx.tcx.hir())
     }
 
     fn visit_nested_body(&mut self, id: hir::BodyId) {
-        let def_id = self.bccx.tcx.hir.body_owner_def_id(id);
+        let def_id = self.bccx.tcx.hir().body_owner_def_id(id);
         self.set.extend(self.bccx.tcx.borrowck(def_id).used_mut_nodes.iter().cloned());
-        self.visit_body(self.bccx.tcx.hir.body(id));
+        self.visit_body(self.bccx.tcx.hir().body(id));
     }
 }
diff --git a/src/librustc_borrowck/dataflow.rs b/src/librustc_borrowck/dataflow.rs
index 1760fb1..d12c221 100644
--- a/src/librustc_borrowck/dataflow.rs
+++ b/src/librustc_borrowck/dataflow.rs
@@ -71,7 +71,7 @@
     scope_kills: Vec<usize>,
 
     /// bits killed as we exit the cfg node directly; if it is jumped
-    /// over, e.g. via `break`, the kills are not reflected in the
+    /// over, e.g., via `break`, the kills are not reflected in the
     /// jump's effects. Updated by `add_kill(KillFrom::Execution)`.
     action_kills: Vec<usize>,
 
@@ -111,7 +111,7 @@
 
 impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O> {
     fn nested(&self, state: &mut pprust::State, nested: pprust::Nested) -> io::Result<()> {
-        pprust::PpAnn::nested(&self.tcx.hir, state, nested)
+        pprust::PpAnn::nested(self.tcx.hir(), state, nested)
     }
     fn pre(&self,
            ps: &mut pprust::State,
@@ -172,7 +172,7 @@
     let mut index = FxHashMap::default();
 
     // FIXME(#15020) Would it be better to fold formals from decl
-    // into cfg itself?  i.e. introduce a fn-based flow-graph in
+    // into cfg itself?  i.e., introduce a fn-based flow-graph in
     // addition to the current block-based flow-graph, rather than
     // have to put traversals like this here?
     if let Some(body) = body {
@@ -430,7 +430,7 @@
                 for offset in 0..usize_bits {
                     let bit = 1 << offset;
                     if (word & bit) != 0 {
-                        // NB: we round up the total number of bits
+                        // N.B., we round up the total number of bits
                         // that we store in any given bit set so that
                         // it is an even multiple of usize::BITS.  This
                         // means that there may be some stray bits at
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index 5b6d157..b8954de 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -185,7 +185,7 @@
 
 impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
     /// Get the LLVM type for a place of the original Rust type of
-    /// this argument/return, i.e. the result of `type_of::type_of`.
+    /// this argument/return, i.e., the result of `type_of::type_of`.
     fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
         self.layout.llvm_type(cx)
     }
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index 38ab130..48e0a3a 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/src/librustc_codegen_llvm/attributes.rs
@@ -15,14 +15,16 @@
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::session::Session;
 use rustc::session::config::Sanitizer;
-use rustc::ty::TyCtxt;
+use rustc::ty::{self, TyCtxt, PolyFnSig};
 use rustc::ty::layout::HasTyCtxt;
 use rustc::ty::query::Providers;
+use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::PanicStrategy;
 use rustc_codegen_ssa::traits::*;
 
+use abi::Abi;
 use attributes;
 use llvm::{self, Attribute};
 use llvm::AttributePlace::Function;
@@ -60,7 +62,7 @@
 
 /// Tell LLVM whether the function can or cannot unwind.
 #[inline]
-pub fn unwind(val: &'ll Value, can_unwind: bool) {
+fn unwind(val: &'ll Value, can_unwind: bool) {
     Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind);
 }
 
@@ -71,7 +73,7 @@
     Attribute::OptimizeForSize.toggle_llfn(Function, val, optimize);
 }
 
-/// Tell LLVM if this function should be 'naked', i.e. skip the epilogue and prologue.
+/// Tell LLVM if this function should be 'naked', i.e., skip the epilogue and prologue.
 #[inline]
 pub fn naked(val: &'ll Value, is_naked: bool) {
     Attribute::Naked.toggle_llfn(Function, val, is_naked);
@@ -129,8 +131,7 @@
 }
 
 pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
-    let cpu = llvm_util::target_cpu(cx.tcx.sess);
-    let target_cpu = CString::new(cpu).unwrap();
+    let target_cpu = SmallCStr::new(llvm_util::target_cpu(cx.tcx.sess));
     llvm::AddFunctionAttrStringValue(
             llfn,
             llvm::AttributePlace::Function,
@@ -147,12 +148,13 @@
     }
 }
 
-/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
+/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
 /// attributes.
 pub fn from_fn_attrs(
-    cx: &CodegenCx<'ll, '_>,
+    cx: &CodegenCx<'ll, 'tcx>,
     llfn: &'ll Value,
     id: Option<DefId>,
+    sig: PolyFnSig<'tcx>,
 ) {
     let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id))
         .unwrap_or_else(|| CodegenFnAttrs::new());
@@ -194,37 +196,42 @@
             llvm::AttributePlace::ReturnValue, llfn);
     }
 
-    let can_unwind = if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) {
-        Some(true)
+    unwind(llfn, if cx.tcx.sess.panic_strategy() != PanicStrategy::Unwind {
+        // In panic=abort mode we assume nothing can unwind anywhere, so
+        // optimize based on this!
+        false
+    } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) {
+        // If a specific #[unwind] attribute is present, use that
+        true
     } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
-        Some(false)
-
-    // Perhaps questionable, but we assume that anything defined
-    // *in Rust code* may unwind. Foreign items like `extern "C" {
-    // fn foo(); }` are assumed not to unwind **unless** they have
-    // a `#[unwind]` attribute.
-    } else if id.map(|id| !cx.tcx.is_foreign_item(id)).unwrap_or(false) {
-        Some(true)
-    } else {
-        None
-    };
-
-    match can_unwind {
-        Some(false) => attributes::unwind(llfn, false),
-        Some(true) if cx.tcx.sess.panic_strategy() == PanicStrategy::Unwind => {
-            attributes::unwind(llfn, true);
+        // Special attribute for allocator functions, which can't unwind
+        false
+    } else if let Some(id) = id {
+        let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
+        if cx.tcx.is_foreign_item(id) {
+            // Foreign items like `extern "C" { fn foo(); }` are assumed not to
+            // unwind
+            false
+        } else if sig.abi != Abi::Rust && sig.abi != Abi::RustCall {
+            // Any items defined in Rust that *don't* have the `extern` ABI are
+            // defined to not unwind. We insert shims to abort if an unwind
+            // happens to enforce this.
+            false
+        } else {
+            // Anything else defined in Rust is assumed that it can possibly
+            // unwind
+            true
         }
-        Some(true) | None => {}
-    }
+    } else {
+        // assume this can possibly unwind, avoiding the application of a
+        // `nounwind` attribute below.
+        true
+    });
 
     // Always annotate functions with the target-cpu they are compiled for.
     // Without this, ThinLTO won't inline Rust functions into Clang generated
     // functions (because Clang annotates functions this way too).
-    // NOTE: For now we just apply this if -Zcross-lang-lto is specified, since
-    //       it introduce a little overhead and isn't really necessary otherwise.
-    if cx.tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() {
-        apply_target_cpu_attr(cx, llfn);
-    }
+    apply_target_cpu_attr(cx, llfn);
 
     let features = llvm_target_features(cx.tcx.sess)
         .map(|s| s.to_string())
diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs
index 68da145..f1c0464 100644
--- a/src/librustc_codegen_llvm/back/link.rs
+++ b/src/librustc_codegen_llvm/back/link.rs
@@ -212,12 +212,7 @@
 }
 
 fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
-    let mut search = Vec::new();
-    sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
-        search.push(path.to_path_buf());
-    });
-
-    search
+    sess.target_filesearch(PathKind::Native).search_path_dirs()
 }
 
 fn archive_config<'a>(sess: &'a Session,
@@ -994,7 +989,7 @@
     //
     // The rationale behind this ordering is that those items lower down in the
     // list can't depend on items higher up in the list. For example nothing can
-    // depend on what we just generated (e.g. that'd be a circular dependency).
+    // depend on what we just generated (e.g., that'd be a circular dependency).
     // Upstream rust libraries are not allowed to depend on our local native
     // libraries as that would violate the structure of the DAG, in that
     // scenario they are required to link to them as well in a shared fashion.
@@ -1003,7 +998,7 @@
     // well, but they also can't depend on what we just started to add to the
     // link line. And finally upstream native libraries can't depend on anything
     // in this DAG so far because they're only dylibs and dylibs can only depend
-    // on other dylibs (e.g. other native deps).
+    // on other dylibs (e.g., other native deps).
     add_local_native_libraries(cmd, sess, codegen_results);
     add_upstream_rust_crates(cmd, sess, codegen_results, crate_type, tmpdir);
     add_upstream_native_libraries(cmd, sess, codegen_results, crate_type);
@@ -1024,11 +1019,10 @@
     // where extern libraries might live, based on the
     // addl_lib_search_paths
     if sess.opts.cg.rpath {
-        let sysroot = sess.sysroot();
         let target_triple = sess.opts.target_triple.triple();
         let mut get_install_prefix_lib_path = || {
             let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
-            let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
+            let tlib = filesearch::relative_target_lib_path(&sess.sysroot, target_triple);
             let mut path = PathBuf::from(install_prefix);
             path.push(&tlib);
 
@@ -1068,12 +1062,13 @@
 fn add_local_native_libraries(cmd: &mut dyn Linker,
                               sess: &Session,
                               codegen_results: &CodegenResults) {
-    sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
-        match k {
-            PathKind::Framework => { cmd.framework_path(path); }
-            _ => { cmd.include_path(&fix_windows_verbatim_for_gcc(path)); }
+    let filesearch = sess.target_filesearch(PathKind::All);
+    for search_path in filesearch.search_paths() {
+        match search_path.kind {
+            PathKind::Framework => { cmd.framework_path(&search_path.dir); }
+            _ => { cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir)); }
         }
-    });
+    }
 
     let relevant_libs = codegen_results.crate_info.used_libraries.iter().filter(|l| {
         relevant_lib(sess, l)
@@ -1205,7 +1200,7 @@
     // compiler-builtins are always placed last to ensure that they're
     // linked correctly.
     // We must always link the `compiler_builtins` crate statically. Even if it
-    // was already "included" in a dylib (e.g. `libstd` when `-C prefer-dynamic`
+    // was already "included" in a dylib (e.g., `libstd` when `-C prefer-dynamic`
     // is used)
     if let Some(cnum) = compiler_builtins {
         add_static_crate(cmd, sess, codegen_results, tmpdir, crate_type, cnum);
@@ -1385,7 +1380,7 @@
             // because a `dylib` can be reused as an intermediate artifact.
             //
             // Note, though, that we don't want to include the whole of a
-            // compiler-builtins crate (e.g. compiler-rt) because it'll get
+            // compiler-builtins crate (e.g., compiler-rt) because it'll get
             // repeatedly linked anyway.
             if crate_type == config::CrateType::Dylib &&
                 codegen_results.crate_info.compiler_builtins != Some(cnum) {
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index 99828e5..bddb45d 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -48,18 +48,11 @@
     }
 }
 
-/// Performs LTO, which in the case of full LTO means merging all modules into
-/// a single one and returning it for further optimizing. For ThinLTO, it will
-/// do the global analysis necessary and return two lists, one of the modules
-/// the need optimization and another for modules that can simply be copied over
-/// from the incr. comp. cache.
-pub(crate) fn run(cgcx: &CodegenContext<LlvmCodegenBackend>,
-                  modules: Vec<ModuleCodegen<ModuleLlvm>>,
-                  cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
-                  timeline: &mut Timeline)
-    -> Result<(Vec<LtoModuleCodegen<LlvmCodegenBackend>>, Vec<WorkProduct>), FatalError>
+fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
+               timeline: &mut Timeline,
+               diag_handler: &Handler)
+    -> Result<(Vec<CString>, Vec<(SerializedModule<ModuleBuffer>, CString)>), FatalError>
 {
-    let diag_handler = cgcx.create_diag_handler();
     let export_threshold = match cgcx.lto {
         // We're just doing LTO for our one crate
         Lto::ThinLocal => SymbolExportLevel::Rust,
@@ -144,36 +137,74 @@
         }
     }
 
+    Ok((symbol_white_list, upstream_modules))
+}
+
+/// Performs fat LTO by merging all modules into a single one and returning it
+/// for further optimization.
+pub(crate) fn run_fat(cgcx: &CodegenContext<LlvmCodegenBackend>,
+                      modules: Vec<ModuleCodegen<ModuleLlvm>>,
+                      timeline: &mut Timeline)
+    -> Result<LtoModuleCodegen<LlvmCodegenBackend>, FatalError>
+{
+    let diag_handler = cgcx.create_diag_handler();
+    let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, timeline, &diag_handler)?;
     let symbol_white_list = symbol_white_list.iter()
                                              .map(|c| c.as_ptr())
                                              .collect::<Vec<_>>();
-    match cgcx.lto {
-        Lto::Fat => {
-            assert!(cached_modules.is_empty());
-            let opt_jobs = fat_lto(cgcx,
-                                   &diag_handler,
-                                   modules,
-                                   upstream_modules,
-                                   &symbol_white_list,
-                                   timeline);
-            opt_jobs.map(|opt_jobs| (opt_jobs, vec![]))
-        }
-        Lto::Thin |
-        Lto::ThinLocal => {
-            if cgcx.opts.debugging_opts.cross_lang_lto.enabled() {
-                unreachable!("We should never reach this case if the LTO step \
-                              is deferred to the linker");
-            }
-            thin_lto(cgcx,
-                     &diag_handler,
-                     modules,
-                     upstream_modules,
-                     cached_modules,
-                     &symbol_white_list,
-                     timeline)
-        }
-        Lto::No => unreachable!(),
+    fat_lto(cgcx, &diag_handler, modules, upstream_modules, &symbol_white_list, timeline)
+}
+
+/// Performs thin LTO by performing necessary global analysis and returning two
+/// lists, one of the modules that need optimization and another for modules that
+/// can simply be copied over from the incr. comp. cache.
+pub(crate) fn run_thin(cgcx: &CodegenContext<LlvmCodegenBackend>,
+                       modules: Vec<(String, ThinBuffer)>,
+                       cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
+                       timeline: &mut Timeline)
+    -> Result<(Vec<LtoModuleCodegen<LlvmCodegenBackend>>, Vec<WorkProduct>), FatalError>
+{
+    let diag_handler = cgcx.create_diag_handler();
+    let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, timeline, &diag_handler)?;
+    let symbol_white_list = symbol_white_list.iter()
+                                             .map(|c| c.as_ptr())
+                                             .collect::<Vec<_>>();
+    if cgcx.opts.debugging_opts.cross_lang_lto.enabled() {
+        unreachable!("We should never reach this case if the LTO step \
+                      is deferred to the linker");
     }
+    thin_lto(cgcx,
+             &diag_handler,
+             modules,
+             upstream_modules,
+             cached_modules,
+             &symbol_white_list,
+             timeline)
+}
+
+pub(crate) fn prepare_thin(
+    cgcx: &CodegenContext<LlvmCodegenBackend>,
+    module: ModuleCodegen<ModuleLlvm>
+) -> (String, ThinBuffer) {
+    let name = module.name.clone();
+    let buffer = ThinBuffer::new(module.module_llvm.llmod());
+
+    // We emit the module after having serialized it into a ThinBuffer
+    // because only then it will contain the ThinLTO module summary.
+    if let Some(ref incr_comp_session_dir) = cgcx.incr_comp_session_dir {
+        if cgcx.config(module.kind).emit_pre_thin_lto_bc {
+            let path = incr_comp_session_dir
+                .join(pre_lto_bitcode_filename(&name));
+
+            fs::write(&path, buffer.data()).unwrap_or_else(|e| {
+                panic!("Error writing pre-lto-bitcode file `{}`: {}",
+                       path.display(),
+                       e);
+            });
+        }
+    }
+
+    (name, buffer)
 }
 
 fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
@@ -182,7 +213,7 @@
            mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
            symbol_white_list: &[*const libc::c_char],
            timeline: &mut Timeline)
-    -> Result<Vec<LtoModuleCodegen<LlvmCodegenBackend>>, FatalError>
+    -> Result<LtoModuleCodegen<LlvmCodegenBackend>, FatalError>
 {
     info!("going for a fat lto");
 
@@ -271,10 +302,10 @@
         timeline.record("passes");
     }
 
-    Ok(vec![LtoModuleCodegen::Fat {
+    Ok(LtoModuleCodegen::Fat {
         module: Some(module),
         _serialized_bitcode: serialized_bitcode,
-    }])
+    })
 }
 
 struct Linker<'a>(&'a mut llvm::Linker<'a>);
@@ -335,7 +366,7 @@
 /// they all go out of scope.
 fn thin_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
             diag_handler: &Handler,
-            modules: Vec<ModuleCodegen<ModuleLlvm>>,
+            modules: Vec<(String, ThinBuffer)>,
             serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
             cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
             symbol_white_list: &[*const libc::c_char],
@@ -355,41 +386,17 @@
         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
-        //        shouldn't do this, however, and instead figure out how to
-        //        extract a summary from an in-memory module and then merge that
-        //        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.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());
-
-            // We emit the module after having serialized it into a ThinBuffer
-            // because only then it will contain the ThinLTO module summary.
-            if let Some(ref incr_comp_session_dir) = cgcx.incr_comp_session_dir {
-                if cgcx.config(module.kind).emit_pre_thin_lto_bc {
-                    let path = incr_comp_session_dir
-                        .join(pre_lto_bitcode_filename(&module.name));
-
-                    fs::write(&path, buffer.data()).unwrap_or_else(|e| {
-                        panic!("Error writing pre-lto-bitcode file `{}`: {}",
-                               path.display(),
-                               e);
-                    });
-                }
-            }
-
+        for (i, (name, buffer)) in modules.into_iter().enumerate() {
+            info!("local module: {} - {}", i, name);
+            let cname = CString::new(name.clone()).unwrap();
             thin_modules.push(llvm::ThinLTOModule {
-                identifier: name.as_ptr(),
+                identifier: cname.as_ptr(),
                 data: buffer.data().as_ptr(),
                 len: buffer.data().len(),
             });
             thin_buffers.push(buffer);
-            module_names.push(name);
-            timeline.record(&module.name);
+            module_names.push(cname);
+            timeline.record(&name);
         }
 
         // FIXME: All upstream crates are deserialized internally in the
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 2ddbd0c..78a3b69 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -782,7 +782,7 @@
     }
     // The x86 ABI seems to require that leading underscores are added to symbol
     // names, so we need an extra underscore on 32-bit. There's also a leading
-    // '\x01' here which disables LLVM's symbol mangling (e.g. no extra
+    // '\x01' here which disables LLVM's symbol mangling (e.g., no extra
     // underscores added in front).
     let prefix = if cgcx.target_pointer_width == "32" {
         "\x01__imp__"
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index f13eeb6..87185a2 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -94,7 +94,7 @@
         if instance.def.is_inline(tcx) {
             attributes::inline(cx, llfn, attributes::InlineAttr::Hint);
         }
-        attributes::from_fn_attrs(cx, llfn, Some(instance.def.def_id()));
+        attributes::from_fn_attrs(cx, llfn, Some(instance.def.def_id()), sig);
 
         let instance_def_id = instance.def_id();
 
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index fd13421..ad14ca7 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -21,7 +21,7 @@
 use rustc_codegen_ssa::traits::*;
 
 use rustc::ty::layout::{HasDataLayout, LayoutOf, self, TyLayout, Size};
-use rustc::mir::interpret::{Scalar, AllocType, Allocation};
+use rustc::mir::interpret::{Scalar, AllocKind, Allocation};
 use consts::const_alloc_to_llvm;
 use rustc_codegen_ssa::mir::place::PlaceRef;
 
@@ -63,7 +63,7 @@
 ///
 /// Each `Block` may contain an instance of this, indicating whether the block
 /// is part of a landing pad or not. This is used to make decision about whether
-/// to emit `invoke` instructions (e.g. in a landing pad we don't continue to
+/// to emit `invoke` instructions (e.g., in a landing pad we don't continue to
 /// use `invoke`) and also about various function call metadata.
 ///
 /// For GNU exceptions (`landingpad` + `resume` instructions) this structure is
@@ -316,9 +316,9 @@
                 }
             },
             Scalar::Ptr(ptr) => {
-                let alloc_type = self.tcx.alloc_map.lock().get(ptr.alloc_id);
-                let base_addr = match alloc_type {
-                    Some(AllocType::Memory(alloc)) => {
+                let alloc_kind = self.tcx.alloc_map.lock().get(ptr.alloc_id);
+                let base_addr = match alloc_kind {
+                    Some(AllocKind::Memory(alloc)) => {
                         let init = const_alloc_to_llvm(self, alloc);
                         if alloc.mutability == Mutability::Mutable {
                             self.static_addr_of_mut(init, alloc.align, None)
@@ -326,10 +326,10 @@
                             self.static_addr_of(init, alloc.align, None)
                         }
                     }
-                    Some(AllocType::Function(fn_instance)) => {
+                    Some(AllocKind::Function(fn_instance)) => {
                         self.get_fn(fn_instance)
                     }
-                    Some(AllocType::Static(def_id)) => {
+                    Some(AllocKind::Static(def_id)) => {
                         assert!(self.tcx.is_static(def_id).is_some());
                         self.get_static(def_id)
                     }
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 5311a6a..086fb1f 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -223,10 +223,10 @@
 
         debug!("get_static: sym={} instance={:?}", sym, instance);
 
-        let g = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
+        let g = if let Some(id) = self.tcx.hir().as_local_node_id(def_id) {
 
             let llty = self.layout_of(ty).llvm_type(self);
-            let (g, attrs) = match self.tcx.hir.get(id) {
+            let (g, attrs) = match self.tcx.hir().get(id) {
                 Node::Item(&hir::Item {
                     ref attrs, span, node: hir::ItemKind::Static(..), ..
                 }) => {
@@ -295,7 +295,7 @@
                             self.tcx.sess.opts.cg.prefer_dynamic));
 
             if needs_dll_storage_attr {
-                // This item is external but not foreign, i.e. it originates from an external Rust
+                // This item is external but not foreign, i.e., it originates from an external Rust
                 // crate. Since we don't know whether this crate will be linked dynamically or
                 // statically in the final application, we always mark such symbols as 'dllimport'.
                 // If final linkage happens to be static, we rely on compiler-emitted __imp_ stubs
@@ -426,7 +426,7 @@
                 //
                 // By default a global's alignment can be freely increased.
                 // This allows LLVM to generate more performant instructions
-                // e.g. using load-aligned into a SIMD register.
+                // e.g., using load-aligned into a SIMD register.
                 //
                 // However, on macOS 10.10 or below, the dynamic linker does not
                 // respect any alignment given on the TLS (radar 24221680).
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 564e424..0bd6146 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -233,7 +233,7 @@
         // they're not available to be linked against. This poses a few problems
         // for the compiler, some of which are somewhat fundamental, but we use
         // the `use_dll_storage_attrs` variable below to attach the `dllexport`
-        // attribute to all LLVM functions that are exported e.g. they're
+        // attribute to all LLVM functions that are exported e.g., they're
         // already tagged with external linkage). This is suboptimal for a few
         // reasons:
         //
@@ -409,7 +409,6 @@
         ));
 
         let llfn = self.declare_fn("rust_eh_unwind_resume", sig);
-        attributes::unwind(llfn, true);
         attributes::apply_target_cpu_attr(self, llfn);
         unwresume.set(Some(llfn));
         llfn
diff --git a/src/librustc_codegen_llvm/debuginfo/doc.rs b/src/librustc_codegen_llvm/debuginfo/doc.rs
index ce0476b..5e2476e 100644
--- a/src/librustc_codegen_llvm/debuginfo/doc.rs
+++ b/src/librustc_codegen_llvm/debuginfo/doc.rs
@@ -166,7 +166,7 @@
 //!
 //! (3) Tuple-, pointer and function types are structurally identified, which
 //!     means that they are equivalent if their component types are equivalent
-//!     (i.e. (i32, i32) is the same regardless in which crate it is used).
+//!     (i.e., (i32, i32) is the same regardless in which crate it is used).
 //!
 //! This algorithm also provides a stable ID for types that are defined in one
 //! crate but instantiated from metadata within another crate. We just have to
diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs
index 4be93d8..ff5ec20 100644
--- a/src/librustc_codegen_llvm/debuginfo/gdb.rs
+++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs
@@ -76,7 +76,7 @@
 
 pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx) -> bool {
     let omit_gdb_pretty_printer_section =
-        attr::contains_name(&cx.tcx.hir.krate_attrs(),
+        attr::contains_name(&cx.tcx.hir().krate_attrs(),
                             "omit_gdb_pretty_printer_section");
 
     !omit_gdb_pretty_printer_section &&
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 5a1c62e..d263b4e 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -509,7 +509,7 @@
             },
             None => {
                 // The Ty is not in the TypeMap but maybe we have already seen
-                // an equivalent type (e.g. only differing in region arguments).
+                // an equivalent type (e.g., only differing in region arguments).
                 // In order to find out, generate the unique type id and look
                 // that up.
                 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index 78bdf67..5b65b1f 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -300,7 +300,7 @@
 
         let mut flags = DIFlags::FlagPrototyped;
 
-        let local_id = self.tcx().hir.as_local_node_id(def_id);
+        let local_id = self.tcx().hir().as_local_node_id(def_id);
         if let Some((id, _, _)) = *self.sess().entry_fn.borrow() {
             if local_id == Some(id) {
                 flags |= DIFlags::FlagMainSubprogram;
@@ -488,7 +488,7 @@
                     );
 
                     // Only "class" methods are generally understood by LLVM,
-                    // so avoid methods on other types (e.g. `<*mut T>::null`).
+                    // so avoid methods on other types (e.g., `<*mut T>::null`).
                     match impl_self_ty.sty {
                         ty::Adt(def, ..) if !def.is_box() => {
                             Some(type_metadata(cx, impl_self_ty, syntax_pos::DUMMY_SP))
diff --git a/src/librustc_codegen_llvm/debuginfo/type_names.rs b/src/librustc_codegen_llvm/debuginfo/type_names.rs
index 60545f9..2e827cc 100644
--- a/src/librustc_codegen_llvm/debuginfo/type_names.rs
+++ b/src/librustc_codegen_llvm/debuginfo/type_names.rs
@@ -19,9 +19,9 @@
 use rustc::hir;
 
 // Compute the name of the type as it should be stored in debuginfo. Does not do
-// any caching, i.e. calling the function twice with the same type will also do
+// any caching, i.e., calling the function twice with the same type will also do
 // the work twice. The `qualified` parameter only affects the first level of the
-// type name, further levels (i.e. type parameters) are always fully qualified.
+// type name, further levels (i.e., type parameters) are always fully qualified.
 pub fn compute_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
                                              t: Ty<'tcx>,
                                              qualified: bool)
diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/src/librustc_codegen_llvm/debuginfo/utils.rs
index 89262be..4b6ef30 100644
--- a/src/librustc_codegen_llvm/debuginfo/utils.rs
+++ b/src/librustc_codegen_llvm/debuginfo/utils.rs
@@ -26,7 +26,7 @@
 pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool
 {
     // The is_local_to_unit flag indicates whether a function is local to the
-    // current compilation unit (i.e. if it is *static* in the C-sense). The
+    // current compilation unit (i.e., if it is *static* in the C-sense). The
     // *reachable* set should provide a good approximation of this, as it
     // contains everything that might leak out of the current crate (by being
     // externally visible or by being inlined into something externally
diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs
index c23aab4..2964f2e 100644
--- a/src/librustc_codegen_llvm/declare.rs
+++ b/src/librustc_codegen_llvm/declare.rs
@@ -26,8 +26,7 @@
 use rustc::ty::layout::LayoutOf;
 use rustc::session::config::Sanitizer;
 use rustc_data_structures::small_c_str::SmallCStr;
-use rustc_target::spec::PanicStrategy;
-use abi::{Abi, FnType, FnTypeExt};
+use abi::{FnType, FnTypeExt};
 use attributes;
 use context::CodegenCx;
 use type_::Type;
@@ -86,10 +85,6 @@
         _ => {},
     }
 
-    if cx.tcx.sess.panic_strategy() != PanicStrategy::Unwind {
-        attributes::unwind(llfn, false);
-    }
-
     attributes::non_lazy_bind(cx.sess(), llfn);
 
     llfn
@@ -132,10 +127,6 @@
             llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
         }
 
-        if sig.abi != Abi::Rust && sig.abi != Abi::RustCall {
-            attributes::unwind(llfn, false);
-        }
-
         fty.apply_attrs_llfn(llfn);
 
         llfn
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 313aa17..8b26ada 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -732,7 +732,7 @@
                             // We found a tuple that needs squishing! So
                             // run over the tuple and load each field.
                             //
-                            // This assumes the type is "simple", i.e. no
+                            // This assumes the type is "simple", i.e., no
                             // destructors, and the contents are SIMD
                             // etc.
                             assert!(!bx.type_needs_drop(arg.layout.ty));
@@ -997,7 +997,7 @@
 }
 
 // Definition of the standard "try" function for Rust using the GNU-like model
-// of exceptions (e.g. the normal semantics of LLVM's landingpad and invoke
+// of exceptions (e.g., the normal semantics of LLVM's landingpad and invoke
 // instructions).
 //
 // This codegen is a little surprising because we always call a shim
@@ -1081,7 +1081,7 @@
         Abi::Rust
     ));
     let llfn = cx.define_internal_fn(name, rust_fn_sig);
-    attributes::from_fn_attrs(cx, llfn, None);
+    attributes::from_fn_attrs(cx, llfn, None, rust_fn_sig);
     let bx = Builder::new_block(cx, llfn, "entry-block");
     codegen(bx);
     llfn
@@ -1171,6 +1171,27 @@
     );
     let arg_tys = sig.inputs();
 
+    if name == "simd_select_bitmask" {
+        let in_ty = arg_tys[0];
+        let m_len = match in_ty.sty {
+            // Note that this `.unwrap()` crashes for isize/usize, that's sort
+            // of intentional as there's not currently a use case for that.
+            ty::Int(i) => i.bit_width().unwrap(),
+            ty::Uint(i) => i.bit_width().unwrap(),
+            _ => return_error!("`{}` is not an integral type", in_ty),
+        };
+        require_simd!(arg_tys[1], "argument");
+        let v_len = arg_tys[1].simd_size(tcx);
+        require!(m_len == v_len,
+                 "mismatched lengths: mask length `{}` != other vector length `{}`",
+                 m_len, v_len
+        );
+        let i1 = bx.type_i1();
+        let i1xn = bx.type_vector(i1, m_len as u64);
+        let m_i1s = bx.bitcast(args[0].immediate(), i1xn);
+        return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
+    }
+
     // every intrinsic takes a SIMD vector as its first argument
     require_simd!(arg_tys[0], "input");
     let in_ty = arg_tys[0];
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 4f90cb7..ff06d37 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -176,13 +176,20 @@
     fn print_pass_timings(&self) {
             unsafe { llvm::LLVMRustPrintPassTimings(); }
     }
-    fn run_lto(
+    fn run_fat_lto(
         cgcx: &CodegenContext<Self>,
         modules: Vec<ModuleCodegen<Self::Module>>,
+        timeline: &mut Timeline
+    ) -> Result<LtoModuleCodegen<Self>, FatalError> {
+        back::lto::run_fat(cgcx, modules, timeline)
+    }
+    fn run_thin_lto(
+        cgcx: &CodegenContext<Self>,
+        modules: Vec<(String, Self::ThinBuffer)>,
         cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
         timeline: &mut Timeline
     ) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError> {
-        back::lto::run(cgcx, modules, cached_modules, timeline)
+        back::lto::run_thin(cgcx, modules, cached_modules, timeline)
     }
     unsafe fn optimize(
         cgcx: &CodegenContext<Self>,
@@ -209,6 +216,12 @@
     ) -> Result<CompiledModule, FatalError> {
         back::write::codegen(cgcx, diag_handler, module, config, timeline)
     }
+    fn prepare_thin(
+        cgcx: &CodegenContext<Self>,
+        module: ModuleCodegen<Self::Module>
+    ) -> (String, Self::ThinBuffer) {
+        back::lto::prepare_thin(cgcx, module)
+    }
     fn run_lto_pass_manager(
         cgcx: &CodegenContext<Self>,
         module: &ModuleCodegen<Self::Module>,
diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs
index fbd5192..3764c12 100644
--- a/src/librustc_codegen_llvm/llvm/mod.rs
+++ b/src/librustc_codegen_llvm/llvm/mod.rs
@@ -125,7 +125,7 @@
 // example happen for generics when using multiple codegen units. This function simply uses the
 // value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the
 // function.
-// For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52
+// For more details on COMDAT sections see e.g., http://www.airs.com/blog/archives/52
 pub fn SetUniqueComdat(llmod: &Module, val: &'a Value) {
     unsafe {
         LLVMRustSetComdat(llmod, val, LLVMGetValueName(val));
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index fdb6373..12109ae 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -124,6 +124,7 @@
 ];
 
 const X86_WHITELIST: &[(&str, Option<&str>)] = &[
+    ("adx", Some("adx_target_feature")),
     ("aes", None),
     ("avx", None),
     ("avx2", None),
diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs
index 9b2d17d..9c69d7d 100644
--- a/src/librustc_codegen_llvm/mono_item.rs
+++ b/src/librustc_codegen_llvm/mono_item.rs
@@ -63,7 +63,7 @@
             llvm::SetUniqueComdat(self.llmod, lldecl);
         }
 
-        // If we're compiling the compiler-builtins crate, e.g. the equivalent of
+        // If we're compiling the compiler-builtins crate, e.g., the equivalent of
         // compiler-rt, then we want to implicitly compile everything with hidden
         // visibility as we're going to link this object all over the place but
         // don't want the symbols to get exported.
@@ -82,7 +82,12 @@
         if instance.def.is_inline(self.tcx) {
             attributes::inline(self, lldecl, attributes::InlineAttr::Hint);
         }
-        attributes::from_fn_attrs(self, lldecl, Some(instance.def.def_id()));
+        attributes::from_fn_attrs(
+            self,
+            lldecl,
+            Some(instance.def.def_id()),
+            mono_sig,
+        );
 
         self.instances.borrow_mut().insert(instance, lldecl);
     }
diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs
index b100b67..313ab1f 100644
--- a/src/librustc_codegen_llvm/type_.rs
+++ b/src/librustc_codegen_llvm/type_.rs
@@ -255,7 +255,7 @@
         }
     }
 
-    // Creates an integer type with the given number of bits, e.g. i24
+    // Creates an integer type with the given number of bits, e.g., i24
     pub fn ix_llcx(
         llcx: &llvm::Context,
         num_bits: u64
diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs
index 15b5bde..52b560c 100644
--- a/src/librustc_codegen_llvm/type_of.rs
+++ b/src/librustc_codegen_llvm/type_of.rs
@@ -15,8 +15,8 @@
 use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
 use rustc_target::abi::FloatTy;
 use rustc_mir::monomorphize::item::DefPathBasedNames;
-use type_::Type;
 use rustc_codegen_ssa::traits::*;
+use type_::Type;
 
 use std::fmt::Write;
 
@@ -84,10 +84,10 @@
             let packed = false;
             match name {
                 None => {
-                    cx.type_struct( &[fill], packed)
+                    cx.type_struct(&[fill], packed)
                 }
                 Some(ref name) => {
-                    let llty = cx.type_named_struct( name);
+                    let llty = cx.type_named_struct(name);
                     cx.set_struct_body(llty, &[fill], packed);
                     llty
                 }
@@ -236,7 +236,7 @@
         }
     }
 
-    /// Get the LLVM type corresponding to a Rust type, i.e. `rustc::ty::Ty`.
+    /// Get the LLVM type corresponding to a Rust type, i.e., `rustc::ty::Ty`.
     /// The pointee type of the pointer in `PlaceRef` is always this type.
     /// For sized types, it is also the right LLVM type for an `alloca`
     /// containing a value of that type, and most immediates (except `bool`).
@@ -470,9 +470,9 @@
                         // (according to its type), or null (which the
                         // niche field's scalar validity range encodes).
                         // This allows using `dereferenceable_or_null`
-                        // for e.g. `Option<&T>`, and this will continue
+                        // for e.g., `Option<&T>`, and this will continue
                         // to work as long as we don't start using more
-                        // niches than just null (e.g. the first page
+                        // niches than just null (e.g., the first page
                         // of the address space, or unaligned pointers).
                         if self.fields.offset(0) == offset {
                             Some(self.for_variant(cx, dataful_variant))
diff --git a/src/librustc_codegen_llvm/va_arg.rs b/src/librustc_codegen_llvm/va_arg.rs
index fbc3e6f..1e5bb03 100644
--- a/src/librustc_codegen_llvm/va_arg.rs
+++ b/src/librustc_codegen_llvm/va_arg.rs
@@ -105,13 +105,30 @@
 ) -> &'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 target = &bx.cx.tcx.sess.target.target;
     let arch = &bx.cx.tcx.sess.target.target.arch;
-    match (&**arch,
-           bx.cx.tcx.sess.target.target.options.is_like_windows) {
+    match (&**arch, target.options.is_like_windows) {
+        // Windows x86
         ("x86", true) => {
             emit_ptr_va_arg(bx, addr, target_ty, false,
                             Align::from_bytes(4).unwrap(), false)
         }
+        // Generic x86
+        ("x86", _) => {
+            emit_ptr_va_arg(bx, addr, target_ty, false,
+                            Align::from_bytes(4).unwrap(), true)
+        }
+        // Windows Aarch64
+        ("aarch4", true) => {
+            emit_ptr_va_arg(bx, addr, target_ty, false,
+                            Align::from_bytes(8).unwrap(), false)
+        }
+        // iOS Aarch64
+        ("aarch4", _) if target.target_os == "ios" => {
+            emit_ptr_va_arg(bx, addr, target_ty, false,
+                            Align::from_bytes(8).unwrap(), true)
+        }
+        // Windows x86_64
         ("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() {
@@ -122,15 +139,14 @@
             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)
-        }
+        // For all other architecture/OS combinations fall back to using
+        // the LLVM va_arg instruction.
+        // https://llvm.org/docs/LangRef.html#va-arg-instruction
         _ => {
-            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 {
+            let va_list = if (target.arch == "aarch64" ||
+                              target.arch == "x86_64" ||
+                              target.arch == "powerpc") &&
+                             !target.options.is_like_windows {
                 bx.load(addr.immediate(), bx.tcx().data_layout.pointer_align.abi)
             } else {
                 addr.immediate()
diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml
index 7b1c7cf..5099449 100644
--- a/src/librustc_codegen_ssa/Cargo.toml
+++ b/src/librustc_codegen_ssa/Cargo.toml
@@ -16,7 +16,7 @@
 rustc-demangle = "0.1.4"
 memmap = "0.6"
 log = "0.4.5"
-libc = "0.2.43"
+libc = "0.2.44"
 jobserver = "0.1.11"
 
 serialize = { path = "../libserialize" }
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 24a70dc..59102e0 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -192,11 +192,7 @@
 
     // linker and linker flavor specified via command line have precedence over what the target
     // specification specifies
-    if let Some(ret) = infer_from(
-        sess,
-        sess.opts.cg.linker.clone(),
-        sess.opts.debugging_opts.linker_flavor,
-    ) {
+    if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) {
         return ret;
     }
 
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index f3cc344..4960c89 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -107,7 +107,7 @@
 /// This trait is the total list of requirements needed by `back::link` and
 /// represents the meaning of each option being passed down. This trait is then
 /// used to dispatch on whether a GNU-like linker (generally `ld.exe`) or an
-/// MSVC linker (e.g. `link.exe`) is being used.
+/// MSVC linker (e.g., `link.exe`) is being used.
 pub trait Linker {
     fn link_dylib(&mut self, lib: &str);
     fn link_rust_dylib(&mut self, lib: &str, path: &Path);
@@ -606,8 +606,7 @@
         self.cmd.arg("/DEBUG");
 
         // This will cause the Microsoft linker to embed .natvis info into the PDB file
-        let sysroot = self.sess.sysroot();
-        let natvis_dir_path = sysroot.join("lib\\rustlib\\etc");
+        let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
         if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
             // LLVM 5.0.0's lld-link frontend doesn't yet recognize, and chokes
             // on, the /NATVIS:... flags.  LLVM 6 (or earlier) should at worst ignore
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index d25917e..a17a00d 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -85,7 +85,7 @@
             // categories:
             //
             // 1. Those that are included statically via a static library
-            // 2. Those included otherwise (e.g. dynamically or via a framework)
+            // 2. Those included otherwise (e.g., dynamically or via a framework)
             //
             // Although our LLVM module is not literally emitting code for the
             // statically included symbols, it's an export of our library which
@@ -93,9 +93,9 @@
             //
             // As a result, if this id is an FFI item (foreign item) then we only
             // let it through if it's included statically.
-            match tcx.hir.get(node_id) {
+            match tcx.hir().get(node_id) {
                 Node::ForeignItem(..) => {
-                    let def_id = tcx.hir.local_def_id(node_id);
+                    let def_id = tcx.hir().local_def_id(node_id);
                     if tcx.is_statically_included_foreign_item(def_id) {
                         Some(def_id)
                     } else {
@@ -115,7 +115,7 @@
                     node: hir::ImplItemKind::Method(..),
                     ..
                 }) => {
-                    let def_id = tcx.hir.local_def_id(node_id);
+                    let def_id = tcx.hir().local_def_id(node_id);
                     let generics = tcx.generics_of(def_id);
                     if !generics.requires_monomorphization(tcx) &&
                         // Functions marked with #[inline] are only ever codegened
@@ -158,12 +158,12 @@
         .collect();
 
     if let Some(id) = *tcx.sess.proc_macro_decls_static.get() {
-        let def_id = tcx.hir.local_def_id(id);
+        let def_id = tcx.hir().local_def_id(id);
         reachable_non_generics.insert(def_id, SymbolExportLevel::C);
     }
 
     if let Some(id) = *tcx.sess.plugin_registrar_fn.get() {
-        let def_id = tcx.hir.local_def_id(id);
+        let def_id = tcx.hir().local_def_id(id);
         reachable_non_generics.insert(def_id, SymbolExportLevel::C);
     }
 
@@ -225,7 +225,7 @@
         // 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",
         ];
@@ -355,7 +355,7 @@
 }
 
 fn is_unreachable_local_definition_provider(tcx: TyCtxt, def_id: DefId) -> bool {
-    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
+    if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
         !tcx.reachable_set(LOCAL_CRATE).0.contains(&node_id)
     } else {
         bug!("is_unreachable_local_definition called with non-local DefId: {:?}",
@@ -393,7 +393,7 @@
             if let Some(Node::Item(&hir::Item {
                 node: hir::ItemKind::Static(..),
                 ..
-            })) = tcx.hir.get_if_local(sym_def_id) {
+            })) = tcx.hir().get_if_local(sym_def_id) {
                 return SymbolExportLevel::Rust;
             }
         }
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 46aee53..ec790e6 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -252,7 +252,8 @@
 
 fn generate_lto_work<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
-    modules: Vec<ModuleCodegen<B::Module>>,
+    needs_fat_lto: Vec<ModuleCodegen<B::Module>>,
+    needs_thin_lto: Vec<(String, B::ThinBuffer)>,
     import_only_modules: Vec<(SerializedModule<B::ModuleBuffer>, WorkProduct)>
 ) -> Vec<(WorkItem<B>, u64)> {
     let mut timeline = cgcx.time_graph.as_ref().map(|tg| {
@@ -260,22 +261,28 @@
                  CODEGEN_WORK_PACKAGE_KIND,
                  "generate lto")
     }).unwrap_or(Timeline::noop());
-    let (lto_modules, copy_jobs) = B::run_lto(cgcx, modules, import_only_modules, &mut timeline)
-        .unwrap_or_else(|e| e.raise());
 
-    let lto_modules = lto_modules.into_iter().map(|module| {
+    let (lto_modules, copy_jobs) = if !needs_fat_lto.is_empty() {
+        assert!(needs_thin_lto.is_empty());
+        assert!(import_only_modules.is_empty());
+        let lto_module = B::run_fat_lto(cgcx, needs_fat_lto, &mut timeline)
+            .unwrap_or_else(|e| e.raise());
+        (vec![lto_module], vec![])
+    } else {
+        assert!(needs_fat_lto.is_empty());
+        B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules, &mut timeline)
+            .unwrap_or_else(|e| e.raise())
+    };
+
+    lto_modules.into_iter().map(|module| {
         let cost = module.cost();
         (WorkItem::LTO(module), cost)
-    });
-
-    let copy_jobs = copy_jobs.into_iter().map(|wp| {
+    }).chain(copy_jobs.into_iter().map(|wp| {
         (WorkItem::CopyPostLtoArtifacts(CachedModuleCodegen {
             name: wp.cgu_name.clone(),
             source: wp,
         }), 0)
-    });
-
-    lto_modules.chain(copy_jobs).collect()
+    })).collect()
 }
 
 pub struct CompiledModules {
@@ -313,8 +320,8 @@
     let sess = tcx.sess;
     let crate_name = tcx.crate_name(LOCAL_CRATE);
     let crate_hash = tcx.crate_hash(LOCAL_CRATE);
-    let no_builtins = attr::contains_name(&tcx.hir.krate().attrs, "no_builtins");
-    let subsystem = attr::first_attr_value_str_by_name(&tcx.hir.krate().attrs,
+    let no_builtins = attr::contains_name(&tcx.hir().krate().attrs, "no_builtins");
+    let subsystem = attr::first_attr_value_str_by_name(&tcx.hir().krate().attrs,
                                                        "windows_subsystem");
     let windows_subsystem = subsystem.map(|subsystem| {
         if subsystem != "windows" && subsystem != "console" {
@@ -671,16 +678,17 @@
     }
 }
 
-enum WorkItemResult<M> {
+enum WorkItemResult<B: WriteBackendMethods> {
     Compiled(CompiledModule),
-    NeedsLTO(ModuleCodegen<M>),
+    NeedsFatLTO(ModuleCodegen<B::Module>),
+    NeedsThinLTO(String, B::ThinBuffer),
 }
 
 fn execute_work_item<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
     work_item: WorkItem<B>,
     timeline: &mut Timeline
-) -> Result<WorkItemResult<B::Module>, FatalError> {
+) -> Result<WorkItemResult<B>, FatalError> {
     let module_config = cgcx.config(work_item.module_kind());
 
     match work_item {
@@ -696,67 +704,80 @@
     }
 }
 
+// Actual LTO type we end up chosing based on multiple factors.
+enum ComputedLtoType {
+    No,
+    Thin,
+    Fat,
+}
+
 fn execute_optimize_work_item<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
     module: ModuleCodegen<B::Module>,
     module_config: &ModuleConfig,
     timeline: &mut Timeline
-) -> Result<WorkItemResult<B::Module>, FatalError> {
+) -> Result<WorkItemResult<B>, FatalError> {
     let diag_handler = cgcx.create_diag_handler();
 
     unsafe {
         B::optimize(cgcx, &diag_handler, &module, module_config, timeline)?;
     }
 
-    let linker_does_lto = cgcx.opts.debugging_opts.cross_lang_lto.enabled();
-
     // After we've done the initial round of optimizations we need to
     // decide whether to synchronously codegen this module or ship it
     // back to the coordinator thread for further LTO processing (which
     // has to wait for all the initial modules to be optimized).
+
+    // If the linker does LTO, we don't have to do it. Note that we
+    // keep doing full LTO, if it is requested, as not to break the
+    // assumption that the output will be a single module.
+    let linker_does_lto = cgcx.opts.debugging_opts.cross_lang_lto.enabled();
+
+    // When we're automatically doing ThinLTO for multi-codegen-unit
+    // builds we don't actually want to LTO the allocator modules if
+    // it shows up. This is due to various linker shenanigans that
+    // we'll encounter later.
+    let is_allocator = module.kind == ModuleKind::Allocator;
+
+    // We ignore a request for full crate grath LTO if the cate type
+    // is only an rlib, as there is no full crate graph to process,
+    // that'll happen later.
     //
-    // Here we dispatch based on the `cgcx.lto` and kind of module we're
-    // codegenning...
-    let needs_lto = match cgcx.lto {
-        Lto::No => false,
-
-        // If the linker does LTO, we don't have to do it. Note that we
-        // keep doing full LTO, if it is requested, as not to break the
-        // assumption that the output will be a single module.
-        Lto::Thin | Lto::ThinLocal if linker_does_lto => false,
-
-        // Here we've got a full crate graph LTO requested. We ignore
-        // this, however, if the crate type is only an rlib as there's
-        // no full crate graph to process, that'll happen later.
-        //
-        // This use case currently comes up primarily for targets that
-        // require LTO so the request for LTO is always unconditionally
-        // passed down to the backend, but we don't actually want to do
-        // anything about it yet until we've got a final product.
-        Lto::Fat | Lto::Thin => {
-            cgcx.crate_types.len() != 1 ||
-                cgcx.crate_types[0] != config::CrateType::Rlib
-        }
-
-        // When we're automatically doing ThinLTO for multi-codegen-unit
-        // builds we don't actually want to LTO the allocator modules if
-        // it shows up. This is due to various linker shenanigans that
-        // we'll encounter later.
-        Lto::ThinLocal => {
-            module.kind != ModuleKind::Allocator
-        }
-    };
+    // This use case currently comes up primarily for targets that
+    // require LTO so the request for LTO is always unconditionally
+    // passed down to the backend, but we don't actually want to do
+    // anything about it yet until we've got a final product.
+    let is_rlib = cgcx.crate_types.len() == 1
+        && cgcx.crate_types[0] == config::CrateType::Rlib;
 
     // Metadata modules never participate in LTO regardless of the lto
     // settings.
-    let needs_lto = needs_lto && module.kind != ModuleKind::Metadata;
-
-    if needs_lto {
-        Ok(WorkItemResult::NeedsLTO(module))
+    let lto_type = if module.kind == ModuleKind::Metadata {
+        ComputedLtoType::No
     } else {
-        let module = unsafe { B::codegen(cgcx, &diag_handler, module, module_config, timeline)? };
-        Ok(WorkItemResult::Compiled(module))
-    }
+        match cgcx.lto {
+            Lto::ThinLocal if !linker_does_lto && !is_allocator
+                => ComputedLtoType::Thin,
+            Lto::Thin if !linker_does_lto && !is_rlib
+                => ComputedLtoType::Thin,
+            Lto::Fat if !is_rlib => ComputedLtoType::Fat,
+            _ => ComputedLtoType::No,
+        }
+    };
+
+    Ok(match lto_type {
+        ComputedLtoType::No => {
+            let module = unsafe {
+                B::codegen(cgcx, &diag_handler, module, module_config, timeline)?
+            };
+            WorkItemResult::Compiled(module)
+        }
+        ComputedLtoType::Thin => {
+            let (name, thin_buffer) = B::prepare_thin(cgcx, module);
+            WorkItemResult::NeedsThinLTO(name, thin_buffer)
+        }
+        ComputedLtoType::Fat => WorkItemResult::NeedsFatLTO(module),
+    })
 }
 
 fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
@@ -764,7 +785,7 @@
     module: CachedModuleCodegen,
     module_config: &ModuleConfig,
     _: &mut Timeline
-) -> Result<WorkItemResult<B::Module>, FatalError> {
+) -> Result<WorkItemResult<B>, FatalError> {
     let incr_comp_session_dir = cgcx.incr_comp_session_dir
                                     .as_ref()
                                     .unwrap();
@@ -826,7 +847,7 @@
     mut module: lto::LtoModuleCodegen<B>,
     module_config: &ModuleConfig,
     timeline: &mut Timeline
-) -> Result<WorkItemResult<B::Module>, FatalError> {
+) -> Result<WorkItemResult<B>, FatalError> {
     let diag_handler = cgcx.create_diag_handler();
 
     unsafe {
@@ -838,10 +859,15 @@
 
 pub enum Message<B: WriteBackendMethods> {
     Token(io::Result<Acquired>),
-    NeedsLTO {
+    NeedsFatLTO {
         result: ModuleCodegen<B::Module>,
         worker_id: usize,
     },
+    NeedsThinLTO {
+        name: String,
+        thin_buffer: B::ThinBuffer,
+        worker_id: usize,
+    },
     Done {
         result: Result<CompiledModule, ()>,
         worker_id: usize,
@@ -1137,7 +1163,8 @@
         let mut compiled_modules = vec![];
         let mut compiled_metadata_module = None;
         let mut compiled_allocator_module = None;
-        let mut needs_lto = Vec::new();
+        let mut needs_fat_lto = Vec::new();
+        let mut needs_thin_lto = Vec::new();
         let mut lto_import_only_modules = Vec::new();
         let mut started_lto = false;
         let mut codegen_aborted = false;
@@ -1166,7 +1193,8 @@
               running > 0 ||
               (!codegen_aborted && (
                   work_items.len() > 0 ||
-                  needs_lto.len() > 0 ||
+                  needs_fat_lto.len() > 0 ||
+                  needs_thin_lto.len() > 0 ||
                   lto_import_only_modules.len() > 0 ||
                   main_thread_worker_state != MainThreadWorkerState::Idle
               ))
@@ -1212,12 +1240,17 @@
                    running == 0 &&
                    main_thread_worker_state == MainThreadWorkerState::Idle {
                     assert!(!started_lto);
-                    assert!(needs_lto.len() + lto_import_only_modules.len() > 0);
                     started_lto = true;
-                    let modules = mem::replace(&mut needs_lto, Vec::new());
+
+                    let needs_fat_lto =
+                        mem::replace(&mut needs_fat_lto, Vec::new());
+                    let needs_thin_lto =
+                        mem::replace(&mut needs_thin_lto, Vec::new());
                     let import_only_modules =
                         mem::replace(&mut lto_import_only_modules, Vec::new());
-                    for (work, cost) in generate_lto_work(&cgcx, modules, import_only_modules) {
+
+                    for (work, cost) in generate_lto_work(&cgcx, needs_fat_lto,
+                                                          needs_thin_lto, import_only_modules) {
                         let insertion_index = work_items
                             .binary_search_by_key(&cost, |&(_, cost)| cost)
                             .unwrap_or_else(|e| e);
@@ -1284,6 +1317,21 @@
             // Relinquish accidentally acquired extra tokens
             tokens.truncate(running);
 
+            // If a thread exits successfully then we drop a token associated
+            // with that worker and update our `running` count. We may later
+            // re-acquire a token to continue running more work. We may also not
+            // actually drop a token here if the worker was running with an
+            // "ephemeral token"
+            let mut free_worker = |worker_id| {
+                if main_thread_worker_state == MainThreadWorkerState::LLVMing {
+                    main_thread_worker_state = MainThreadWorkerState::Idle;
+                } else {
+                    running -= 1;
+                }
+
+                free_worker_ids.push(worker_id);
+            };
+
             let msg = coordinator_receive.recv().unwrap();
             match *msg.downcast::<Message<B>>().ok().unwrap() {
                 // Save the token locally and the next turn of the loop will use
@@ -1358,24 +1406,8 @@
                     assert_eq!(main_thread_worker_state,
                                MainThreadWorkerState::Codegenning);
                 }
-
-                // If a thread exits successfully then we drop a token associated
-                // with that worker and update our `running` count. We may later
-                // re-acquire a token to continue running more work. We may also not
-                // actually drop a token here if the worker was running with an
-                // "ephemeral token"
-                //
-                // Note that if the thread failed that means it panicked, so we
-                // abort immediately.
                 Message::Done { result: Ok(compiled_module), worker_id } => {
-                    if main_thread_worker_state == MainThreadWorkerState::LLVMing {
-                        main_thread_worker_state = MainThreadWorkerState::Idle;
-                    } else {
-                        running -= 1;
-                    }
-
-                    free_worker_ids.push(worker_id);
-
+                    free_worker(worker_id);
                     match compiled_module.kind {
                         ModuleKind::Regular => {
                             compiled_modules.push(compiled_module);
@@ -1390,15 +1422,15 @@
                         }
                     }
                 }
-                Message::NeedsLTO { result, worker_id } => {
+                Message::NeedsFatLTO { result, worker_id } => {
                     assert!(!started_lto);
-                    if main_thread_worker_state == MainThreadWorkerState::LLVMing {
-                        main_thread_worker_state = MainThreadWorkerState::Idle;
-                    } else {
-                        running -= 1;
-                    }
-                    free_worker_ids.push(worker_id);
-                    needs_lto.push(result);
+                    free_worker(worker_id);
+                    needs_fat_lto.push(result);
+                }
+                Message::NeedsThinLTO { name, thin_buffer, worker_id } => {
+                    assert!(!started_lto);
+                    free_worker(worker_id);
+                    needs_thin_lto.push((name, thin_buffer));
                 }
                 Message::AddImportOnlyModule { module_data, work_product } => {
                     assert!(!started_lto);
@@ -1408,6 +1440,7 @@
                     lto_import_only_modules.push((module_data, work_product));
                     main_thread_worker_state = MainThreadWorkerState::Idle;
                 }
+                // If the thread failed that means it panicked, so we abort immediately.
                 Message::Done { result: Err(()), worker_id: _ } => {
                     bug!("worker thread panicked");
                 }
@@ -1485,7 +1518,7 @@
         // we exit.
         struct Bomb<B: ExtraBackendMethods> {
             coordinator_send: Sender<Box<dyn Any + Send>>,
-            result: Option<WorkItemResult<B::Module>>,
+            result: Option<WorkItemResult<B>>,
             worker_id: usize,
         }
         impl<B: ExtraBackendMethods> Drop for Bomb<B> {
@@ -1495,8 +1528,11 @@
                     Some(WorkItemResult::Compiled(m)) => {
                         Message::Done::<B> { result: Ok(m), worker_id }
                     }
-                    Some(WorkItemResult::NeedsLTO(m)) => {
-                        Message::NeedsLTO::<B> { result: m, worker_id }
+                    Some(WorkItemResult::NeedsFatLTO(m)) => {
+                        Message::NeedsFatLTO::<B> { result: m, worker_id }
+                    }
+                    Some(WorkItemResult::NeedsThinLTO(name, thin_buffer)) => {
+                        Message::NeedsThinLTO::<B> { name, thin_buffer, worker_id }
                     }
                     None => Message::Done::<B> { result: Err(()), worker_id }
                 };
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index 266f789..8a5b8bd 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -268,7 +268,7 @@
         let (base, info) = match bx.load_operand(src).val {
             OperandValue::Pair(base, info) => {
                 // fat-ptr to fat-ptr unsize preserves the vtable
-                // i.e. &'a fmt::Debug+Send => &'a fmt::Debug
+                // i.e., &'a fmt::Debug+Send => &'a fmt::Debug
                 // So we need to pointercast the base to ensure
                 // the types match up.
                 let thin_ptr = dst.layout.field(bx.cx(), FAT_PTR_ADDR);
@@ -453,7 +453,7 @@
 ) {
     let (main_def_id, span) = match *cx.sess().entry_fn.borrow() {
         Some((id, span, _)) => {
-            (cx.tcx().hir.local_def_id(id), span)
+            (cx.tcx().hir().local_def_id(id), span)
         }
         None => return,
     };
diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs
index 8c53129..70b7729 100644
--- a/src/librustc_codegen_ssa/common.rs
+++ b/src/librustc_codegen_ssa/common.rs
@@ -158,7 +158,7 @@
 }
 
 // To avoid UB from LLVM, these two functions mask RHS with an
-// appropriate mask unconditionally (i.e. the fallback behavior for
+// appropriate mask unconditionally (i.e., the fallback behavior for
 // all shifts). For 32- and 64-bit types, this matches the semantics
 // of Java. (See related discussion on #1877 and #10183.)
 
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index 24ede4d..d0cdb89 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -61,7 +61,7 @@
 use rustc::middle::cstore::{LibSource, CrateSource, NativeLibrary};
 use syntax_pos::symbol::Symbol;
 
-// NB: This module needs to be declared first so diagnostics are
+// N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
 mod diagnostics;
 
diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs
index c7e2c76..81da7f5 100644
--- a/src/librustc_codegen_ssa/mir/analyze.rs
+++ b/src/librustc_codegen_ssa/mir/analyze.rs
@@ -43,7 +43,7 @@
             // These sorts of types require an alloca. Note that
             // is_llvm_immediate() may *still* be true, particularly
             // for newtypes, but we currently force some types
-            // (e.g. structs) into an alloca unconditionally, just so
+            // (e.g., structs) into an alloca unconditionally, just so
             // that we don't have to deal with having two pathways
             // (gep vs extractvalue etc).
             analyzer.not_ssa(mir::Local::new(index));
@@ -227,9 +227,9 @@
 
             PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
             PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => {
-                // Reads from uninitialized variables (e.g. in dead code, after
+                // Reads from uninitialized variables (e.g., in dead code, after
                 // optimizations) require locals to be in (uninitialized) memory.
-                // NB: there can be uninitialized reads of a local visited after
+                // N.B., there can be uninitialized reads of a local visited after
                 // an assignment to that local, if they happen on disjoint paths.
                 let ssa_read = match self.first_assignment(local) {
                     Some(assignment_location) => {
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index a992364..750de1c 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -467,7 +467,7 @@
         };
 
         if Some(local) == mir.spread_arg {
-            // This argument (e.g. the last argument in the "rust-call" ABI)
+            // This argument (e.g., the last argument in the "rust-call" ABI)
             // is a tuple that was spread at the ABI level and now we have
             // to reconstruct it into a tuple local variable, from multiple
             // individual LLVM function arguments.
@@ -614,7 +614,7 @@
             // because that's what the llvm.dbg.declare intrinsic expects.
 
             // FIXME(eddyb) this shouldn't be necessary but SROA seems to
-            // mishandle DW_OP_plus not preceded by DW_OP_deref, i.e. it
+            // mishandle DW_OP_plus not preceded by DW_OP_deref, i.e., it
             // 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.
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index 1aba532..90aa9f6 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -229,9 +229,9 @@
             layout::Variants::Tagged { ref tag, .. } => {
                 let signed = match tag.value {
                     // We use `i1` for bytes that are always `0` or `1`,
-                    // e.g. `#[repr(i8)] enum E { A, B }`, but we can't
+                    // e.g., `#[repr(i8)] enum E { A, B }`, but we can't
                     // let LLVM interpret the `i1` as signed, because
-                    // then `i1 1` (i.e. E::B) is effectively `i8 -1`.
+                    // then `i1 1` (i.e., E::B) is effectively `i8 -1`.
                     layout::Int(_, signed) => !tag.is_bool() && signed,
                     _ => false
                 };
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index dc7b1ec..c932ffd 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -319,9 +319,9 @@
                         if let layout::Abi::Scalar(ref scalar) = operand.layout.abi {
                             if let layout::Int(_, s) = scalar.value {
                                 // We use `i1` for bytes that are always `0` or `1`,
-                                // e.g. `#[repr(i8)] enum E { A, B }`, but we can't
+                                // e.g., `#[repr(i8)] enum E { A, B }`, but we can't
                                 // let LLVM interpret the `i1` as signed, because
-                                // then `i1 1` (i.e. E::B) is effectively `i8 -1`.
+                                // then `i1 1` (i.e., E::B) is effectively `i8 -1`.
                                 signed = !scalar.is_bool() && s;
 
                                 let er = scalar.valid_range_exclusive(bx.cx());
diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs
index 8fe8979..26f8a9a 100644
--- a/src/librustc_codegen_ssa/mono_item.rs
+++ b/src/librustc_codegen_ssa/mono_item.rs
@@ -42,7 +42,7 @@
                 cx.codegen_static(def_id, is_mutable);
             }
             MonoItem::GlobalAsm(node_id) => {
-                let item = cx.tcx().hir.expect_item(node_id);
+                let item = cx.tcx().hir().expect_item(node_id);
                 if let hir::ItemKind::GlobalAsm(ref ga) = item.node {
                     cx.codegen_global_asm(ga);
                 } else {
diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/src/librustc_codegen_ssa/traits/declare.rs
index f9a2965..611e5f7 100644
--- a/src/librustc_codegen_ssa/traits/declare.rs
+++ b/src/librustc_codegen_ssa/traits/declare.rs
@@ -41,7 +41,7 @@
     /// Use this function when you intend to define a global. This function will
     /// return None if the name already has a definition associated with it. In that
     /// case an error should be reported to the user, because it usually happens due
-    /// to user’s fault (e.g. misuse of #[no_mangle] or #[export_name] attributes).
+    /// to user’s fault (e.g., misuse of #[no_mangle] or #[export_name] attributes).
     fn define_global(&self, name: &str, ty: Self::Type) -> Option<Self::Value>;
 
     /// Declare a private global
diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs
index 1d31bdf..ed53c8f 100644
--- a/src/librustc_codegen_ssa/traits/type_.rs
+++ b/src/librustc_codegen_ssa/traits/type_.rs
@@ -32,7 +32,7 @@
     fn type_i64(&self) -> Self::Type;
     fn type_i128(&self) -> Self::Type;
 
-    // Creates an integer type with the given number of bits, e.g. i24
+    // Creates an integer type with the given number of bits, e.g., i24
     fn type_ix(&self, num_bits: u64) -> Self::Type;
     fn type_isize(&self) -> Self::Type;
 
diff --git a/src/librustc_codegen_ssa/traits/write.rs b/src/librustc_codegen_ssa/traits/write.rs
index 72522e1..edc5c27 100644
--- a/src/librustc_codegen_ssa/traits/write.rs
+++ b/src/librustc_codegen_ssa/traits/write.rs
@@ -24,14 +24,19 @@
     type ThinData: Send + Sync;
     type ThinBuffer: ThinBufferMethods;
 
-    /// Performs LTO, which in the case of full LTO means merging all modules into
-    /// a single one and returning it for further optimizing. For ThinLTO, it will
-    /// do the global analysis necessary and return two lists, one of the modules
-    /// the need optimization and another for modules that can simply be copied over
-    /// from the incr. comp. cache.
-    fn run_lto(
+    /// Performs fat LTO by merging all modules into a single one and returning it
+    /// for further optimization.
+    fn run_fat_lto(
         cgcx: &CodegenContext<Self>,
         modules: Vec<ModuleCodegen<Self::Module>>,
+        timeline: &mut Timeline,
+    ) -> Result<LtoModuleCodegen<Self>, FatalError>;
+    /// Performs thin LTO by performing necessary global analysis and returning two
+    /// lists, one of the modules that need optimization and another for modules that
+    /// can simply be copied over from the incr. comp. cache.
+    fn run_thin_lto(
+        cgcx: &CodegenContext<Self>,
+        modules: Vec<(String, Self::ThinBuffer)>,
         cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
         timeline: &mut Timeline,
     ) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError>;
@@ -55,6 +60,10 @@
         config: &ModuleConfig,
         timeline: &mut Timeline,
     ) -> Result<CompiledModule, FatalError>;
+    fn prepare_thin(
+        cgcx: &CodegenContext<Self>,
+        module: ModuleCodegen<Self::Module>
+    ) -> (String, Self::ThinBuffer);
     fn run_lto_pass_manager(
         cgcx: &CodegenContext<Self>,
         llmod: &ModuleCodegen<Self::Module>,
diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs
index 046f0cc..7471846 100644
--- a/src/librustc_codegen_utils/codegen_backend.rs
+++ b/src/librustc_codegen_utils/codegen_backend.rs
@@ -22,8 +22,8 @@
 #![feature(box_syntax)]
 
 use std::any::Any;
-use std::io::{self, Write};
-use std::fs::File;
+use std::io::Write;
+use std::fs;
 use std::path::Path;
 use std::sync::{mpsc, Arc};
 
@@ -81,13 +81,9 @@
 
 impl MetadataLoader for NoLlvmMetadataLoader {
     fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
-        let mut file = File::open(filename)
-            .map_err(|e| format!("metadata file open err: {:?}", e))?;
-
-        let mut buf = Vec::new();
-        io::copy(&mut file, &mut buf).unwrap();
-        let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
-        return Ok(rustc_erase_owner!(buf.map_owner_box()));
+        let buf = fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?;
+        let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf);
+        Ok(rustc_erase_owner!(buf.map_owner_box()))
     }
 
     fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String> {
@@ -103,7 +99,7 @@
 }
 
 impl MetadataOnlyCodegenBackend {
-    pub fn new() -> Box<dyn CodegenBackend> {
+    pub fn boxed() -> Box<dyn CodegenBackend> {
         box MetadataOnlyCodegenBackend(())
     }
 }
@@ -165,15 +161,12 @@
                 tcx,
                 collector::MonoItemCollectionMode::Eager
             ).0 {
-            match mono_item {
-                MonoItem::Fn(inst) => {
-                    let def_id = inst.def_id();
-                    if def_id.is_local()  {
-                        let _ = inst.def.is_inline(tcx);
-                        let _ = tcx.codegen_fn_attrs(def_id);
-                    }
+            if let MonoItem::Fn(inst) = mono_item {
+                let def_id = inst.def_id();
+                if def_id.is_local()  {
+                    let _ = inst.def.is_inline(tcx);
+                    let _ = tcx.codegen_fn_attrs(def_id);
                 }
-                _ => {}
             }
         }
         tcx.sess.abort_if_errors();
@@ -181,7 +174,7 @@
         let metadata = tcx.encode_metadata();
 
         box OngoingCodegen {
-            metadata: metadata,
+            metadata,
             metadata_version: tcx.metadata_encoding_version().to_vec(),
             crate_name: tcx.crate_name(LOCAL_CRATE),
         }
@@ -212,8 +205,7 @@
             } else {
                 &ongoing_codegen.metadata.raw_data
             };
-            let mut file = File::create(&output_name).unwrap();
-            file.write_all(metadata).unwrap();
+            fs::write(&output_name, metadata).unwrap();
         }
 
         sess.abort_if_errors();
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index ea8259d..cbef3ff 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -53,7 +53,7 @@
 /// reporting an error.
 pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
     if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() {
-        let main_def_id = tcx.hir.local_def_id(id);
+        let main_def_id = tcx.hir().local_def_id(id);
 
         if tcx.has_attr(main_def_id, "rustc_error") {
             tcx.sess.span_fatal(span, "compilation successful");
diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs
index 344a252..d5b95e7 100644
--- a/src/librustc_codegen_utils/symbol_names.rs
+++ b/src/librustc_codegen_utils/symbol_names.rs
@@ -71,7 +71,7 @@
 //! order to also avoid inter-crate conflicts two more measures are taken:
 //!
 //! - The name of the crate containing the symbol is prepended to the symbol
-//!   name, i.e. symbols are "crate qualified". For example, a function `foo` in
+//!   name, i.e., symbols are "crate qualified". For example, a function `foo` in
 //!   module `bar` in crate `baz` would get a symbol name like
 //!   `baz::bar::foo::{hash}` instead of just `bar::foo::{hash}`. This avoids
 //!   simple conflicts between functions from different crates.
@@ -250,7 +250,7 @@
 
     debug!("symbol_name(def_id={:?}, substs={:?})", def_id, substs);
 
-    let node_id = tcx.hir.as_local_node_id(def_id);
+    let node_id = tcx.hir().as_local_node_id(def_id);
 
     if let Some(id) = node_id {
         if *tcx.sess.plugin_registrar_fn.get() == Some(id) {
@@ -265,7 +265,7 @@
 
     // FIXME(eddyb) Precompute a custom symbol name based on attributes.
     let is_foreign = if let Some(id) = node_id {
-        match tcx.hir.get(id) {
+        match tcx.hir().get(id) {
             Node::ForeignItem(_) => true,
             _ => false,
         }
@@ -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_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs
index 6eaf0c1..c4ad31a 100644
--- a/src/librustc_codegen_utils/symbol_names_test.rs
+++ b/src/librustc_codegen_utils/symbol_names_test.rs
@@ -33,7 +33,7 @@
 
     tcx.dep_graph.with_ignore(|| {
         let mut visitor = SymbolNamesTest { tcx };
-        tcx.hir.krate().visit_all_item_likes(&mut visitor);
+        tcx.hir().krate().visit_all_item_likes(&mut visitor);
     })
 }
 
@@ -45,7 +45,7 @@
     fn process_attrs(&mut self,
                      node_id: ast::NodeId) {
         let tcx = self.tcx;
-        let def_id = tcx.hir.local_def_id(node_id);
+        let def_id = tcx.hir().local_def_id(node_id);
         for attr in tcx.get_attrs(def_id).iter() {
             if attr.check_name(SYMBOL_NAME) {
                 // for now, can only use on monomorphic names
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index 188919d..1754376 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -19,7 +19,7 @@
 rustc-rayon = "0.1.1"
 rustc-rayon-core = "0.1.1"
 rustc-hash = "1.0.1"
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 
 [dependencies.parking_lot]
 version = "0.6"
diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index c211d88..2a19583 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -531,7 +531,7 @@
     /// indices. Cannot be used during a transaction.
     ///
     /// Beforehand, all nodes must be marked as `Done` and no cycles
-    /// on these nodes may be present. This is done by e.g. `process_cycles`.
+    /// on these nodes may be present. This is done by e.g., `process_cycles`.
     #[inline(never)]
     fn compress(&mut self, do_completed: DoCompleted) -> Option<Vec<O>> {
         let nodes_len = self.nodes.len();
diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs
index 27c2f8b..0b126e5 100644
--- a/src/librustc_data_structures/owning_ref/mod.rs
+++ b/src/librustc_data_structures/owning_ref/mod.rs
@@ -215,7 +215,7 @@
 ## Mutable reference
 
 When the owned container implements `DerefMut`, it is also possible to make
-a _mutable owning reference_. (E.g. with `Box`, `RefMut`, `MutexGuard`)
+a _mutable owning reference_. (e.g., with `Box`, `RefMut`, `MutexGuard`)
 
 ```
 extern crate owning_ref;
@@ -452,7 +452,7 @@
     /// use owning_ref::{OwningRef, Erased};
     ///
     /// fn main() {
-    ///     // NB: Using the concrete types here for explicitness.
+    ///     // N.B., using the concrete types here for explicitness.
     ///     // For less verbose code type aliases like `BoxRef` are provided.
     ///
     ///     let owning_ref_a: OwningRef<Box<[i32; 4]>, [i32; 4]>
@@ -722,7 +722,7 @@
     /// use owning_ref::{OwningRefMut, Erased};
     ///
     /// fn main() {
-    ///     // NB: Using the concrete types here for explicitness.
+    ///     // N.B., using the concrete types here for explicitness.
     ///     // For less verbose code type aliases like `BoxRef` are provided.
     ///
     ///     let owning_ref_mut_a: OwningRefMut<Box<[i32; 4]>, [i32; 4]>
@@ -1124,8 +1124,8 @@
     unsafe fn to_handle_mut(x: *const Self) -> Self::HandleMut { (*x).borrow_mut() }
 }
 
-// NB: Implementing ToHandle{,Mut} for Mutex and RwLock requires a decision
-// about which handle creation to use (i.e. read() vs try_read()) as well as
+// N.B., implementing ToHandle{,Mut} for Mutex and RwLock requires a decision
+// about which handle creation to use (i.e., read() vs try_read()) as well as
 // what to do with error results.
 
 /// Typedef of a owning reference that uses a `Box` as the owner.
diff --git a/src/librustc_data_structures/sorted_map.rs b/src/librustc_data_structures/sorted_map.rs
index 29d99a6..3bd3d11 100644
--- a/src/librustc_data_structures/sorted_map.rs
+++ b/src/librustc_data_structures/sorted_map.rs
@@ -10,7 +10,7 @@
 
 use std::borrow::Borrow;
 use std::cmp::Ordering;
-use std::convert::From;
+use std::iter::FromIterator;
 use std::mem;
 use std::ops::{RangeBounds, Bound, Index, IndexMut};
 
@@ -25,11 +25,10 @@
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug, RustcEncodable,
          RustcDecodable)]
 pub struct SortedMap<K: Ord, V> {
-    data: Vec<(K,V)>
+    data: Vec<(K, V)>
 }
 
 impl<K: Ord, V> SortedMap<K, V> {
-
     #[inline]
     pub fn new() -> SortedMap<K, V> {
         SortedMap {
@@ -82,7 +81,10 @@
     }
 
     #[inline]
-    pub fn get(&self, key: &K) -> Option<&V> {
+    pub fn get<Q>(&self, key: &Q) -> Option<&V>
+        where K: Borrow<Q>,
+              Q: Ord + ?Sized
+    {
         match self.lookup_index_for(key) {
             Ok(index) => {
                 unsafe {
@@ -96,7 +98,10 @@
     }
 
     #[inline]
-    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
+    pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
+        where K: Borrow<Q>,
+              Q: Ord + ?Sized
+    {
         match self.lookup_index_for(key) {
             Ok(index) => {
                 unsafe {
@@ -122,13 +127,13 @@
 
     /// Iterate over the keys, sorted
     #[inline]
-    pub fn keys(&self) -> impl Iterator<Item=&K> + ExactSizeIterator {
+    pub fn keys(&self) -> impl Iterator<Item = &K> + ExactSizeIterator {
         self.data.iter().map(|&(ref k, _)| k)
     }
 
     /// Iterate over values, sorted by key
     #[inline]
-    pub fn values(&self) -> impl Iterator<Item=&V> + ExactSizeIterator {
+    pub fn values(&self) -> impl Iterator<Item = &V> + ExactSizeIterator {
         self.data.iter().map(|&(_, ref v)| v)
     }
 
@@ -138,6 +143,11 @@
     }
 
     #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+
+    #[inline]
     pub fn range<R>(&self, range: R) -> &[(K, V)]
         where R: RangeBounds<K>
     {
@@ -207,8 +217,11 @@
 
     /// Looks up the key in `self.data` via `slice::binary_search()`.
     #[inline(always)]
-    fn lookup_index_for(&self, key: &K) -> Result<usize, usize> {
-        self.data.binary_search_by(|&(ref x, _)| x.cmp(key))
+    fn lookup_index_for<Q>(&self, key: &Q) -> Result<usize, usize>
+        where K: Borrow<Q>,
+              Q: Ord + ?Sized
+    {
+        self.data.binary_search_by(|&(ref x, _)| x.borrow().cmp(key))
     }
 
     #[inline]
@@ -247,38 +260,54 @@
 
         (start, end)
     }
+
+    #[inline]
+    pub fn contains_key<Q>(&self, key: &Q) -> bool
+        where K: Borrow<Q>,
+              Q: Ord + ?Sized
+    {
+        self.get(key).is_some()
+    }
 }
 
 impl<K: Ord, V> IntoIterator for SortedMap<K, V> {
     type Item = (K, V);
     type IntoIter = ::std::vec::IntoIter<(K, V)>;
+
     fn into_iter(self) -> Self::IntoIter {
         self.data.into_iter()
     }
 }
 
-impl<K: Ord, V, Q: Borrow<K>> Index<Q> for SortedMap<K, V> {
+impl<'a, K, Q, V> Index<&'a Q> for SortedMap<K, V>
+    where K: Ord + Borrow<Q>,
+          Q: Ord + ?Sized
+{
     type Output = V;
-    fn index(&self, index: Q) -> &Self::Output {
-        let k: &K = index.borrow();
-        self.get(k).unwrap()
+
+    fn index(&self, key: &Q) -> &Self::Output {
+        self.get(key).expect("no entry found for key")
     }
 }
 
-impl<K: Ord, V, Q: Borrow<K>> IndexMut<Q> for SortedMap<K, V> {
-    fn index_mut(&mut self, index: Q) -> &mut Self::Output {
-        let k: &K = index.borrow();
-        self.get_mut(k).unwrap()
+impl<'a, K, Q, V> IndexMut<&'a Q> for SortedMap<K, V>
+    where K: Ord + Borrow<Q>,
+          Q: Ord + ?Sized
+{
+    fn index_mut(&mut self, key: &Q) -> &mut Self::Output {
+        self.get_mut(key).expect("no entry found for key")
     }
 }
 
-impl<K: Ord, V, I: Iterator<Item=(K, V)>> From<I> for SortedMap<K, V> {
-    fn from(data: I) -> Self {
-        let mut data: Vec<(K, V)> = data.collect();
+impl<K: Ord, V> FromIterator<(K, V)> for SortedMap<K, V> {
+    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
+        let mut data: Vec<(K, V)> = iter.into_iter().collect();
+
         data.sort_unstable_by(|&(ref k1, _), &(ref k2, _)| k1.cmp(k2));
         data.dedup_by(|&mut (ref k1, _), &mut (ref k2, _)| {
             k1.cmp(k2) == Ordering::Equal
         });
+
         SortedMap {
             data
         }
diff --git a/src/librustc_data_structures/thin_vec.rs b/src/librustc_data_structures/thin_vec.rs
index 546686b..5b7ea16 100644
--- a/src/librustc_data_structures/thin_vec.rs
+++ b/src/librustc_data_structures/thin_vec.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/// A vector type optimized for cases where this size is usually 0 (c.f. `SmallVector`).
+/// A vector type optimized for cases where this size is usually 0 (cf. `SmallVector`).
 /// The `Option<Box<..>>` wrapping allows us to represent a zero sized vector with `None`,
 /// which uses only a single (null) pointer.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs
index fd5dfab..250dad8 100644
--- a/src/librustc_data_structures/transitive_relation.rs
+++ b/src/librustc_data_structures/transitive_relation.rs
@@ -304,7 +304,7 @@
     ///
     /// The intuition is that this moves "one step up" through a lattice
     /// (where the relation is encoding the `<=` relation for the lattice).
-    /// So e.g. if the relation is `->` and we have
+    /// So e.g., if the relation is `->` and we have
     ///
     /// ```
     /// a -> b -> d -> f
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index 1e32f5e..0356cc9 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -35,7 +35,7 @@
 rustc_typeck = { path = "../librustc_typeck" }
 serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 syntax_ext = { path = "../libsyntax_ext" }
 syntax_pos = { path = "../libsyntax_pos" }
 
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 777cc09..b26d81b 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -9,15 +9,9 @@
 // except according to those terms.
 
 use rustc::dep_graph::DepGraph;
-use rustc::hir::{self, map as hir_map};
+use rustc::hir;
 use rustc::hir::lowering::lower_crate;
-use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::stable_hasher::StableHasher;
-use rustc_mir as mir;
-use rustc::session::{CompileResult, CrateDisambiguator, Session};
-use rustc::session::CompileIncomplete;
-use rustc::session::config::{self, Input, OutputFilenames, OutputType};
-use rustc::session::search_paths::PathKind;
+use rustc::hir::map as hir_map;
 use rustc::lint;
 use rustc::middle::{self, reachable, resolve_lifetime, stability};
 use rustc::middle::privacy::AccessLevels;
@@ -25,32 +19,27 @@
 use rustc::traits;
 use rustc::util::common::{install_panic_hook, time, ErrorReported};
 use rustc::util::profiling::ProfileCategory;
+use rustc::session::{CompileResult, CrateDisambiguator, Session};
+use rustc::session::CompileIncomplete;
+use rustc::session::config::{self, Input, OutputFilenames, OutputType};
+use rustc::session::search_paths::PathKind;
 use rustc_allocator as allocator;
 use rustc_borrowck as borrowck;
+use rustc_codegen_utils::codegen_backend::CodegenBackend;
+use rustc_data_structures::fingerprint::Fingerprint;
+use rustc_data_structures::stable_hasher::StableHasher;
+use rustc_data_structures::sync::{self, Lrc, Lock};
 use rustc_incremental;
-use rustc_resolve::{MakeGlobMap, Resolver, ResolverArenas};
 use rustc_metadata::creader::CrateLoader;
 use rustc_metadata::cstore::{self, CStore};
-use rustc_traits;
-use rustc_codegen_utils::codegen_backend::CodegenBackend;
-use rustc_typeck as typeck;
-use rustc_privacy;
-use rustc_plugin::registry::Registry;
-use rustc_plugin as plugin;
+use rustc_mir as mir;
 use rustc_passes::{self, ast_validation, hir_stats, loops, rvalue_promotion};
-use super::Compilation;
-
-use serialize::json;
-
-use std::any::Any;
-use std::env;
-use std::ffi::OsString;
-use std::fs;
-use std::io::{self, Write};
-use std::iter;
-use std::path::{Path, PathBuf};
-use rustc_data_structures::sync::{self, Lrc, Lock};
-use std::sync::mpsc;
+use rustc_plugin as plugin;
+use rustc_plugin::registry::Registry;
+use rustc_privacy;
+use rustc_resolve::{MakeGlobMap, Resolver, ResolverArenas};
+use rustc_traits;
+use rustc_typeck as typeck;
 use syntax::{self, ast, attr, diagnostics, visit};
 use syntax::early_buffered_lints::BufferedEarlyLint;
 use syntax::ext::base::ExtCtxt;
@@ -62,10 +51,21 @@
 use syntax_pos::{FileName, hygiene};
 use syntax_ext;
 
-use proc_macro_decls;
-use pretty::ReplaceBodyWithLoop;
+use serialize::json;
 
+use std::any::Any;
+use std::env;
+use std::ffi::OsString;
+use std::fs;
+use std::io::{self, Write};
+use std::iter;
+use std::path::{Path, PathBuf};
+use std::sync::mpsc;
+
+use pretty::ReplaceBodyWithLoop;
+use proc_macro_decls;
 use profile;
+use super::Compilation;
 
 #[cfg(not(parallel_queries))]
 pub fn spawn_thread_pool<F: FnOnce(config::Options) -> R + sync::Send, R: sync::Send>(
@@ -305,7 +305,7 @@
                             outdir,
                             output,
                             opt_crate,
-                            tcx.hir.krate(),
+                            tcx.hir().krate(),
                             &analysis,
                             tcx,
                             &crate_name,
@@ -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!(
@@ -908,7 +908,6 @@
         }
     });
 
-    let whitelisted_legacy_custom_derives = registry.take_whitelisted_custom_derives();
     let Registry {
         syntax_exts,
         early_lint_passes,
@@ -955,7 +954,6 @@
         crate_loader,
         &resolver_arenas,
     );
-    resolver.whitelisted_legacy_custom_derives = whitelisted_legacy_custom_derives;
     syntax_ext::register_builtins(&mut resolver, syntax_exts, sess.features_untracked().quote);
 
     // Expand all macros
@@ -977,7 +975,7 @@
         let mut old_path = OsString::new();
         if cfg!(windows) {
             old_path = env::var_os("PATH").unwrap_or(old_path);
-            let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths();
+            let mut new_path = sess.host_filesearch(PathKind::All).search_path_dirs();
             for path in env::split_paths(&old_path) {
                 if !new_path.contains(&path) {
                     new_path.push(path);
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 45d107f..41c9b22 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -258,7 +258,7 @@
             .unwrap_or(&sess.target.target.options.codegen_backend);
         let backend = match &codegen_name[..] {
             "metadata_only" => {
-                rustc_codegen_utils::codegen_backend::MetadataOnlyCodegenBackend::new
+                rustc_codegen_utils::codegen_backend::MetadataOnlyCodegenBackend::boxed
             }
             filename if filename.contains(".") => {
                 load_backend_from_dylib(filename.as_ref())
@@ -291,7 +291,7 @@
     // let's just return a dummy creation function which won't be used in
     // general anyway.
     if cfg!(test) {
-        return rustc_codegen_utils::codegen_backend::MetadataOnlyCodegenBackend::new
+        return rustc_codegen_utils::codegen_backend::MetadataOnlyCodegenBackend::boxed
     }
 
     let target = session::config::host_triple();
@@ -1042,7 +1042,7 @@
                     targets.sort();
                     println!("{}", targets.join("\n"));
                 },
-                Sysroot => println!("{}", sess.sysroot().display()),
+                Sysroot => println!("{}", sess.sysroot.display()),
                 TargetSpec => println!("{}", sess.target.target.to_json().pretty()),
                 FileNames | CrateName => {
                     let input = input.unwrap_or_else(||
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index fb8093d..b41b0d0 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -8,25 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! The various pretty print routines.
+//! The various pretty-printing routines.
 
-pub use self::UserIdentifiedItem::*;
-pub use self::PpSourceMode::*;
-pub use self::PpMode::*;
-use self::NodesMatchingUII::*;
-
-use {abort_on_err, driver};
-
-use rustc::ty::{self, TyCtxt, Resolutions, AllArenas};
 use rustc::cfg;
 use rustc::cfg::graphviz::LabelledCFG;
+use rustc::hir;
+use rustc::hir::map as hir_map;
+use rustc::hir::map::blocks;
+use rustc::hir::print as pprust_hir;
 use rustc::session::Session;
 use rustc::session::config::{Input, OutputFilenames};
+use rustc::ty::{self, TyCtxt, Resolutions, AllArenas};
 use rustc_borrowck as borrowck;
 use rustc_borrowck::graphviz as borrowck_dot;
 use rustc_data_structures::thin_vec::ThinVec;
 use rustc_metadata::cstore::CStore;
-
 use rustc_mir::util::{write_mir_pretty, write_mir_graphviz};
 
 use syntax::ast::{self, BlockCheckMode};
@@ -47,10 +43,11 @@
 use std::str::FromStr;
 use std::mem;
 
-use rustc::hir::map as hir_map;
-use rustc::hir::map::blocks;
-use rustc::hir;
-use rustc::hir::print as pprust_hir;
+pub use self::UserIdentifiedItem::*;
+pub use self::PpSourceMode::*;
+pub use self::PpMode::*;
+use self::NodesMatchingUII::*;
+use {abort_on_err, driver};
 
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub enum PpSourceMode {
@@ -495,7 +492,7 @@
     }
 
     fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'tcx>> {
-        Some(&self.tcx.hir)
+        Some(&self.tcx.hir())
     }
 
     fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn {
@@ -514,7 +511,7 @@
         if let pprust_hir::Nested::Body(id) = nested {
             self.tables.set(self.tcx.body_tables(id));
         }
-        pprust_hir::PpAnn::nested(&self.tcx.hir, state, nested)?;
+        pprust_hir::PpAnn::nested(self.tcx.hir(), state, nested)?;
         self.tables.set(old_tables);
         Ok(())
     }
@@ -851,18 +848,18 @@
             // Find the function this expression is from.
             let mut node_id = expr.id;
             loop {
-                let node = tcx.hir.get(node_id);
+                let node = tcx.hir().get(node_id);
                 if let Some(n) = hir::map::blocks::FnLikeNode::from_node(node) {
                     break n.body();
                 }
-                let parent = tcx.hir.get_parent_node(node_id);
+                let parent = tcx.hir().get_parent_node(node_id);
                 assert_ne!(node_id, parent);
                 node_id = parent;
             }
         }
         blocks::Code::FnLike(fn_like) => fn_like.body(),
     };
-    let body = tcx.hir.body(body_id);
+    let body = tcx.hir().body(body_id);
     let cfg = cfg::CFG::new(tcx, &body);
     let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges;
     let lcfg = LabelledCFG {
@@ -1164,7 +1161,7 @@
         match ppm {
             PpmMir | PpmMirCFG => {
                 if let Some(nodeid) = nodeid {
-                    let def_id = tcx.hir.local_def_id(nodeid);
+                    let def_id = tcx.hir().local_def_id(nodeid);
                     match ppm {
                         PpmMir => write_mir_pretty(tcx, Some(def_id), &mut out),
                         PpmMirCFG => write_mir_graphviz(tcx, Some(def_id), &mut out),
@@ -1183,11 +1180,11 @@
                 let nodeid =
                     nodeid.expect("`pretty flowgraph=..` needs NodeId (int) or unique path \
                                    suffix (b::c::d)");
-                let node = tcx.hir.find(nodeid).unwrap_or_else(|| {
+                let node = tcx.hir().find(nodeid).unwrap_or_else(|| {
                     tcx.sess.fatal(&format!("--pretty flowgraph couldn't find id: {}", nodeid))
                 });
 
-                match blocks::Code::from_node(&tcx.hir, nodeid) {
+                match blocks::Code::from_node(&tcx.hir(), nodeid) {
                     Some(code) => {
                         let variants = gather_flowgraph_variants(tcx.sess);
 
@@ -1200,7 +1197,7 @@
                                                got {:?}",
                                               node);
 
-                        tcx.sess.span_fatal(tcx.hir.span(nodeid), &message)
+                        tcx.sess.span_fatal(tcx.hir().span(nodeid), &message)
                     }
                 }
             }
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index b8cd9bd..f9d49f0 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -10,13 +10,11 @@
 
 //! # Standalone Tests for the Inference Module
 
-use std::path::PathBuf;
-use std::sync::mpsc;
-
 use driver;
 use errors;
 use errors::emitter::Emitter;
 use errors::{DiagnosticBuilder, Level};
+use rustc::hir;
 use rustc::hir::map as hir_map;
 use rustc::infer::outlives::env::OutlivesEnvironment;
 use rustc::infer::type_variable::TypeVariableOrigin;
@@ -40,7 +38,8 @@
 use syntax::symbol::Symbol;
 use syntax_pos::DUMMY_SP;
 
-use rustc::hir;
+use std::path::PathBuf;
+use std::sync::mpsc;
 
 struct Env<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     infcx: &'a infer::InferCtxt<'a, 'gcx, 'tcx>,
@@ -98,7 +97,7 @@
 
 fn test_env<F>(source_string: &str, args: (Box<dyn Emitter + sync::Send>, usize), body: F)
 where
-    F: FnOnce(Env),
+    F: FnOnce(Env) + sync::Send,
 {
     syntax::with_globals(|| {
         let mut options = config::Options::default();
@@ -155,7 +154,7 @@
     let arenas = ty::AllArenas::new();
     let hir_map = hir_map::map_crate(&sess, &cstore, &mut hir_forest, &defs);
 
-    // run just enough stuff to build a tcx:
+    // Run just enough stuff to build a tcx.
     let (tx, _rx) = mpsc::channel();
     let outputs = OutputFilenames {
         out_directory: PathBuf::new(),
@@ -186,7 +185,7 @@
                     param_env: param_env,
                 });
                 let outlives_env = OutlivesEnvironment::new(param_env);
-                let def_id = tcx.hir.local_def_id(ast::CRATE_NODE_ID);
+                let def_id = tcx.hir().local_def_id(ast::CRATE_NODE_ID);
                 infcx.resolve_regions_and_report_errors(
                     def_id,
                     &region_scope_tree,
@@ -228,8 +227,8 @@
     }
 
     pub fn create_simple_region_hierarchy(&mut self) {
-        // creates a region hierarchy where 1 is root, 10 and 11 are
-        // children of 1, etc
+        // Creates a region hierarchy where 1 is root, 10 and 11 are
+        // children of 1, etc.
 
         let dscope = region::Scope {
             id: hir::ItemLocalId::from_u32(1),
@@ -256,7 +255,7 @@
 
     #[allow(dead_code)] // this seems like it could be useful, even if we don't use it now
     pub fn lookup_item(&self, names: &[String]) -> ast::NodeId {
-        return match search_mod(self, &self.infcx.tcx.hir.krate().module, 0, names) {
+        return match search_mod(self, &self.infcx.tcx.hir().krate().module, 0, names) {
             Some(id) => id,
             None => {
                 panic!("no item found: `{}`", names.join("::"));
@@ -271,7 +270,7 @@
         ) -> Option<ast::NodeId> {
             assert!(idx < names.len());
             for item in &m.item_ids {
-                let item = this.infcx.tcx.hir.expect_item(item.id);
+                let item = this.infcx.tcx.hir().expect_item(item.id);
                 if item.name.to_string() == names[idx] {
                     return search(this, item, idx + 1, names);
                 }
@@ -364,7 +363,7 @@
         self.infcx
             .tcx
             .mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
-                def_id: self.infcx.tcx.hir.local_def_id(ast::CRATE_NODE_ID),
+                def_id: self.infcx.tcx.hir().local_def_id(ast::CRATE_NODE_ID),
                 index,
                 name,
             }))
@@ -410,7 +409,7 @@
 
     pub fn re_free(&self, id: u32) -> ty::Region<'tcx> {
         self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion {
-            scope: self.infcx.tcx.hir.local_def_id(ast::CRATE_NODE_ID),
+            scope: self.infcx.tcx.hir().local_def_id(ast::CRATE_NODE_ID),
             bound_region: ty::BrAnon(id),
         }))
     }
@@ -434,7 +433,7 @@
                 obligations,
                 value: (),
             }) => {
-                // None of these tests should require nested obligations:
+                // None of these tests should require nested obligations.
                 assert!(obligations.is_empty());
             }
             Err(ref e) => {
@@ -476,7 +475,7 @@
         env.assert_eq(t_rptr1, t_rptr1);
         env.assert_eq(t_rptr10, t_rptr10);
 
-        // will cause an error when regions are resolved
+        // This will cause an error when regions are resolved.
         env.make_subtype(t_rptr10, t_rptr1);
     })
 }
@@ -487,7 +486,7 @@
     //!
     //!     fn(&'a isize) <: for<'b> fn(&'b isize)
     //!
-    //! does NOT hold.
+    //! *does not* hold.
 
     test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
         env.create_simple_region_hierarchy();
@@ -506,7 +505,7 @@
     //!
     //!     for<'a> fn(&'a isize) <: fn(&'b isize)
     //!
-    //! DOES hold.
+    //! *does* hold.
 
     test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
         env.create_simple_region_hierarchy();
@@ -578,11 +577,11 @@
 fn subst_ty_renumber_some_bounds() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         // Situation:
-        // Theta = [A -> &'a foo]
+        // `Theta = [A -> &'a foo]`
 
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
 
-        // t_source = (A, fn(A))
+        // `t_source = (A, fn(A))`
         let t_source = {
             let t_param = env.t_param(0);
             env.t_pair(t_param, env.t_fn(&[t_param], env.t_nil()))
@@ -591,9 +590,9 @@
         let substs = env.infcx.tcx.intern_substs(&[t_rptr_bound1.into()]);
         let t_substituted = t_source.subst(env.infcx.tcx, substs);
 
-        // t_expected = (&'a isize, fn(&'a isize))
+        // `t_expected = (&'a isize, fn(&'a isize))`
         //
-        // but not that the Debruijn index is different in the different cases.
+        // However, note that the Debruijn index is different in the different cases.
         let t_expected = {
             let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
             env.t_pair(t_rptr_bound1, env.t_fn(&[t_rptr_bound2], env.t_nil()))
@@ -613,7 +612,7 @@
 fn escaping() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
         // Situation:
-        // Theta = [A -> &'a foo]
+        // `Theta = [A -> &'a foo]`
         env.create_simple_region_hierarchy();
 
         assert!(!env.t_nil().has_escaping_bound_vars());
@@ -627,7 +626,7 @@
         let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
         assert!(t_rptr_bound2.has_escaping_bound_vars());
 
-        // t_fn = fn(A)
+        // `t_fn = fn(A)`
         let t_param = env.t_param(0);
         assert!(!t_param.has_escaping_bound_vars());
         let t_fn = env.t_fn(&[t_param], env.t_nil());
@@ -642,7 +641,7 @@
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let re_bound1 = env.re_late_bound_with_debruijn(1, d1());
 
-        // type t_source<'a> = fn(&'a isize)
+        // `type t_source<'a> = fn(&'a isize)`
         let t_source = {
             let re_early = env.re_early_bound(0, "'a");
             env.t_fn(&[env.t_rptr(re_early)], env.t_nil())
@@ -651,7 +650,7 @@
         let substs = env.infcx.tcx.intern_substs(&[re_bound1.into()]);
         let t_substituted = t_source.subst(env.infcx.tcx, substs);
 
-        // t_expected = fn(&'a isize)
+        // `t_expected = fn(&'a isize)`
         //
         // but not that the Debruijn index is different in the different cases.
         let t_expected = {
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index ab2ab25..7bd0f0f 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -549,7 +549,7 @@
         // 3 |
         // 4 |   }
         //   |
-        for pos in 0..line_len + 1 {
+        for pos in 0..=line_len {
             draw_col_separator(buffer, line_offset + pos + 1, width_offset - 2);
             buffer.putc(line_offset + pos + 1,
                         width_offset - 2,
@@ -617,7 +617,7 @@
             let pos = pos + 1;
 
             if pos > 1 && (annotation.has_label() || annotation.takes_space()) {
-                for p in line_offset + 1..line_offset + pos + 1 {
+                for p in line_offset + 1..=line_offset + pos {
                     buffer.putc(p,
                                 code_offset + annotation.start_col,
                                 '|',
@@ -634,7 +634,7 @@
                     }
                 }
                 AnnotationType::MultilineEnd(depth) => {
-                    for p in line_offset..line_offset + pos + 1 {
+                    for p in line_offset..=line_offset + pos {
                         buffer.putc(p,
                                     width_offset + depth - 1,
                                     '|',
@@ -1262,7 +1262,7 @@
 
                         // Do not underline the leading...
                         let start = part.snippet.len()
-                            .saturating_sub(part.snippet.trim_left().len());
+                            .saturating_sub(part.snippet.trim_start().len());
                         // ...or trailing spaces. Account for substitutions containing unicode
                         // characters.
                         let sub_len = part.snippet.trim().chars().fold(0, |acc, ch| {
diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs
index 22a0cc9..15c0dba 100644
--- a/src/librustc_incremental/assert_dep_graph.rs
+++ b/src/librustc_incremental/assert_dep_graph.rs
@@ -79,8 +79,8 @@
             let mut visitor = IfThisChanged { tcx,
                                             if_this_changed: vec![],
                                             then_this_would_need: vec![] };
-            visitor.process_attrs(ast::CRATE_NODE_ID, &tcx.hir.krate().attrs);
-            tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
+            visitor.process_attrs(ast::CRATE_NODE_ID, &tcx.hir().krate().attrs);
+            tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
             (visitor.if_this_changed, visitor.then_this_would_need)
         };
 
@@ -121,7 +121,7 @@
     }
 
     fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) {
-        let def_id = self.tcx.hir.local_def_id(node_id);
+        let def_id = self.tcx.hir().local_def_id(node_id);
         let def_path_hash = self.tcx.def_path_hash(def_id);
         for attr in attrs {
             if attr.check_name(ATTR_IF_THIS_CHANGED) {
@@ -170,7 +170,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for IfThisChanged<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index 4ff2529..8c562ff 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(|| {
@@ -62,7 +62,7 @@
             available_cgus
         };
 
-        for attr in &tcx.hir.krate().attrs {
+        for attr in &tcx.hir().krate().attrs {
             ams.check_attr(attr);
         }
     })
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index f760861..e17663c 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -78,7 +78,7 @@
 ];
 
 /// DepNodes for MirValidated/Optimized, which is relevant in "executable"
-/// code, i.e. functions+methods
+/// code, i.e., functions+methods
 const BASE_MIR: &[&str] = &[
     label_strs::MirOptimized,
     label_strs::MirValidated,
@@ -223,7 +223,7 @@
     }
 
     tcx.dep_graph.with_ignore(|| {
-        let krate = tcx.hir.krate();
+        let krate = tcx.hir().krate();
         let mut dirty_clean_visitor = DirtyCleanVisitor {
             tcx,
             checked_attrs: Default::default(),
@@ -333,7 +333,7 @@
     /// Return all DepNode labels that should be asserted for this item.
     /// index=0 is the "name" used for error messages
     fn auto_labels(&mut self, item_id: ast::NodeId, attr: &Attribute) -> (&'static str, Labels) {
-        let node = self.tcx.hir.get(item_id);
+        let node = self.tcx.hir().get(item_id);
         let (name, labels) = match node {
             HirNode::Item(item) => {
                 match item.node {
@@ -364,16 +364,16 @@
                     // Module-level inline assembly (from global_asm!)
                     HirItem::GlobalAsm(..) => ("ItemGlobalAsm", LABELS_HIR_ONLY),
 
-                    // A type alias, e.g. `type Foo = Bar<u8>`
+                    // A type alias, e.g., `type Foo = Bar<u8>`
                     HirItem::Ty(..) => ("ItemTy", LABELS_HIR_ONLY),
 
-                    // An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
+                    // An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`
                     HirItem::Enum(..) => ("ItemEnum", LABELS_ADT),
 
-                    // A struct definition, e.g. `struct Foo<A> {x: A}`
+                    // A struct definition, e.g., `struct Foo<A> {x: A}`
                     HirItem::Struct(..) => ("ItemStruct", LABELS_ADT),
 
-                    // A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
+                    // A union definition, e.g., `union Foo<A, B> {x: A, y: B}`
                     HirItem::Union(..) => ("ItemUnion", LABELS_ADT),
 
                     // Represents a Trait Declaration
@@ -511,7 +511,7 @@
     }
 
     fn check_item(&mut self, item_id: ast::NodeId, item_span: Span) {
-        let def_id = self.tcx.hir.local_def_id(item_id);
+        let def_id = self.tcx.hir().local_def_id(item_id);
         for attr in self.tcx.get_attrs(def_id).iter() {
             let assertion = match self.assertion_maybe(item_id, attr) {
                 Some(a) => a,
@@ -630,7 +630,7 @@
 
 impl<'a, 'tcx> intravisit::Visitor<'tcx> for FindAllAttrs<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
-        intravisit::NestedVisitorMap::All(&self.tcx.hir)
+        intravisit::NestedVisitorMap::All(&self.tcx.hir())
     }
 
     fn visit_attribute(&mut self, attr: &'tcx Attribute) {
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 75cdefa..11ce10fd 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
@@ -354,7 +354,7 @@
     }
 
     // State: "s-{timestamp}-{random-number}-"
-    let mut new_sub_dir_name = String::from(&old_sub_dir_name[.. dash_indices[2] + 1]);
+    let mut new_sub_dir_name = String::from(&old_sub_dir_name[..= dash_indices[2]]);
 
     // Append the svh
     base_n::push_str(svh.as_u64() as u128, INT_ENCODE_BASE, &mut new_sub_dir_name);
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/builtin.rs b/src/librustc_lint/builtin.rs
index 7dd1ca3..7dd5d3c 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -131,7 +131,7 @@
             hir::ItemKind::Enum(..) |
             hir::ItemKind::Struct(..) |
             hir::ItemKind::Union(..) => {
-                let def_id = cx.tcx.hir.local_def_id(it.id);
+                let def_id = cx.tcx.hir().local_def_id(it.id);
                 self.check_heap_type(cx, it.span, cx.tcx.type_of(def_id))
             }
             _ => ()
@@ -142,7 +142,7 @@
             hir::ItemKind::Struct(ref struct_def, _) |
             hir::ItemKind::Union(ref struct_def, _) => {
                 for struct_field in struct_def.fields() {
-                    let def_id = cx.tcx.hir.local_def_id(struct_field.id);
+                    let def_id = cx.tcx.hir().local_def_id(struct_field.id);
                     self.check_heap_type(cx, struct_field.span,
                                          cx.tcx.type_of(def_id));
                 }
@@ -424,8 +424,8 @@
                 // If the trait is private, add the impl items to private_traits so they don't get
                 // reported for missing docs.
                 let real_trait = trait_ref.path.def.def_id();
-                if let Some(node_id) = cx.tcx.hir.as_local_node_id(real_trait) {
-                    match cx.tcx.hir.find(node_id) {
+                if let Some(node_id) = cx.tcx.hir().as_local_node_id(real_trait) {
+                    match cx.tcx.hir().find(node_id) {
                         Some(Node::Item(item)) => {
                             if let hir::VisibilityKind::Inherited = item.vis.node {
                                 for impl_item_ref in impl_item_refs {
@@ -527,21 +527,21 @@
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(cx.tcx.hir.local_def_id(item.id));
+                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.id));
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             hir::ItemKind::Union(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(cx.tcx.hir.local_def_id(item.id));
+                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.id));
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             hir::ItemKind::Enum(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(cx.tcx.hir.local_def_id(item.id));
+                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.id));
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             _ => return,
@@ -606,7 +606,7 @@
             let mut impls = NodeSet::default();
             cx.tcx.for_each_impl(debug, |d| {
                 if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() {
-                    if let Some(node_id) = cx.tcx.hir.as_local_node_id(ty_def.did) {
+                    if let Some(node_id) = cx.tcx.hir().as_local_node_id(ty_def.did) {
                         impls.insert(node_id);
                     }
                 }
@@ -871,7 +871,7 @@
             _ => return,
         };
 
-        let def_id = cx.tcx.hir.local_def_id(it.id);
+        let def_id = cx.tcx.hir().local_def_id(it.id);
         let prfn = match cx.tcx.extern_mod_stmt_cnum(def_id) {
             Some(cnum) => cx.tcx.plugin_registrar_fn(cnum),
             None => {
@@ -1073,7 +1073,7 @@
     fn check_item(&mut self, ctx: &LateContext, item: &hir::Item) {
         if let hir::ItemKind::Union(ref vdata, _) = item.node {
             for field in vdata.fields() {
-                let field_ty = ctx.tcx.type_of(ctx.tcx.hir.local_def_id(field.id));
+                let field_ty = ctx.tcx.type_of(ctx.tcx.hir().local_def_id(field.id));
                 if field_ty.needs_drop(ctx.tcx, ctx.param_env) {
                     ctx.span_lint(UNIONS_WITH_DROP_FIELDS,
                                   field.span,
@@ -1275,7 +1275,7 @@
     }
 }
 fn check_const(cx: &LateContext, body_id: hir::BodyId) {
-    let def_id = cx.tcx.hir.body_owner_def_id(body_id);
+    let def_id = cx.tcx.hir().body_owner_def_id(body_id);
     let is_static = cx.tcx.is_static(def_id).is_some();
     let param_env = if is_static {
         // Use the same param_env as `codegen_static_initializer`, to reuse the cache.
@@ -1332,7 +1332,7 @@
 
 
         if cx.tcx.features().trivial_bounds {
-            let def_id = cx.tcx.hir.local_def_id(item.id);
+            let def_id = cx.tcx.hir().local_def_id(item.id);
             let predicates = cx.tcx.predicates_of(def_id);
             for &(predicate, span) in &predicates.predicates {
                 let predicate_kind_name = match predicate {
@@ -1540,8 +1540,8 @@
                     }
                     _ => {},
                 }
-                TokenTree::Delimited(_, ref delim) => {
-                    self.check_tokens(cx, delim.tts.clone().into())
+                TokenTree::Delimited(_, _, tts) => {
+                    self.check_tokens(cx, tts.stream())
                 },
             }
         }
@@ -1573,7 +1573,7 @@
                 }
             }
 
-            // no new keywords yet for 2018 edition and beyond
+            // There are no new keywords yet for the 2018 edition and beyond.
             // However, `await` is a "false" keyword in the 2018 edition,
             // and can only be used if the `async_await` feature is enabled.
             // Otherwise, we emit an error.
@@ -1746,7 +1746,7 @@
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements {
     fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
         let infer_static = cx.tcx.features().infer_static_outlives_requirements;
-        let def_id = cx.tcx.hir.local_def_id(item.id);
+        let def_id = cx.tcx.hir().local_def_id(item.id);
         if let hir::ItemKind::Struct(_, ref generics) = item.node {
             let mut bound_count = 0;
             let mut lint_spans = Vec::new();
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 71efc56..66364ff 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Lints in the Rust compiler.
+//! # Lints in the Rust compiler
 //!
 //! This currently only contains the definitions and implementations
 //! of most of the lints that `rustc` supports directly, it does not
 //! contain the infrastructure for defining/registering lints. That is
 //! available in `rustc::lint` and `rustc_plugin` respectively.
 //!
-//! # Note
+//! ## Note
 //!
 //! This API is completely unstable and subject to change.
 
@@ -36,11 +36,16 @@
 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;
 
+mod diagnostics;
+mod nonstandard_style;
+pub mod builtin;
+mod types;
+mod unused;
+
 use rustc::lint;
 use rustc::lint::{LateContext, LateLintPass, LintPass, LintArray};
 use rustc::lint::builtin::{
@@ -55,19 +60,13 @@
 use rustc::hir;
 
 use syntax::ast;
+use syntax::edition::Edition;
 use syntax_pos::Span;
 
 use session::Session;
-use syntax::edition::Edition;
 use lint::LintId;
 use lint::FutureIncompatibleInfo;
 
-mod diagnostics;
-mod nonstandard_style;
-pub mod builtin;
-mod types;
-mod unused;
-
 use nonstandard_style::*;
 use builtin::*;
 use types::*;
@@ -213,8 +212,7 @@
     //   and include the full URL, sort items in ascending order of issue numbers.
     // - Later, change lint to error
     // - Eventually, remove lint
-    store.register_future_incompatible(sess,
-                                       vec![
+    store.register_future_incompatible(sess, vec![
         FutureIncompatibleInfo {
             id: LintId::of(PRIVATE_IN_PUBLIC),
             reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
@@ -334,7 +332,7 @@
         },
         ]);
 
-    // Register renamed and removed lints
+    // Register renamed and removed lints.
     store.register_renamed("single_use_lifetime", "single_use_lifetimes");
     store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths");
     store.register_renamed("bare_trait_object", "bare_trait_objects");
@@ -345,10 +343,10 @@
     store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate");
     store.register_removed("negate_unsigned", "cast a signed value instead");
     store.register_removed("raw_pointer_derive", "using derive with raw pointers is ok");
-    // Register lint group aliases
+    // Register lint group aliases.
     store.register_group_alias("nonstandard_style", "bad_style");
-    // This was renamed to raw_pointer_derive, which was then removed,
-    // so it is also considered removed
+    // This was renamed to `raw_pointer_derive`, which was then removed,
+    // so it is also considered removed.
     store.register_removed("raw_pointer_deriving", "using derive with raw pointers is ok");
     store.register_removed("drop_with_repr_extern", "drop flags have been removed");
     store.register_removed("fat_ptr_transmutes", "was accidentally removed back in 2014");
@@ -378,7 +376,7 @@
     store.register_removed("resolve_trait_on_defaulted_unit",
         "converted into hard error, see https://github.com/rust-lang/rust/issues/48950");
     store.register_removed("private_no_mangle_fns",
-        "no longer an warning, #[no_mangle] functions always exported");
+        "no longer a warning, #[no_mangle] functions always exported");
     store.register_removed("private_no_mangle_statics",
-        "no longer an warning, #[no_mangle] statics always exported");
+        "no longer a warning, #[no_mangle] statics always exported");
 }
diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs
index 40781b0..e071c34 100644
--- a/src/librustc_lint/nonstandard_style.rs
+++ b/src/librustc_lint/nonstandard_style.rs
@@ -8,19 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use rustc::hir::{self, GenericParamKind, PatKind};
 use rustc::hir::def::Def;
+use rustc::hir::intravisit::FnKind;
 use rustc::ty;
+use rustc_target::spec::abi::Abi;
 use lint::{LateContext, LintContext, LintArray};
 use lint::{LintPass, LateLintPass};
-
-use rustc_target::spec::abi::Abi;
 use syntax::ast;
 use syntax::attr;
 use syntax_pos::Span;
 
-use rustc::hir::{self, GenericParamKind, PatKind};
-use rustc::hir::intravisit::FnKind;
-
 #[derive(PartialEq)]
 pub enum MethodLateContext {
     TraitAutoImpl,
@@ -29,7 +27,7 @@
 }
 
 pub fn method_context(cx: &LateContext, id: ast::NodeId) -> MethodLateContext {
-    let def_id = cx.tcx.hir.local_def_id(id);
+    let def_id = cx.tcx.hir().local_def_id(id);
     let item = cx.tcx.associated_item(def_id);
     match item.container {
         ty::TraitContainer(..) => MethodLateContext::TraitAutoImpl,
@@ -169,7 +167,7 @@
     fn to_snake_case(mut str: &str) -> String {
         let mut words = vec![];
         // Preserve leading underscores
-        str = str.trim_left_matches(|c: char| {
+        str = str.trim_start_matches(|c: char| {
             if c == '_' {
                 words.push(String::new());
                 true
@@ -201,7 +199,7 @@
             if ident.is_empty() {
                 return true;
             }
-            let ident = ident.trim_left_matches('\'');
+            let ident = ident.trim_start_matches('\'');
             let ident = ident.trim_matches('_');
 
             let mut allow_underscore = true;
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 82ace62..e225e64 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -139,8 +139,8 @@
                             _ => bug!(),
                         };
                         if lit_val < min || lit_val > max {
-                            let parent_id = cx.tcx.hir.get_parent_node(e.id);
-                            if let Node::Expr(parent_expr) = cx.tcx.hir.get(parent_id) {
+                            let parent_id = cx.tcx.hir().get_parent_node(e.id);
+                            if let Node::Expr(parent_expr) = cx.tcx.hir().get(parent_id) {
                                 if let hir::ExprKind::Cast(..) = parent_expr.node {
                                     if let ty::Char = cx.tables.expr_ty(parent_expr).sty {
                                         let mut err = cx.struct_span_lint(
@@ -756,7 +756,7 @@
                     diag.help(s);
                 }
                 if let ty::Adt(def, _) = unsafe_ty.sty {
-                    if let Some(sp) = self.cx.tcx.hir.span_if_local(def.did) {
+                    if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did) {
                         diag.span_note(sp, "type defined here");
                     }
                 }
@@ -766,7 +766,7 @@
     }
 
     fn check_foreign_fn(&mut self, id: ast::NodeId, decl: &hir::FnDecl) {
-        let def_id = self.cx.tcx.hir.local_def_id(id);
+        let def_id = self.cx.tcx.hir().local_def_id(id);
         let sig = self.cx.tcx.fn_sig(def_id);
         let sig = self.cx.tcx.erase_late_bound_regions(&sig);
 
@@ -783,7 +783,7 @@
     }
 
     fn check_foreign_static(&mut self, id: ast::NodeId, span: Span) {
-        let def_id = self.cx.tcx.hir.local_def_id(id);
+        let def_id = self.cx.tcx.hir().local_def_id(id);
         let ty = self.cx.tcx.type_of(def_id);
         self.check_type_for_ffi_and_report_errors(span, ty);
     }
@@ -801,7 +801,7 @@
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
     fn check_foreign_item(&mut self, cx: &LateContext, it: &hir::ForeignItem) {
         let mut vis = ImproperCTypesVisitor { cx };
-        let abi = cx.tcx.hir.get_foreign_abi(it.id);
+        let abi = cx.tcx.hir().get_foreign_abi(it.id);
         if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic {
             match it.node {
                 hir::ForeignItemKind::Fn(ref decl, _, _) => {
@@ -827,7 +827,7 @@
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
     fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
         if let hir::ItemKind::Enum(ref enum_definition, _) = it.node {
-            let item_def_id = cx.tcx.hir.local_def_id(it.id);
+            let item_def_id = cx.tcx.hir().local_def_id(it.id);
             let t = cx.tcx.type_of(item_def_id);
             let ty = cx.tcx.erase_regions(&t);
             match cx.layout_of(ty) {
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index fab618d..d3e1af7 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -61,7 +61,7 @@
 
         let t = cx.tables.expr_ty(&expr);
         let type_permits_lack_of_use = if t.is_unit()
-            || cx.tcx.is_ty_uninhabited_from(cx.tcx.hir.get_module_parent(expr.id), t) {
+            || cx.tcx.is_ty_uninhabited_from(cx.tcx.hir().get_module_parent(expr.id), t) {
             true
         } else {
             match t.sty {
@@ -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_llvm/build.rs b/src/librustc_llvm/build.rs
index 7d01ed5..ce48208 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -192,11 +192,11 @@
             // On MSVC llvm-config will print the full name to libraries, but
             // we're only interested in the name part
             let name = Path::new(lib).file_name().unwrap().to_str().unwrap();
-            name.trim_right_matches(".lib")
+            name.trim_end_matches(".lib")
         } else if lib.ends_with(".lib") {
             // Some MSVC libraries just come up with `.lib` tacked on, so chop
             // that off
-            lib.trim_right_matches(".lib")
+            lib.trim_end_matches(".lib")
         } else {
             continue;
         };
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 1c48d84..10f35e5 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -22,7 +22,7 @@
 // NOTE: This crate only exists to allow linking on mingw targets.
 
 /// Initialize targets enabled by the build script via `cfg(llvm_component = "...")`.
-/// NB: this function can't be moved to `rustc_codegen_llvm` because of the `cfg`s.
+/// N.B., this function can't be moved to `rustc_codegen_llvm` because of the `cfg`s.
 pub fn initialize_available_targets() {
     macro_rules! init_target(
         ($cfg:meta, $($method:ident),*) => { {
diff --git a/src/librustc_lsan/Cargo.toml b/src/librustc_lsan/Cargo.toml
index 2573825..a8e11df 100644
--- a/src/librustc_lsan/Cargo.toml
+++ b/src/librustc_lsan/Cargo.toml
@@ -16,4 +16,4 @@
 [dependencies]
 alloc = { path = "../liballoc" }
 core = { path = "../libcore" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
+compiler_builtins = "0.1.0"
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 2be9883..f650db5 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -56,7 +56,7 @@
     /// Original name of the crate.
     pub name: Symbol,
 
-    /// Name of the crate as imported.  I.e. if imported with
+    /// Name of the crate as imported.  I.e., if imported with
     /// `extern crate foo as bar;` this will be `bar`.
     pub imported_name: Symbol,
 
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index d0fa63a..da2ba39 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -307,7 +307,7 @@
             Lrc::new(link_args::collect(tcx))
         },
 
-        // Returns a map from a sufficiently visible external item (i.e. an
+        // Returns a map from a sufficiently visible external item (i.e., an
         // external item that is visible from at least one local module) to a
         // sufficiently visible parent (considering modules that re-export the
         // external item to be parents).
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 2736c60..feed70c 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -318,7 +318,7 @@
     }
 
     fn encode_info_for_items(&mut self) -> Index {
-        let krate = self.tcx.hir.krate();
+        let krate = self.tcx.hir().krate();
         let mut index = IndexBuilder::new(self);
         let vis = Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Public };
         index.record(DefId::local(CRATE_DEF_INDEX),
@@ -333,7 +333,7 @@
     }
 
     fn encode_def_path_table(&mut self) -> Lazy<DefPathTable> {
-        let definitions = self.tcx.hir.definitions();
+        let definitions = self.tcx.hir().definitions();
         self.lazy(definitions.def_path_table())
     }
 
@@ -475,7 +475,7 @@
         let index = items.write_index(&mut self.opaque);
         let index_bytes = self.position() - i;
 
-        let attrs = tcx.hir.krate_attrs();
+        let attrs = tcx.hir().krate_attrs();
         let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
         let has_default_lib_allocator = attr::contains_name(&attrs, "default_lib_allocator");
         let has_global_allocator = *tcx.sess.has_global_allocator.get();
@@ -495,10 +495,10 @@
             plugin_registrar_fn: tcx.sess
                 .plugin_registrar_fn
                 .get()
-                .map(|id| tcx.hir.local_def_id(id).index),
+                .map(|id| tcx.hir().local_def_id(id).index),
             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)
+                Some(tcx.hir().local_def_id(id).index)
             } else {
                 None
             },
@@ -600,8 +600,8 @@
             }
         };
 
-        let enum_id = tcx.hir.as_local_node_id(enum_did).unwrap();
-        let enum_vis = &tcx.hir.expect_item(enum_id).vis;
+        let enum_id = tcx.hir().as_local_node_id(enum_did).unwrap();
+        let enum_vis = &tcx.hir().expect_item(enum_id).vis;
 
         Entry {
             kind: EntryKind::Variant(self.lazy(&data)),
@@ -636,7 +636,7 @@
                                                                  &hir::Visibility)>)
                            -> Entry<'tcx> {
         let tcx = self.tcx;
-        let def_id = tcx.hir.local_def_id(id);
+        let def_id = tcx.hir().local_def_id(id);
         debug!("IsolatedEncoder::encode_info_for_mod({:?})", def_id);
 
         let data = ModData {
@@ -652,7 +652,7 @@
             span: self.lazy(&tcx.def_span(def_id)),
             attributes: self.encode_attributes(attrs),
             children: self.lazy_seq(md.item_ids.iter().map(|item_id| {
-                tcx.hir.local_def_id(item_id.id).index
+                tcx.hir().local_def_id(item_id.id).index
             })),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
@@ -686,8 +686,8 @@
         let def_id = field.did;
         debug!("IsolatedEncoder::encode_field({:?})", def_id);
 
-        let variant_id = tcx.hir.as_local_node_id(variant.did).unwrap();
-        let variant_data = tcx.hir.expect_variant_data(variant_id);
+        let variant_id = tcx.hir().as_local_node_id(variant.did).unwrap();
+        let variant_data = tcx.hir().expect_variant_data(variant_id);
 
         Entry {
             kind: EntryKind::Field,
@@ -726,8 +726,8 @@
             }
         };
 
-        let struct_id = tcx.hir.as_local_node_id(adt_def_id).unwrap();
-        let struct_vis = &tcx.hir.expect_item(struct_id).vis;
+        let struct_id = tcx.hir().as_local_node_id(adt_def_id).unwrap();
+        let struct_vis = &tcx.hir().expect_item(struct_id).vis;
         let mut ctor_vis = ty::Visibility::from_hir(struct_vis, struct_id, tcx);
         for field in &variant.fields {
             if ctor_vis.is_at_least(field.vis, tcx) {
@@ -791,8 +791,8 @@
         debug!("IsolatedEncoder::encode_info_for_trait_item({:?})", def_id);
         let tcx = self.tcx;
 
-        let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-        let ast_item = tcx.hir.expect_trait_item(node_id);
+        let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+        let ast_item = tcx.hir().expect_trait_item(node_id);
         let trait_item = tcx.associated_item(def_id);
 
         let container = match trait_item.defaultness {
@@ -814,7 +814,7 @@
                     };
 
                 let rendered =
-                    hir::print::to_string(&self.tcx.hir, |s| s.print_trait_item(ast_item));
+                    hir::print::to_string(self.tcx.hir(), |s| s.print_trait_item(ast_item));
                 let rendered_const = self.lazy(&RenderedConst(rendered));
 
                 EntryKind::AssociatedConst(container, const_qualif, rendered_const)
@@ -891,7 +891,7 @@
     }
 
     fn const_qualif(&self, mir: u8, body_id: hir::BodyId) -> ConstQualif {
-        let body_owner_def_id = self.tcx.hir.body_owner_def_id(body_id);
+        let body_owner_def_id = self.tcx.hir().body_owner_def_id(body_id);
         let ast_promotable = self.tcx.const_is_rvalue_promotable_to_static(body_owner_def_id);
 
         ConstQualif { mir, ast_promotable }
@@ -901,8 +901,8 @@
         debug!("IsolatedEncoder::encode_info_for_impl_item({:?})", def_id);
         let tcx = self.tcx;
 
-        let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
-        let ast_item = self.tcx.hir.expect_impl_item(node_id);
+        let node_id = self.tcx.hir().as_local_node_id(def_id).unwrap();
+        let ast_item = self.tcx.hir().expect_impl_item(node_id);
         let impl_item = self.tcx.associated_item(def_id);
 
         let container = match impl_item.defaultness {
@@ -987,7 +987,7 @@
     fn encode_fn_arg_names_for_body(&mut self, body_id: hir::BodyId)
                                     -> LazySeq<ast::Name> {
         self.tcx.dep_graph.with_ignore(|| {
-            let body = self.tcx.hir.body(body_id);
+            let body = self.tcx.hir().body(body_id);
             self.lazy_seq(body.arguments.iter().map(|arg| {
                 match arg.pat.node {
                     PatKind::Binding(_, _, ident, _) => ident.name,
@@ -1036,8 +1036,8 @@
     }
 
     fn encode_rendered_const_for_body(&mut self, body_id: hir::BodyId) -> Lazy<RenderedConst> {
-        let body = self.tcx.hir.body(body_id);
-        let rendered = hir::print::to_string(&self.tcx.hir, |s| s.print_expr(&body.value));
+        let body = self.tcx.hir().body(body_id);
+        let rendered = hir::print::to_string(self.tcx.hir(), |s| s.print_expr(&body.value));
         let rendered_const = &RenderedConst(rendered);
         self.lazy(rendered_const)
     }
@@ -1081,7 +1081,7 @@
                 // for methods, write all the stuff get_trait_method
                 // needs to know
                 let struct_ctor = if !struct_def.is_struct() {
-                    Some(tcx.hir.local_def_id(struct_def.id()).index)
+                    Some(tcx.hir().local_def_id(struct_def.id()).index)
                 } else {
                     None
                 };
@@ -1141,7 +1141,8 @@
 
                 EntryKind::Impl(self.lazy(&data))
             }
-            hir::ItemKind::Trait(..) => {
+            hir::ItemKind::Trait(..) |
+            hir::ItemKind::TraitAlias(..) => {
                 let trait_def = tcx.trait_def(def_id);
                 let data = TraitData {
                     unsafety: trait_def.unsafety,
@@ -1154,7 +1155,6 @@
                 EntryKind::Trait(self.lazy(&data))
             }
             hir::ItemKind::ExternCrate(_) |
-            hir::ItemKind::TraitAlias(..) |
             hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item),
         };
 
@@ -1167,7 +1167,7 @@
                 hir::ItemKind::ForeignMod(ref fm) => {
                     self.lazy_seq(fm.items
                         .iter()
-                        .map(|foreign_item| tcx.hir.local_def_id(foreign_item.id).index))
+                        .map(|foreign_item| tcx.hir().local_def_id(foreign_item.id).index))
                 }
                 hir::ItemKind::Enum(..) => {
                     let def = self.tcx.adt_def(def_id);
@@ -1282,7 +1282,7 @@
     /// Serialize the text of exported macros
     fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef) -> Entry<'tcx> {
         use syntax::print::pprust;
-        let def_id = self.tcx.hir.local_def_id(macro_def.id);
+        let def_id = self.tcx.hir().local_def_id(macro_def.id);
         Entry {
             kind: EntryKind::MacroDef(self.lazy(&MacroDef {
                 body: pprust::tts_to_string(&macro_def.body.trees().collect::<Vec<_>>()),
@@ -1339,8 +1339,8 @@
         let tcx = self.tcx;
 
         let tables = self.tcx.typeck_tables_of(def_id);
-        let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
-        let hir_id = self.tcx.hir.node_to_hir_id(node_id);
+        let node_id = self.tcx.hir().as_local_node_id(def_id).unwrap();
+        let hir_id = self.tcx.hir().node_to_hir_id(node_id);
         let kind = match tables.node_id_to_type(hir_id).sty {
             ty::Generator(def_id, ..) => {
                 let layout = self.tcx.generator_layout(def_id);
@@ -1382,8 +1382,8 @@
     fn encode_info_for_anon_const(&mut self, def_id: DefId) -> Entry<'tcx> {
         debug!("IsolatedEncoder::encode_info_for_anon_const({:?})", def_id);
         let tcx = self.tcx;
-        let id = tcx.hir.as_local_node_id(def_id).unwrap();
-        let body_id = tcx.hir.body_owned_by(id);
+        let id = tcx.hir().as_local_node_id(def_id).unwrap();
+        let body_id = tcx.hir().body_owned_by(id);
         let const_data = self.encode_rendered_const_for_body(body_id);
         let mir = tcx.mir_const_qualif(def_id).0;
 
@@ -1491,7 +1491,7 @@
             tcx,
             impls: FxHashMap::default(),
         };
-        tcx.hir.krate().visit_all_item_likes(&mut visitor);
+        tcx.hir().krate().visit_all_item_likes(&mut visitor);
 
         let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
 
@@ -1505,7 +1505,7 @@
             .map(|(trait_def_id, mut impls)| {
                 // Bring everything into deterministic order for hashing
                 impls.sort_by_cached_key(|&def_index| {
-                    tcx.hir.definitions().def_path_hash(def_index)
+                    tcx.hir().definitions().def_path_hash(def_index)
                 });
 
                 TraitImpls {
@@ -1617,7 +1617,7 @@
 
 impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.index.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.index.tcx.hir())
     }
     fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
         intravisit::walk_expr(self, ex);
@@ -1625,7 +1625,7 @@
     }
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         intravisit::walk_item(self, item);
-        let def_id = self.index.tcx.hir.local_def_id(item.id);
+        let def_id = self.index.tcx.hir().local_def_id(item.id);
         match item.node {
             hir::ItemKind::ExternCrate(_) |
             hir::ItemKind::Use(..) => (), // ignore these
@@ -1635,7 +1635,7 @@
     }
     fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) {
         intravisit::walk_foreign_item(self, ni);
-        let def_id = self.index.tcx.hir.local_def_id(ni.id);
+        let def_id = self.index.tcx.hir().local_def_id(ni.id);
         self.index.record(def_id,
                           IsolatedEncoder::encode_info_for_foreign_item,
                           (def_id, ni));
@@ -1647,7 +1647,7 @@
         intravisit::walk_variant(self, v, g, id);
 
         if let Some(ref discr) = v.node.disr_expr {
-            let def_id = self.index.tcx.hir.local_def_id(discr.id);
+            let def_id = self.index.tcx.hir().local_def_id(discr.id);
             self.index.record(def_id, IsolatedEncoder::encode_info_for_anon_const, def_id);
         }
     }
@@ -1660,7 +1660,7 @@
         self.index.encode_info_for_ty(ty);
     }
     fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef) {
-        let def_id = self.index.tcx.hir.local_def_id(macro_def.id);
+        let def_id = self.index.tcx.hir().local_def_id(macro_def.id);
         self.index.record(def_id, IsolatedEncoder::encode_info_for_macro_def, macro_def);
     }
 }
@@ -1682,7 +1682,7 @@
             match param.kind {
                 hir::GenericParamKind::Lifetime { .. } => {}
                 hir::GenericParamKind::Type { ref default, .. } => {
-                    let def_id = self.tcx.hir.local_def_id(param.id);
+                    let def_id = self.tcx.hir().local_def_id(param.id);
                     let has_default = Untracked(default.is_some());
                     let encode_info = IsolatedEncoder::encode_info_for_ty_param;
                     self.record(def_id, encode_info, (def_id, has_default));
@@ -1694,7 +1694,7 @@
     fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
         match ty.node {
             hir::TyKind::Array(_, ref length) => {
-                let def_id = self.tcx.hir.local_def_id(length.id);
+                let def_id = self.tcx.hir().local_def_id(length.id);
                 self.record(def_id, IsolatedEncoder::encode_info_for_anon_const, def_id);
             }
             _ => {}
@@ -1704,7 +1704,7 @@
     fn encode_info_for_expr(&mut self, expr: &hir::Expr) {
         match expr.node {
             hir::ExprKind::Closure(..) => {
-                let def_id = self.tcx.hir.local_def_id(expr.id);
+                let def_id = self.tcx.hir().local_def_id(expr.id);
                 self.record(def_id, IsolatedEncoder::encode_info_for_closure, def_id);
             }
             _ => {}
@@ -1716,7 +1716,7 @@
     /// so it's easier to do that here then to wait until we would encounter
     /// normally in the visitor walk.
     fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
-        let def_id = self.tcx.hir.local_def_id(item.id);
+        let def_id = self.tcx.hir().local_def_id(item.id);
         match item.node {
             hir::ItemKind::Static(..) |
             hir::ItemKind::Const(..) |
@@ -1746,7 +1746,7 @@
 
                 // If the struct has a constructor, encode it.
                 if !struct_def.is_struct() {
-                    let ctor_def_id = self.tcx.hir.local_def_id(struct_def.id());
+                    let ctor_def_id = self.tcx.hir().local_def_id(struct_def.id());
                     self.record(ctor_def_id,
                                 IsolatedEncoder::encode_struct_ctor,
                                 (def_id, ctor_def_id));
@@ -1781,7 +1781,7 @@
 impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'a, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
         if let hir::ItemKind::Impl(..) = item.node {
-            let impl_id = self.tcx.hir.local_def_id(item.id);
+            let impl_id = self.tcx.hir().local_def_id(item.id);
             if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) {
                 self.impls
                     .entry(trait_ref.def_id)
diff --git a/src/librustc_metadata/foreign_modules.rs b/src/librustc_metadata/foreign_modules.rs
index e96d56f..5b2002f 100644
--- a/src/librustc_metadata/foreign_modules.rs
+++ b/src/librustc_metadata/foreign_modules.rs
@@ -18,7 +18,7 @@
         tcx,
         modules: Vec::new(),
     };
-    tcx.hir.krate().visit_all_item_likes(&mut collector);
+    tcx.hir().krate().visit_all_item_likes(&mut collector);
     return collector.modules
 }
 
@@ -35,11 +35,11 @@
         };
 
         let foreign_items = fm.items.iter()
-            .map(|it| self.tcx.hir.local_def_id(it.id))
+            .map(|it| self.tcx.hir().local_def_id(it.id))
             .collect();
         self.modules.push(ForeignModule {
             foreign_items,
-            def_id: self.tcx.hir.local_def_id(it.id),
+            def_id: self.tcx.hir().local_def_id(it.id),
         });
     }
 
diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs
index fd2c223..aea3ac1 100644
--- a/src/librustc_metadata/index_builder.rs
+++ b/src/librustc_metadata/index_builder.rs
@@ -90,7 +90,7 @@
 impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
     pub fn new(ecx: &'a mut EncodeContext<'b, 'tcx>) -> Self {
         IndexBuilder {
-            items: Index::new(ecx.tcx.hir.definitions().def_index_counts_lo_hi()),
+            items: Index::new(ecx.tcx.hir().definitions().def_index_counts_lo_hi()),
             ecx,
         }
     }
@@ -195,7 +195,7 @@
     ($t:ty) => {
         impl<'tcx> DepGraphRead for &'tcx $t {
             fn read(&self, tcx: TyCtxt) {
-                tcx.hir.read(self.id);
+                tcx.hir().read(self.id);
             }
         }
     }
@@ -229,6 +229,6 @@
 
 impl<T> DepGraphRead for FromId<T> {
     fn read(&self, tcx: TyCtxt) {
-        tcx.hir.read(self.0);
+        tcx.hir().read(self.0);
     }
 }
diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs
index 008e1e3..decd85c 100644
--- a/src/librustc_metadata/link_args.rs
+++ b/src/librustc_metadata/link_args.rs
@@ -17,9 +17,9 @@
     let mut collector = Collector {
         args: Vec::new(),
     };
-    tcx.hir.krate().visit_all_item_likes(&mut collector);
+    tcx.hir().krate().visit_all_item_likes(&mut collector);
 
-    for attr in tcx.hir.krate().attrs.iter() {
+    for attr in tcx.hir().krate().attrs.iter() {
         if attr.path == "link_args" {
             if let Some(linkarg) = attr.value_str() {
                 collector.add_link_args(&linkarg.as_str());
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index d4e5169..f01ed9e 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -661,7 +661,7 @@
             // Ok so at this point we've determined that `(lib, kind)` above is
             // a candidate crate to load, and that `slot` is either none (this
             // is the first crate of its kind) or if some the previous path has
-            // the exact same hash (e.g. it's the exact same crate).
+            // the exact same hash (e.g., it's the exact same crate).
             //
             // In principle these two candidate crates are exactly the same so
             // we can choose either of them to link. As a stupidly gross hack,
@@ -678,7 +678,7 @@
             // candidates are all canonicalized, so we canonicalize the sysroot
             // as well.
             if let Some((ref prev, _)) = ret {
-                let sysroot = self.sess.sysroot();
+                let sysroot = &self.sess.sysroot;
                 let sysroot = sysroot.canonicalize()
                                      .unwrap_or_else(|_| sysroot.to_path_buf());
                 if prev.starts_with(&sysroot) {
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index 392644c..6f85418 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -25,7 +25,7 @@
         tcx,
         libs: Vec::new(),
     };
-    tcx.hir.krate().visit_all_item_likes(&mut collector);
+    tcx.hir().krate().visit_all_item_likes(&mut collector);
     collector.process_command_line();
     return collector.libs
 }
@@ -65,7 +65,7 @@
                 name: None,
                 kind: cstore::NativeUnknown,
                 cfg: None,
-                foreign_module: Some(self.tcx.hir.local_def_id(it.id)),
+                foreign_module: Some(self.tcx.hir().local_def_id(it.id)),
                 wasm_import_module: None,
             };
             let mut kind_specified = false;
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index e91d15b..1ae3f0a 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -40,7 +40,7 @@
 }
 
 /// Metadata encoding version.
-/// NB: increment this if you change the format of metadata such that
+/// N.B., increment this if you change the format of metadata such that
 /// the rustc version can't be found to compare with `rustc_version()`.
 pub const METADATA_VERSION: u8 = 4;
 
@@ -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
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index 2da0ede..5044e35 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -25,4 +25,4 @@
 syntax_pos = { path = "../libsyntax_pos" }
 byteorder = { version = "1.1", features = ["i128"] }
 rustc_apfloat = { path = "../librustc_apfloat" }
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index ba26ed3..598c2f8 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -195,8 +195,8 @@
                 let needs_note = match ty.sty {
                     ty::Closure(id, _) => {
                         let tables = self.infcx.tcx.typeck_tables_of(id);
-                        let node_id = self.infcx.tcx.hir.as_local_node_id(id).unwrap();
-                        let hir_id = self.infcx.tcx.hir.node_to_hir_id(node_id);
+                        let node_id = self.infcx.tcx.hir().as_local_node_id(id).unwrap();
+                        let hir_id = self.infcx.tcx.hir().node_to_hir_id(node_id);
 
                         tables.closure_kind_origins().get(hir_id).is_none()
                     }
@@ -720,13 +720,13 @@
                 format!("`{}` would have to be valid for `{}`...", name, region_name),
             );
 
-            if let Some(fn_node_id) = self.infcx.tcx.hir.as_local_node_id(self.mir_def_id) {
+            if let Some(fn_node_id) = self.infcx.tcx.hir().as_local_node_id(self.mir_def_id) {
                 err.span_label(
                     drop_span,
                     format!(
                         "...but `{}` will be dropped here, when the function `{}` returns",
                         name,
-                        self.infcx.tcx.hir.name(fn_node_id),
+                        self.infcx.tcx.hir().name(fn_node_id),
                     ),
                 );
 
@@ -1064,7 +1064,7 @@
 
         let escapes_from = if tcx.is_closure(self.mir_def_id) {
             let tables = tcx.typeck_tables_of(self.mir_def_id);
-            let mir_hir_id = tcx.hir.def_index_to_hir_id(self.mir_def_id.index);
+            let mir_hir_id = tcx.hir().def_index_to_hir_id(self.mir_def_id.index);
             match tables.node_id_to_type(mir_hir_id).sty {
                 ty::Closure(..) => "closure",
                 ty::Generator(..) => "generator",
@@ -1249,7 +1249,7 @@
     /// (part of) a non-`mut` local that occurs potentially after that
     /// local has already been initialized. `place` is the path being
     /// assigned; `err_place` is a place providing a reason why
-    /// `place` is not mutable (e.g. the non-`mut` local `x` in an
+    /// `place` is not mutable (e.g., the non-`mut` local `x` in an
     /// assignment to `x.f`).
     pub(super) fn report_illegal_reassignment(
         &mut self,
@@ -1412,11 +1412,11 @@
                 );
 
                 if let ty::TyKind::Closure(did, _substs) = self.mir.local_decls[closure].ty.sty {
-                    let node_id = match self.infcx.tcx.hir.as_local_node_id(did) {
+                    let node_id = match self.infcx.tcx.hir().as_local_node_id(did) {
                         Some(node_id) => node_id,
                         _ => return,
                     };
-                    let hir_id = self.infcx.tcx.hir.node_to_hir_id(node_id);
+                    let hir_id = self.infcx.tcx.hir().node_to_hir_id(node_id);
 
                     if let Some((
                         span, name
@@ -1654,12 +1654,12 @@
                     // the local code in the current crate, so this returns an `Option` in case
                     // the closure comes from another crate. But in that case we wouldn't
                     // be borrowck'ing it, so we can just unwrap:
-                    let node_id = self.infcx.tcx.hir.as_local_node_id(def_id).unwrap();
+                    let node_id = self.infcx.tcx.hir().as_local_node_id(def_id).unwrap();
                     let freevar = self.infcx
                         .tcx
                         .with_freevars(node_id, |fv| fv[field.index()]);
 
-                    self.infcx.tcx.hir.name(freevar.var_id()).to_string()
+                    self.infcx.tcx.hir().name(freevar.var_id()).to_string()
                 }
                 _ => {
                     // Might need a revision when the fields in trait RFC is implemented
@@ -1980,8 +1980,8 @@
     ) -> Option<AnnotatedBorrowFnSignature> {
         debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig);
         let is_closure = self.infcx.tcx.is_closure(did);
-        let fn_node_id = self.infcx.tcx.hir.as_local_node_id(did)?;
-        let fn_decl = self.infcx.tcx.hir.fn_decl(fn_node_id)?;
+        let fn_node_id = self.infcx.tcx.hir().as_local_node_id(did)?;
+        let fn_decl = self.infcx.tcx.hir().fn_decl(fn_node_id)?;
 
         // We need to work out which arguments to highlight. We do this by looking
         // at the return type, where there are three cases:
@@ -2423,8 +2423,8 @@
             "closure_span: def_id={:?} target_place={:?} places={:?}",
             def_id, target_place, places
         );
-        let node_id = self.infcx.tcx.hir.as_local_node_id(def_id)?;
-        let expr = &self.infcx.tcx.hir.expect_expr(node_id).node;
+        let node_id = self.infcx.tcx.hir().as_local_node_id(def_id)?;
+        let expr = &self.infcx.tcx.hir().expect_expr(node_id).node;
         debug!("closure_span: node_id={:?} expr={:?}", node_id, expr);
         if let hir::ExprKind::Closure(
             .., args_span, _
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 76ba6ae..e3029c6 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -137,7 +137,7 @@
     let attributes = tcx.get_attrs(def_id);
     let param_env = tcx.param_env(def_id);
     let id = tcx
-        .hir
+        .hir()
         .as_local_node_id(def_id)
         .expect("do_mir_borrowck: non-local DefId");
 
@@ -173,7 +173,7 @@
         |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
     ));
 
-    let locals_are_invalidated_at_exit = match tcx.hir.body_owner_kind(id) {
+    let locals_are_invalidated_at_exit = match tcx.hir().body_owner_kind(id) {
             hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => false,
             hir::BodyOwnerKind::Fn => true,
     };
@@ -229,7 +229,7 @@
         |bd, i| DebugFormatted::new(&bd.move_data().inits[i]),
     ));
 
-    let movable_generator = match tcx.hir.get(id) {
+    let movable_generator = match tcx.hir().get(id) {
         Node::Expr(&hir::Expr {
             node: hir::ExprKind::Closure(.., Some(hir::GeneratorMovability::Static)),
             ..
@@ -1526,7 +1526,7 @@
               // ancestors; dataflow recurs on children when parents
               // move (to support partial (re)inits).
               //
-              // (I.e. querying parents breaks scenario 7; but may want
+              // (I.e., querying parents breaks scenario 7; but may want
               // to do such a query based on partial-init feature-gate.)
         }
     }
@@ -1562,7 +1562,7 @@
         //
         // (Distinct from handling of scenarios 1+2+4 above because
         // `place` does not interfere with suffixes of its prefixes,
-        // e.g. `a.b.c` does not interfere with `a.b.d`)
+        // e.g., `a.b.c` does not interfere with `a.b.d`)
         //
         // This code covers scenario 1.
 
@@ -1735,7 +1735,7 @@
             //
             // This does not use check_if_path_or_subpath_is_moved,
             // because we want to *allow* reinitializations of fields:
-            // e.g. want to allow
+            // e.g., want to allow
             //
             // `let mut s = ...; drop(s.x); s.x=Val;`
             //
@@ -2166,7 +2166,7 @@
     /// `u.a.x` and `a.b.y` are.
     Arbitrary,
     /// The places have the same type, and are either completely disjoint
-    /// or equal - i.e. they can't "partially" overlap as can occur with
+    /// or equal - i.e., they can't "partially" overlap as can occur with
     /// unions. This is the "base case" on which we recur for extensions
     /// of the place.
     EqualOrDisjoint,
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index a556199..fb93c41 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -40,7 +40,7 @@
 #[derive(Debug)]
 enum GroupedMoveError<'tcx> {
     // Place expression can't be moved from,
-    // e.g. match x[0] { s => (), } where x: &[String]
+    // e.g., match x[0] { s => (), } where x: &[String]
     MovesFromPlace {
         original_path: Place<'tcx>,
         span: Span,
@@ -49,7 +49,7 @@
         binds_to: Vec<Local>,
     },
     // Part of a value expression can't be moved from,
-    // e.g. match &String::new() { &x => (), }
+    // e.g., match &String::new() { &x => (), }
     MovesFromValue {
         original_path: Place<'tcx>,
         span: Span,
@@ -319,8 +319,8 @@
                                         let upvar_hir_id =
                                             upvar_decl.var_hir_id.assert_crate_local();
                                         let upvar_node_id =
-                                            self.infcx.tcx.hir.hir_to_node_id(upvar_hir_id);
-                                        let upvar_span = self.infcx.tcx.hir.span(upvar_node_id);
+                                            self.infcx.tcx.hir().hir_to_node_id(upvar_hir_id);
+                                        let upvar_span = self.infcx.tcx.hir().span(upvar_node_id);
                                         diag.span_label(upvar_span, "captured outer variable");
                                         break;
                                     }
@@ -426,13 +426,13 @@
                     .span_to_snippet(pat_span)
                     .unwrap();
                 if pat_snippet.starts_with('&') {
-                    let pat_snippet = pat_snippet[1..].trim_left();
+                    let pat_snippet = pat_snippet[1..].trim_start();
                     let suggestion;
                     let to_remove;
                     if pat_snippet.starts_with("mut")
                         && pat_snippet["mut".len()..].starts_with(Pattern_White_Space)
                     {
-                        suggestion = pat_snippet["mut".len()..].trim_left();
+                        suggestion = pat_snippet["mut".len()..].trim_start();
                         to_remove = "&mut";
                     } else {
                         suggestion = pat_snippet;
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 7afe2c6..ab819aa 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`.
@@ -317,8 +317,8 @@
                 let upvar_hir_id = self.mir.upvar_decls[upvar_index.index()]
                     .var_hir_id
                     .assert_crate_local();
-                let upvar_node_id = self.infcx.tcx.hir.hir_to_node_id(upvar_hir_id);
-                if let Some(Node::Binding(pat)) = self.infcx.tcx.hir.find(upvar_node_id) {
+                let upvar_node_id = self.infcx.tcx.hir().hir_to_node_id(upvar_hir_id);
+                if let Some(Node::Binding(pat)) = self.infcx.tcx.hir().find(upvar_node_id) {
                     if let hir::PatKind::Binding(
                         hir::BindingAnnotation::Unannotated,
                         _,
@@ -641,8 +641,8 @@
         if let ty::TyKind::Adt(def, _) = ty.sty {
             let field = def.all_fields().nth(field.index())?;
             // Use the HIR types to construct the diagnostic message.
-            let node_id = tcx.hir.as_local_node_id(field.did)?;
-            let node = tcx.hir.find(node_id)?;
+            let node_id = tcx.hir().as_local_node_id(field.did)?;
+            let node = tcx.hir().find(node_id)?;
             // Now we're dealing with the actual struct that we're going to suggest a change to,
             // we can expect a field that is an immutable reference to a type.
             if let hir::Node::Field(field) = node {
diff --git a/src/librustc_mir/borrow_check/nll/constraints/mod.rs b/src/librustc_mir/borrow_check/nll/constraints/mod.rs
index a873af8..bfac33b 100644
--- a/src/librustc_mir/borrow_check/nll/constraints/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/constraints/mod.rs
@@ -40,7 +40,7 @@
     /// Constructs a "normal" graph from the constraint set; the graph makes it
     /// easy to find the constraints affecting a particular region.
     ///
-    /// NB: This graph contains a "frozen" view of the current
+    /// N.B., this graph contains a "frozen" view of the current
     /// constraints.  any new constraints added to the `ConstraintSet`
     /// after the graph is built will not be present in the graph.
     crate fn graph(&self, num_region_vars: usize) -> graph::NormalConstraintGraph {
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 477b789..7fb3f02 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -277,13 +277,17 @@
                         borrow_region_vid,
                         region,
                     );
-                let opt_place_desc = self.describe_place(&borrow.borrowed_place);
-                BorrowExplanation::MustBeValidFor {
-                    category,
-                    from_closure,
-                    span,
-                    region_name,
-                    opt_place_desc,
+                if let Some(region_name) = region_name {
+                    let opt_place_desc = self.describe_place(&borrow.borrowed_place);
+                    BorrowExplanation::MustBeValidFor {
+                        category,
+                        from_closure,
+                        span,
+                        region_name,
+                        opt_place_desc,
+                    }
+                } else {
+                    BorrowExplanation::Unexplained
                 }
             } else {
                 BorrowExplanation::Unexplained
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 0c4140c..cd46943 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -176,7 +176,7 @@
     // Dump facts if requested.
     let polonius_output = all_facts.and_then(|all_facts| {
         if infcx.tcx.sess.opts.debugging_opts.nll_facts {
-            let def_path = infcx.tcx.hir.def_path(def_id);
+            let def_path = infcx.tcx.hir().def_path(def_id);
             let dir_path =
                 PathBuf::from("nll-facts").join(def_path.to_filename_friendly_no_crate());
             all_facts.write_to_dir(dir_path, location_table).unwrap();
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
index 3358e58..32aaa05 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
@@ -38,6 +38,7 @@
         match self {
             ConstraintCategory::Assignment => "assignment ",
             ConstraintCategory::Return => "returning this value ",
+            ConstraintCategory::Yield => "yielding this value ",
             ConstraintCategory::UseAsConst => "using this value as a constant ",
             ConstraintCategory::UseAsStatic => "using this value as a static ",
             ConstraintCategory::Cast => "cast ",
@@ -133,11 +134,10 @@
             let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup);
 
             match categorized_path[i].0 {
-                ConstraintCategory::OpaqueType
-                | ConstraintCategory::Boring
-                | ConstraintCategory::BoringNoLocation
-                | ConstraintCategory::Internal => false,
-                ConstraintCategory::TypeAnnotation | ConstraintCategory::Return => true,
+                ConstraintCategory::OpaqueType | ConstraintCategory::Boring |
+                ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false,
+                ConstraintCategory::TypeAnnotation | ConstraintCategory::Return |
+                ConstraintCategory::Yield => true,
                 _ => constraint_sup_scc != target_scc,
             }
         });
@@ -376,9 +376,7 @@
 
         diag.span_label(span, message);
 
-        match self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, &mut 1)
-            .source
-        {
+        match self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, &mut 1).unwrap().source {
             RegionNameSource::NamedEarlyBoundRegion(fr_span)
             | RegionNameSource::NamedFreeRegion(fr_span)
             | RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _)
@@ -521,10 +519,10 @@
         );
 
         let counter = &mut 1;
-        let fr_name = self.give_region_a_name(infcx, mir, mir_def_id, fr, counter);
+        let fr_name = self.give_region_a_name(infcx, mir, mir_def_id, fr, counter).unwrap();
         fr_name.highlight_region_name(&mut diag);
         let outlived_fr_name =
-            self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, counter);
+            self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, counter).unwrap();
         outlived_fr_name.highlight_region_name(&mut diag);
 
         let mir_def_name = if infcx.tcx.is_closure(mir_def_id) {
@@ -661,7 +659,7 @@
         infcx: &InferCtxt<'_, '_, 'tcx>,
         borrow_region: RegionVid,
         outlived_region: RegionVid,
-    ) -> (ConstraintCategory, bool, Span, RegionName) {
+    ) -> (ConstraintCategory, bool, Span, Option<RegionName>) {
         let (category, from_closure, span) =
             self.best_blame_constraint(mir, borrow_region, |r| r == outlived_region);
         let outlived_fr_name =
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index a32fb05..a41d27e 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -157,7 +157,7 @@
         mir_def_id: DefId,
         fr: RegionVid,
         counter: &mut usize,
-    ) -> RegionName {
+    ) -> Option<RegionName> {
         debug!("give_region_a_name(fr={:?}, counter={})", fr, counter);
 
         assert!(self.universal_regions.is_universal_region(fr));
@@ -177,8 +177,7 @@
                 self.give_name_if_anonymous_region_appears_in_output(
                     infcx, mir, mir_def_id, fr, counter,
                 )
-            })
-            .unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr));
+            });
 
         debug!("give_region_a_name: gave name {:?}", value);
         value
@@ -226,12 +225,14 @@
                 },
 
                 ty::BoundRegion::BrEnv => {
-                    let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).expect("non-local mir");
+                    let mir_node_id = tcx.hir()
+                                         .as_local_node_id(mir_def_id)
+                                         .expect("non-local mir");
                     let def_ty = self.universal_regions.defining_ty;
 
                     if let DefiningTy::Closure(def_id, substs) = def_ty {
                         let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) =
-                            tcx.hir.expect_expr(mir_node_id).node
+                            tcx.hir().expect_expr(mir_node_id).node
                         {
                             span
                         } else {
@@ -302,10 +303,10 @@
         name: &InternedString,
     ) -> Span {
         let scope = error_region.free_region_binding_scope(tcx);
-        let node = tcx.hir.as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID);
+        let node = tcx.hir().as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID);
 
-        let span = tcx.sess.source_map().def_span(tcx.hir.span(node));
-        if let Some(param) = tcx.hir
+        let span = tcx.sess.source_map().def_span(tcx.hir().span(node));
+        if let Some(param) = tcx.hir()
             .get_generics(scope)
             .and_then(|generics| generics.get_named(name))
         {
@@ -361,8 +362,8 @@
         argument_index: usize,
         counter: &mut usize,
     ) -> Option<RegionName> {
-        let mir_node_id = infcx.tcx.hir.as_local_node_id(mir_def_id)?;
-        let fn_decl = infcx.tcx.hir.fn_decl(mir_node_id)?;
+        let mir_node_id = infcx.tcx.hir().as_local_node_id(mir_def_id)?;
+        let fn_decl = infcx.tcx.hir().fn_decl(mir_node_id)?;
         let argument_hir_ty: &hir::Ty = &fn_decl.inputs[argument_index];
         match argument_hir_ty.node {
             // This indicates a variable with no type annotation, like
@@ -685,9 +686,9 @@
         let type_name = with_highlight_region_for_regionvid(
             fr, *counter, || infcx.extract_type_name(&return_ty));
 
-        let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).expect("non-local mir");
+        let mir_node_id = tcx.hir().as_local_node_id(mir_def_id).expect("non-local mir");
 
-        let (return_span, mir_description) = match tcx.hir.get(mir_node_id) {
+        let (return_span, mir_description) = match tcx.hir().get(mir_node_id) {
             hir::Node::Expr(hir::Expr {
                 node: hir::ExprKind::Closure(_, _, _, span, gen_move),
                 ..
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs
index 73fa1b0..0c0504b 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs
@@ -81,11 +81,11 @@
         upvar_index: usize,
     ) -> (Symbol, Span) {
         let upvar_hir_id = mir.upvar_decls[upvar_index].var_hir_id.assert_crate_local();
-        let upvar_node_id = tcx.hir.hir_to_node_id(upvar_hir_id);
+        let upvar_node_id = tcx.hir().hir_to_node_id(upvar_hir_id);
         debug!("get_upvar_name_and_span_for_region: upvar_node_id={:?}", upvar_node_id);
 
-        let upvar_name = tcx.hir.name(upvar_node_id);
-        let upvar_span = tcx.hir.span(upvar_node_id);
+        let upvar_name = tcx.hir().name(upvar_node_id);
+        let upvar_span = tcx.hir().span(upvar_node_id);
         debug!("get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}",
                upvar_name, upvar_span);
 
@@ -95,7 +95,7 @@
     /// Search the argument types for one that references fr (which should be a free region).
     /// Returns Some(_) with the index of the input if one is found.
     ///
-    /// NB: In the case of a closure, the index is indexing into the signature as seen by the
+    /// N.B., in the case of a closure, the index is indexing into the signature as seen by the
     /// user - in particular, index 0 is not the implicit self parameter.
     crate fn get_argument_index_for_region(
         &self,
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 fbde699..cbd1e66 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -119,7 +119,7 @@
     external_name: Option<ty::Region<'tcx>>,
 }
 
-/// NB: The variants in `Cause` are intentionally ordered. Lower
+/// N.B., the variants in `Cause` are intentionally ordered. Lower
 /// values are preferred when it comes to error messages. Do not
 /// reorder willy nilly.
 #[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
@@ -657,7 +657,7 @@
                     .buffer(errors_buffer);
             } else {
                 // FIXME. We should handle this case better. It
-                // indicates that we have e.g. some region variable
+                // indicates that we have e.g., some region variable
                 // whose value is like `'a+'b` where `'a` and `'b` are
                 // distinct unrelated univesal regions that are not
                 // known to outlive one another. It'd be nice to have
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs
index 69e2c89..4f5829f 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs
@@ -48,7 +48,7 @@
 
         let mut basic_blocks = IndexVec::with_capacity(num_points);
         for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
-            basic_blocks.extend((0..bb_data.statements.len() + 1).map(|_| bb));
+            basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb));
         }
 
         Self {
@@ -313,7 +313,7 @@
         self.points.insert_all_into_row(r);
     }
 
-    /// Add all elements in `r_from` to `r_to` (because e.g. `r_to:
+    /// Add all elements in `r_from` to `r_to` (because e.g., `r_to:
     /// r_from`).
     crate fn add_region(&mut self, r_to: N, r_from: N) -> bool {
         self.points.union_rows(r_from, r_to)
diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
index 85ea39e..bb890e6 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
@@ -40,7 +40,7 @@
         // If the user explicitly annotated the input types, extract
         // those.
         //
-        // e.g. `|x: FxHashMap<_, &'static u32>| ...`
+        // e.g., `|x: FxHashMap<_, &'static u32>| ...`
         let user_provided_sig;
         if !self.tcx().is_closure(self.mir_def_id) {
             user_provided_sig = None;
@@ -50,7 +50,7 @@
                 None => None,
                 Some(user_provided_poly_sig) => {
                     // Instantiate the canonicalized variables from
-                    // user-provided signature (e.g. the `_` in the code
+                    // user-provided signature (e.g., the `_` in the code
                     // above) with fresh variables.
                     let (poly_sig, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(
                         mir.span,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
index 4b39d58..320422c 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
@@ -23,7 +23,7 @@
     liveness_map: &'me NllLivenessMap,
 
     /// Head of a linked list of **definitions** of each variable --
-    /// definition in this context means assignment, e.g. `x` is
+    /// definition in this context means assignment, e.g., `x` is
     /// defined in `x = y` but not `y`; that first def is the head of
     /// a linked list that lets you enumerate all places the variable
     /// is assigned.
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 5f64dfd..4807abe 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 //! This pass type-checks the MIR to ensure it is not broken.
+
 #![allow(unreachable_code)]
 
 use borrow_check::borrow_set::BorrowSet;
@@ -1467,7 +1468,7 @@
                             value_ty,
                             ty,
                             term_location.to_locations(),
-                            ConstraintCategory::Return,
+                            ConstraintCategory::Yield,
                         ) {
                             span_mirbug!(
                                 self,
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index c54a4f9..97fdb80 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -210,8 +210,8 @@
         param_env: ty::ParamEnv<'tcx>,
     ) -> Self {
         let tcx = infcx.tcx;
-        let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).unwrap();
-        let mir_hir_id = tcx.hir.node_to_hir_id(mir_node_id);
+        let mir_node_id = tcx.hir().as_local_node_id(mir_def_id).unwrap();
+        let mir_hir_id = tcx.hir().node_to_hir_id(mir_node_id);
         UniversalRegionsBuilder {
             infcx,
             mir_def_id,
@@ -485,7 +485,7 @@
         let tcx = self.infcx.tcx;
         let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id);
 
-        match tcx.hir.body_owner_kind(self.mir_node_id) {
+        match tcx.hir().body_owner_kind(self.mir_node_id) {
             BodyOwnerKind::Fn => {
                 let defining_ty = if self.mir_def_id == closure_base_def_id {
                     tcx.type_of(closure_base_def_id)
@@ -780,9 +780,9 @@
                 owner: fn_def_id.index,
                 local_id: *late_bound,
             };
-            let region_node_id = tcx.hir.hir_to_node_id(hir_id);
-            let name = tcx.hir.name(region_node_id).as_interned_str();
-            let region_def_id = tcx.hir.local_def_id(region_node_id);
+            let region_node_id = tcx.hir().hir_to_node_id(hir_id);
+            let name = tcx.hir().name(region_node_id).as_interned_str();
+            let region_def_id = tcx.hir().local_def_id(region_node_id);
             let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
                 scope: fn_def_id,
                 bound_region: ty::BoundRegion::BrNamed(region_def_id, name),
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs
index 715d6e0..eeac915 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/src/librustc_mir/borrow_check/places_conflict.rs
@@ -128,10 +128,10 @@
                         //
                         // There is no *easy* way of comparing the fields
                         // further on, because they might have different types
-                        // (e.g. borrows of `u.a.0` and `u.b.y` where `.0` and
+                        // (e.g., borrows of `u.a.0` and `u.b.y` where `.0` and
                         // `.y` come from different structs).
                         //
-                        // We could try to do some things here - e.g. count
+                        // We could try to do some things here - e.g., count
                         // dereferences - but that's probably not a good
                         // idea, at least for now, so just give up and
                         // report a conflict. This is unsafe code anyway so
@@ -175,14 +175,14 @@
                         // borrowed place (at least in MIR as it is
                         // currently.)
                         //
-                        // e.g. a (mutable) borrow of `a[5]` while we read the
+                        // e.g., a (mutable) borrow of `a[5]` while we read the
                         // array length of `a`.
                         debug!("borrow_conflicts_with_place: implicit field");
                         return false;
                     }
 
                     (ProjectionElem::Deref, _, Shallow(None)) => {
-                        // e.g. a borrow of `*x.y` while we shallowly access `x.y` or some
+                        // e.g., a borrow of `*x.y` while we shallowly access `x.y` or some
                         // prefix thereof - the shallow access can't touch anything behind
                         // the pointer.
                         debug!("borrow_conflicts_with_place: shallow access behind ptr");
@@ -216,7 +216,7 @@
                     | (ProjectionElem::Downcast { .. }, _, _) => {
                         // Recursive case. This can still be disjoint on a
                         // further iteration if this a shallow access and
-                        // there's a deref later on, e.g. a borrow
+                        // there's a deref later on, e.g., a borrow
                         // of `*x.y` while accessing `x`.
                     }
                 }
@@ -251,7 +251,7 @@
 /// the place `a` with a "next" pointer to `a.b`).  Created by
 /// `unroll_place`.
 ///
-/// NB: This particular impl strategy is not the most obvious.  It was
+/// N.B., this particular impl strategy is not the most obvious.  It was
 /// chosen because it makes a measurable difference to NLL
 /// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
 struct PlaceComponents<'p, 'tcx: 'p> {
@@ -277,7 +277,7 @@
 /// Iterator over components; see `PlaceComponents::iter` for more
 /// information.
 ///
-/// NB: This is not a *true* Rust iterator -- the code above just
+/// N.B., this is not a *true* Rust iterator -- the code above just
 /// manually invokes `next`. This is because we (sometimes) want to
 /// keep executing even after `None` has been returned.
 struct PlaceComponentsIter<'p, 'tcx: 'p> {
@@ -384,13 +384,13 @@
         (Place::Projection(pi1), Place::Projection(pi2)) => {
             match (&pi1.elem, &pi2.elem) {
                 (ProjectionElem::Deref, ProjectionElem::Deref) => {
-                    // derefs (e.g. `*x` vs. `*x`) - recur.
+                    // derefs (e.g., `*x` vs. `*x`) - recur.
                     debug!("place_element_conflict: DISJOINT-OR-EQ-DEREF");
                     Overlap::EqualOrDisjoint
                 }
                 (ProjectionElem::Field(f1, _), ProjectionElem::Field(f2, _)) => {
                     if f1 == f2 {
-                        // same field (e.g. `a.y` vs. `a.y`) - recur.
+                        // same field (e.g., `a.y` vs. `a.y`) - recur.
                         debug!("place_element_conflict: DISJOINT-OR-EQ-FIELD");
                         Overlap::EqualOrDisjoint
                     } else {
diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs
index 7d583b4..b759e04 100644
--- a/src/librustc_mir/borrow_check/prefixes.rs
+++ b/src/librustc_mir/borrow_check/prefixes.rs
@@ -91,7 +91,7 @@
 
         // Post-processing `place`: Enqueue any remaining
         // work. Also, `place` may not be a prefix itself, but
-        // may hold one further down (e.g. we never return
+        // may hold one further down (e.g., we never return
         // downcasts here, but may return a base of a downcast).
 
         'cursor: loop {
diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs
index 2ef7161..4df8d66 100644
--- a/src/librustc_mir/build/block.rs
+++ b/src/librustc_mir/build/block.rs
@@ -117,7 +117,7 @@
                     };
                     this.block_context.push(BlockFrame::Statement { ignores_expr_result });
 
-                    // Enter the remainder scope, i.e. the bindings' destruction scope.
+                    // Enter the remainder scope, i.e., the bindings' destruction scope.
                     this.push_scope((remainder_scope, source_info));
                     let_scope_stack.push(remainder_scope);
 
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 18ce7ae..a476165 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! See docs in build/expr/mod.rs
+//! See docs in `build/expr/mod.rs`.
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::Idx;
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index 8eb46a0..0e7305e 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -414,7 +414,7 @@
 
                     // must be handled above or else we get an
                     // infinite loop in the builder; see
-                    // e.g. `ExprKind::VarRef` above
+                    // e.g., `ExprKind::VarRef` above
                     Category::Place => false,
 
                     _ => true,
diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs
index 45235b3..0e9f81b 100644
--- a/src/librustc_mir/build/expr/stmt.rs
+++ b/src/librustc_mir/build/expr/stmt.rs
@@ -16,7 +16,7 @@
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     /// Builds a block of MIR statements to evaluate the HAIR `expr`.
     /// If the original expression was an AST statement,
-    /// (e.g. `some().code(&here());`) then `opt_stmt_span` is the
+    /// (e.g., `some().code(&here());`) then `opt_stmt_span` is the
     /// span of that statement (including its semicolon, if any).
     /// Diagnostics use this span (which may be larger than that of
     /// `expr`) to identify when statement temporaries are dropped.
diff --git a/src/librustc_mir/build/into.rs b/src/librustc_mir/build/into.rs
index 9c8d0b2..3e57c4a 100644
--- a/src/librustc_mir/build/into.rs
+++ b/src/librustc_mir/build/into.rs
@@ -11,7 +11,7 @@
 //! In general, there are a number of things for which it's convenient
 //! to just call `builder.into` and have it emit its result into a
 //! given location. This is basically for expressions or things that can be
-//! wrapped up as expressions (e.g. blocks). To make this ergonomic, we use this
+//! wrapped up as expressions (e.g., blocks). To make this ergonomic, we use this
 //! latter `EvalInto` trait.
 
 use build::{BlockAnd, Builder};
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 342aaf9..7e7c0b1 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -101,7 +101,7 @@
 
         // create binding start block for link them by false edges
         let candidate_count = arms.iter().fold(0, |ac, c| ac + c.patterns.len());
-        let pre_binding_blocks: Vec<_> = (0..candidate_count + 1)
+        let pre_binding_blocks: Vec<_> = (0..=candidate_count)
             .map(|_| self.cfg.start_new_block())
             .collect();
 
@@ -111,7 +111,7 @@
         // pattern, which means there may be more than one candidate
         // *per arm*. These candidates are kept sorted such that the
         // highest priority candidate comes first in the list.
-        // (i.e. same order as in source)
+        // (i.e., same order as in source)
 
         let candidates: Vec<_> = arms.iter()
             .enumerate()
@@ -470,7 +470,7 @@
         );
         let place = Place::Local(local_id);
         let var_ty = self.local_decls[local_id].ty;
-        let hir_id = self.hir.tcx().hir.node_to_hir_id(var);
+        let hir_id = self.hir.tcx().hir().node_to_hir_id(var);
         let region_scope = self.hir.region_scope_tree.var_scope(hir_id.local_id);
         self.schedule_drop(span, region_scope, &place, var_ty, DropKind::Storage);
         place
@@ -479,7 +479,7 @@
     pub fn schedule_drop_for_binding(&mut self, var: NodeId, span: Span, for_guard: ForGuard) {
         let local_id = self.var_local_id(var, for_guard);
         let var_ty = self.local_decls[local_id].ty;
-        let hir_id = self.hir.tcx().hir.node_to_hir_id(var);
+        let hir_id = self.hir.tcx().hir().node_to_hir_id(var);
         let region_scope = self.hir.region_scope_tree.var_scope(hir_id.local_id);
         self.schedule_drop(
             span,
@@ -1384,7 +1384,7 @@
                     // Tricky business: For `ref id` and `ref mut id`
                     // patterns, we want `id` within the guard to
                     // correspond to a temp of type `& &T` or `& &mut
-                    // T` (i.e. a "borrow of a borrow") that is
+                    // T` (i.e., a "borrow of a borrow") that is
                     // implicitly dereferenced.
                     //
                     // To borrow a borrow, we need that inner borrow
diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs
index cfea357..328b330 100644
--- a/src/librustc_mir/build/matches/simplify.rs
+++ b/src/librustc_mir/build/matches/simplify.rs
@@ -26,6 +26,10 @@
 use build::matches::{Ascription, Binding, MatchPair, Candidate};
 use hair::*;
 use rustc::mir::*;
+use rustc::ty;
+use rustc::ty::layout::{Integer, IntegerExt, Size};
+use syntax::attr::{SignedInt, UnsignedInt};
+use rustc::hir::RangeEnd;
 
 use std::mem;
 
@@ -62,6 +66,7 @@
                                  match_pair: MatchPair<'pat, 'tcx>,
                                  candidate: &mut Candidate<'pat, 'tcx>)
                                  -> Result<(), MatchPair<'pat, 'tcx>> {
+        let tcx = self.hir.tcx();
         match *match_pair.pattern.kind {
             PatternKind::AscribeUserType { ref subpattern, ref user_ty, user_ty_span } => {
                 candidate.ascriptions.push(Ascription {
@@ -104,7 +109,34 @@
                 Err(match_pair)
             }
 
-            PatternKind::Range { .. } => {
+            PatternKind::Range { lo, hi, ty, end } => {
+                let range = match ty.sty {
+                    ty::Char => {
+                        Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32)))
+                    }
+                    ty::Int(ity) => {
+                        // FIXME(49937): refactor these bit manipulations into interpret.
+                        let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
+                        let min = 1u128 << (size.bits() - 1);
+                        let max = (1u128 << (size.bits() - 1)) - 1;
+                        Some((min, max, size))
+                    }
+                    ty::Uint(uty) => {
+                        // FIXME(49937): refactor these bit manipulations into interpret.
+                        let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size();
+                        let max = !0u128 >> (128 - size.bits());
+                        Some((0, max, size))
+                    }
+                    _ => None,
+                };
+                if let Some((min, max, sz)) = range {
+                    if let (Some(lo), Some(hi)) = (lo.val.try_to_bits(sz), hi.val.try_to_bits(sz)) {
+                        if lo <= min && (hi > max || hi == max && end == RangeEnd::Included) {
+                            // Irrefutable pattern match.
+                            return Ok(());
+                        }
+                    }
+                }
                 Err(match_pair)
             }
 
diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs
index 9405f43..3ac7bd3 100644
--- a/src/librustc_mir/build/misc.rs
+++ b/src/librustc_mir/build/misc.rs
@@ -22,7 +22,7 @@
     /// Add a new temporary value of type `ty` storing the result of
     /// evaluating `expr`.
     ///
-    /// NB: **No cleanup is scheduled for this temporary.** You should
+    /// N.B., **No cleanup is scheduled for this temporary.** You should
     /// call `schedule_drop` once the temporary is initialized.
     pub fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> {
         let temp = self.local_decls.push(LocalDecl::new_temp(ty, span));
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 90a204c..ab52d9b 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -39,10 +39,10 @@
 
 /// Construct the MIR for a given def-id.
 pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'tcx> {
-    let id = tcx.hir.as_local_node_id(def_id).unwrap();
+    let id = tcx.hir().as_local_node_id(def_id).unwrap();
 
     // Figure out what primary body this item has.
-    let (body_id, return_ty_span) = match tcx.hir.get(id) {
+    let (body_id, return_ty_span) = match tcx.hir().get(id) {
         Node::Variant(variant) =>
             return create_constructor_shim(tcx, id, &variant.node.data),
         Node::StructCtor(ctor) =>
@@ -76,10 +76,10 @@
             (*body_id, ty.span)
         }
         Node::AnonConst(hir::AnonConst { body, id, .. }) => {
-            (*body, tcx.hir.span(*id))
+            (*body, tcx.hir().span(*id))
         }
 
-        _ => span_bug!(tcx.hir.span(id), "can't build MIR for {:?}", def_id),
+        _ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def_id),
     };
 
     tcx.infer_ctxt().enter(|infcx| {
@@ -89,9 +89,9 @@
         } else if let hir::BodyOwnerKind::Fn = cx.body_owner_kind {
             // fetch the fully liberated fn signature (that is, all bound
             // types/lifetimes replaced)
-            let fn_hir_id = tcx.hir.node_to_hir_id(id);
+            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 fn_def_id = tcx.hir().local_def_id(id);
 
             let ty = tcx.type_of(fn_def_id);
             let mut abi = fn_sig.abi;
@@ -121,18 +121,18 @@
                 hir::Unsafety::Unsafe => Safety::FnUnsafe,
             };
 
-            let body = tcx.hir.body(body_id);
+            let body = tcx.hir().body(body_id);
             let explicit_arguments =
                 body.arguments
                     .iter()
                     .enumerate()
                     .map(|(index, arg)| {
-                        let owner_id = tcx.hir.body_owner(body_id);
+                        let owner_id = tcx.hir().body_owner(body_id);
                         let opt_ty_info;
                         let self_arg;
-                        if let Some(ref fn_decl) = tcx.hir.fn_decl(owner_id) {
+                        if let Some(ref fn_decl) = tcx.hir().fn_decl(owner_id) {
                             let ty_hir_id = fn_decl.inputs[index].hir_id;
-                            let ty_span = tcx.hir.span(tcx.hir.hir_to_node_id(ty_hir_id));
+                            let ty_span = tcx.hir().span(tcx.hir().hir_to_node_id(ty_hir_id));
                             opt_ty_info = Some(ty_span);
                             self_arg = if index == 0 && fn_decl.implicit_self.has_implicit_self() {
                                 match fn_decl.implicit_self {
@@ -159,7 +159,7 @@
                     ty::Generator(gen_def_id, gen_substs, ..) =>
                         gen_substs.sig(gen_def_id, tcx),
                     _ =>
-                        span_bug!(tcx.hir.span(id), "generator w/o generator type: {:?}", ty),
+                        span_bug!(tcx.hir().span(id), "generator w/o generator type: {:?}", ty),
                 };
                 (Some(gen_sig.yield_ty), gen_sig.return_ty)
             } else {
@@ -246,7 +246,7 @@
                                      v: &'tcx hir::VariantData)
                                      -> Mir<'tcx>
 {
-    let span = tcx.hir.span(ctor_id);
+    let span = tcx.hir().span(ctor_id);
     if let hir::VariantData::Tuple(ref fields, ctor_id) = *v {
         tcx.infer_ctxt().enter(|infcx| {
             let mut mir = shim::build_adt_ctor(&infcx, ctor_id, fields, span);
@@ -263,7 +263,7 @@
             };
 
             mir_util::dump_mir(tcx, None, "mir_map", &0,
-                               MirSource::item(tcx.hir.local_def_id(ctor_id)),
+                               MirSource::item(tcx.hir().local_def_id(ctor_id)),
                                &mir, |_, _| Ok(()) );
 
             mir
@@ -280,7 +280,7 @@
                                             closure_expr_id: ast::NodeId,
                                             body_id: hir::BodyId)
                                             -> Ty<'tcx> {
-    let closure_expr_hir_id = tcx.hir.node_to_hir_id(closure_expr_id);
+    let closure_expr_hir_id = tcx.hir().node_to_hir_id(closure_expr_id);
     let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_hir_id);
 
     let (closure_def_id, closure_substs) = match closure_ty.sty {
@@ -628,12 +628,7 @@
     // unwind anyway. Don't stop them.
     let attrs = &tcx.get_attrs(fn_def_id);
     match attr::find_unwind_attr(Some(tcx.sess.diagnostic()), attrs) {
-        None => {
-            // FIXME(rust-lang/rust#48251) -- Had to disable
-            // abort-on-panic for backwards compatibility reasons.
-            false
-        }
-
+        None => true,
         Some(UnwindAttr::Allowed) => false,
         Some(UnwindAttr::Aborts) => true,
     }
@@ -662,14 +657,14 @@
     let arguments: Vec<_> = arguments.collect();
 
     let tcx = hir.tcx();
-    let span = tcx.hir.span(fn_id);
+    let span = tcx.hir().span(fn_id);
 
     // Gather the upvars of a closure, if any.
     let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| {
         freevars.iter().map(|fv| {
             let var_id = fv.var_id();
-            let var_hir_id = tcx.hir.node_to_hir_id(var_id);
-            let closure_expr_id = tcx.hir.local_def_id(fn_id);
+            let var_hir_id = tcx.hir().node_to_hir_id(var_id);
+            let closure_expr_id = tcx.hir().local_def_id(fn_id);
             let capture = hir.tables().upvar_capture(ty::UpvarId {
                 var_path: ty::UpvarPath {hir_id: var_hir_id},
                 closure_expr_id: LocalDefId::from_def_id(closure_expr_id),
@@ -684,7 +679,7 @@
                 by_ref,
                 mutability: Mutability::Not,
             };
-            if let Some(Node::Binding(pat)) = tcx.hir.find(var_id) {
+            if let Some(Node::Binding(pat)) = tcx.hir().find(var_id) {
                 if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
                     decl.debug_name = ident.name;
 
@@ -711,7 +706,7 @@
         return_ty_span,
         upvar_decls);
 
-    let fn_def_id = tcx.hir.local_def_id(fn_id);
+    let fn_def_id = tcx.hir().local_def_id(fn_id);
     let call_site_scope = region::Scope {
         id: body.value.hir_id.local_id,
         data: region::ScopeData::CallSite
@@ -754,7 +749,7 @@
         // RustCall pseudo-ABI untuples the last argument.
         spread_arg = Some(Local::new(arguments.len()));
     }
-    let closure_expr_id = tcx.hir.local_def_id(fn_id);
+    let closure_expr_id = tcx.hir().local_def_id(fn_id);
     info!("fn_id {:?} has attrs {:?}", closure_expr_id,
           tcx.get_attrs(closure_expr_id));
 
@@ -769,10 +764,10 @@
     ty_span: Span,
 ) -> Mir<'tcx> {
     let tcx = hir.tcx();
-    let ast_expr = &tcx.hir.body(body_id).value;
+    let ast_expr = &tcx.hir().body(body_id).value;
     let ty = hir.tables().expr_ty_adjusted(ast_expr);
-    let owner_id = tcx.hir.body_owner(body_id);
-    let span = tcx.hir.span(owner_id);
+    let owner_id = tcx.hir().body_owner(body_id);
+    let span = tcx.hir().span(owner_id);
     let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty, ty_span,vec![]);
 
     let mut block = START_BLOCK;
@@ -798,8 +793,8 @@
 fn construct_error<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
                                    body_id: hir::BodyId)
                                    -> Mir<'tcx> {
-    let owner_id = hir.tcx().hir.body_owner(body_id);
-    let span = hir.tcx().hir.span(owner_id);
+    let owner_id = hir.tcx().hir().body_owner(body_id);
+    let span = hir.tcx().hir().span(owner_id);
     let ty = hir.tcx().types.err;
     let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty, span, vec![]);
     let source_info = builder.source_info(span);
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 2a11f24..8c94876 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -152,7 +152,7 @@
 pub(crate) struct CachedBlock {
     /// The cached block for the cleanups-on-diverge path. This block
     /// contains code to run the current drop and all the preceding
-    /// drops (i.e. those having lower index in Drop’s Scope drop
+    /// drops (i.e., those having lower index in Drop’s Scope drop
     /// array)
     unwind: Option<BasicBlock>,
 
@@ -182,7 +182,7 @@
     /// Block to branch into when the loop or block terminates (either by being `break`-en out
     /// from, or by having its condition to become false)
     pub break_block: BasicBlock,
-    /// The destination of the loop/block expression itself (i.e. where to put the result of a
+    /// The destination of the loop/block expression itself (i.e., where to put the result of a
     /// `break` expression)
     pub break_destination: Place<'tcx>,
 }
@@ -322,11 +322,11 @@
             let same_lint_scopes = tcx.dep_graph.with_ignore(|| {
                 let sets = tcx.lint_levels(LOCAL_CRATE);
                 let parent_hir_id =
-                    tcx.hir.definitions().node_to_hir_id(
+                    tcx.hir().definitions().node_to_hir_id(
                         self.source_scope_local_data[source_scope].lint_root
                     );
                 let current_hir_id =
-                    tcx.hir.definitions().node_to_hir_id(node_id);
+                    tcx.hir().definitions().node_to_hir_id(node_id);
                 sets.lint_level_set(parent_hir_id) ==
                     sets.lint_level_set(current_hir_id)
             });
@@ -737,7 +737,7 @@
             //
             // Note that this code iterates scopes from the inner-most to the outer-most,
             // invalidating caches of each scope visited. This way bare minimum of the
-            // caches gets invalidated. i.e. if a new drop is added into the middle scope, the
+            // caches gets invalidated. i.e., if a new drop is added into the middle scope, the
             // cache of outer scpoe stays intact.
             scope.invalidate_cache(!needs_drop, this_scope);
             if this_scope {
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 291b5c1..248c5d2 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -664,7 +664,7 @@
     let cid = key.value;
     let def_id = cid.instance.def.def_id();
 
-    if let Some(id) = tcx.hir.as_local_node_id(def_id) {
+    if let Some(id) = tcx.hir().as_local_node_id(def_id) {
         let tables = tcx.typeck_tables_of(def_id);
 
         // Do match-check before building MIR
@@ -672,7 +672,7 @@
             return Err(ErrorHandled::Reported)
         }
 
-        if let hir::BodyOwnerKind::Const = tcx.hir.body_owner_kind(id) {
+        if let hir::BodyOwnerKind::Const = tcx.hir().body_owner_kind(id) {
             tcx.mir_const_qualif(def_id);
         }
 
@@ -708,7 +708,7 @@
                 // because any code that existed before validation could not have failed validation
                 // thus preventing such a hard error from being a backwards compatibility hazard
                 Some(Def::Const(_)) | Some(Def::AssociatedConst(_)) => {
-                    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+                    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
                     err.report_as_lint(
                         tcx.at(tcx.def_span(def_id)),
                         "any use of this value will cause an error",
@@ -728,7 +728,7 @@
                         err.report_as_lint(
                             tcx.at(span),
                             "reaching this expression at runtime will panic or abort",
-                            tcx.hir.as_local_node_id(def_id).unwrap(),
+                            tcx.hir().as_local_node_id(def_id).unwrap(),
                         )
                     }
                 // anything else (array lengths, enum initializers, constant patterns) are reported
diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs
index d815bfe..52eae58 100644
--- a/src/librustc_mir/dataflow/at_location.rs
+++ b/src/librustc_mir/dataflow/at_location.rs
@@ -67,7 +67,7 @@
 /// effects at any point in the control-flow graph by starting with
 /// the state at the start of the basic block (`reset_to_entry_of`)
 /// and then replaying the effects of statements and terminators
-/// (e.g. via `reconstruct_statement_effect` and
+/// (e.g., via `reconstruct_statement_effect` and
 /// `reconstruct_terminator_effect`; don't forget to call
 /// `apply_local_effect`).
 pub struct FlowAtLocation<BD>
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 3a9e4fc..5e78ef0 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -267,7 +267,7 @@
                         Place::Local(..) | Place::Static(..) => {} // okay
                         Place::Projection(..) => {
                             // ... can assign into projections,
-                            // e.g. `box (&mut _)`. Current
+                            // e.g., `box (&mut _)`. Current
                             // conservative solution: force
                             // immediate activation here.
                             sets.gen(*index);
diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs
index efdf9c3..c29a855 100644
--- a/src/librustc_mir/dataflow/impls/mod.rs
+++ b/src/librustc_mir/dataflow/impls/mod.rs
@@ -488,7 +488,7 @@
                 //
                 // FIXME(#46525): We *need* to do this for StorageLive as well as
                 // StorageDead, because lifetimes of match bindings with guards are
-                // weird - i.e. this code
+                // weird - i.e., this code
                 //
                 // ```
                 //     fn main() {
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index c191456..bd84266 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -290,7 +290,7 @@
 /// It abstracts over the FlowState and also completely hides the
 /// underlying flow analysis results, because it needs to handle cases
 /// where we are combining the results of *multiple* flow analyses
-/// (e.g. borrows + inits + uninits).
+/// (e.g., borrows + inits + uninits).
 pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> {
     type FlowState: FlowsAtLocation;
 
@@ -553,7 +553,7 @@
 /// Parameterization for the precise form of data flow that is used.
 /// `InitialFlow` handles initializing the bitvectors before any
 /// code is inspected by the analysis. Analyses that need more nuanced
-/// initialization (e.g. they need to consult the results of some other
+/// initialization (e.g., they need to consult the results of some other
 /// dataflow analysis to set up the initial bitvectors) should not
 /// implement this.
 pub trait InitialFlow {
@@ -592,7 +592,7 @@
 
     /// A name describing the dataflow analysis that this
     /// BitDenotation is supporting.  The name should be something
-    /// suitable for plugging in as part of a filename e.g. avoid
+    /// suitable for plugging in as part of a filename e.g., avoid
     /// space-characters or other things that tend to look bad on a
     /// file system, like slashes or periods. It is also better for
     /// the name to be reasonably short, again because it will be
@@ -739,7 +739,7 @@
     /// To reflect this, the `propagate_call_return` method of the
     /// `BitDenotation` mutates `in_out` when propagating `in_out` via
     /// a call terminator; such mutation is performed *last*, to
-    /// ensure its side-effects do not leak elsewhere (e.g. into
+    /// ensure its side-effects do not leak elsewhere (e.g., into
     /// unwind target).
     fn propagate_bits_into_graph_successors_of(
         &mut self,
diff --git a/src/librustc_mir/dataflow/move_paths/abs_domain.rs b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
index 4d20857..186e5f5 100644
--- a/src/librustc_mir/dataflow/move_paths/abs_domain.rs
+++ b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
@@ -10,7 +10,7 @@
 
 //! The move-analysis portion of borrowck needs to work in an abstract
 //! domain of lifted Places.  Most of the Place variants fall into a
-//! one-to-one mapping between the concrete and abstract (e.g. a
+//! one-to-one mapping between the concrete and abstract (e.g., a
 //! field-deref on a local-variable, `x.field`, has the same meaning
 //! in both domains). Indexed-Projections are the exception: `a[x]`
 //! needs to be treated as mapping to the same move path as `a[y]` as
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/cx/block.rs b/src/librustc_mir/hair/cx/block.rs
index d56ddcb..beb035d 100644
--- a/src/librustc_mir/hair/cx/block.rs
+++ b/src/librustc_mir/hair/cx/block.rs
@@ -55,9 +55,9 @@
                                 -> Vec<StmtRef<'tcx>> {
     let mut result = vec![];
     for (index, stmt) in stmts.iter().enumerate() {
-        let hir_id = cx.tcx.hir.node_to_hir_id(stmt.node.id());
+        let hir_id = cx.tcx.hir().node_to_hir_id(stmt.node.id());
         let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
-        let stmt_span = StatementSpan(cx.tcx.hir.span(stmt.node.id()));
+        let stmt_span = StatementSpan(cx.tcx.hir().span(stmt.node.id()));
         match stmt.node {
             hir::StmtKind::Expr(ref expr, _) |
             hir::StmtKind::Semi(ref expr, _) => {
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 2e9edf2..a1471ad 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -181,7 +181,7 @@
 
             // To ensure that both implicit and explicit coercions are
             // handled the same way, we insert an extra layer of indirection here.
-            // For explicit casts (e.g. 'foo as *const T'), the source of the 'Use'
+            // For explicit casts (e.g., 'foo as *const T'), the source of the 'Use'
             // will be an ExprKind::Hair with the appropriate cast expression. Here,
             // we make our Use source the generated Cast from the original coercion.
             //
@@ -556,7 +556,7 @@
 
         // Now comes the rote stuff:
         hir::ExprKind::Repeat(ref v, ref count) => {
-            let def_id = cx.tcx.hir.local_def_id(count.id);
+            let def_id = cx.tcx.hir().local_def_id(count.id);
             let substs = Substs::identity_for_item(cx.tcx.global_tcx(), def_id);
             let instance = ty::Instance::resolve(
                 cx.tcx.global_tcx(),
@@ -588,7 +588,7 @@
             match dest.target_id {
                 Ok(target_id) => ExprKind::Break {
                     label: region::Scope {
-                        id: cx.tcx.hir.node_to_hir_id(target_id).local_id,
+                        id: cx.tcx.hir().node_to_hir_id(target_id).local_id,
                         data: region::ScopeData::Node
                     },
                     value: value.to_ref(),
@@ -600,7 +600,7 @@
             match dest.target_id {
                 Ok(loop_id) => ExprKind::Continue {
                     label: region::Scope {
-                        id: cx.tcx.hir.node_to_hir_id(loop_id).local_id,
+                        id: cx.tcx.hir().node_to_hir_id(loop_id).local_id,
                         data: region::ScopeData::Node
                     },
                 },
@@ -974,17 +974,17 @@
                    var_id,
                    index,
                    closure_expr_id);
-            let var_hir_id = cx.tcx.hir.node_to_hir_id(var_id);
+            let var_hir_id = cx.tcx.hir().node_to_hir_id(var_id);
             let var_ty = cx.tables().node_id_to_type(var_hir_id);
 
             // FIXME free regions in closures are not right
             let closure_ty = cx.tables()
-                               .node_id_to_type(cx.tcx.hir.node_to_hir_id(closure_expr_id));
+                               .node_id_to_type(cx.tcx.hir().node_to_hir_id(closure_expr_id));
 
             // FIXME we're just hard-coding the idea that the
             // signature will be &self or &mut self and hence will
             // have a bound region with number 0
-            let closure_def_id = cx.tcx.hir.local_def_id(closure_expr_id);
+            let closure_def_id = cx.tcx.hir().local_def_id(closure_expr_id);
             let region = ty::ReFree(ty::FreeRegion {
                 scope: closure_def_id,
                 bound_region: ty::BoundRegion::BrAnon(0),
@@ -1176,10 +1176,10 @@
                                    freevar: &hir::Freevar,
                                    freevar_ty: Ty<'tcx>)
                                    -> ExprRef<'tcx> {
-    let var_hir_id = cx.tcx.hir.node_to_hir_id(freevar.var_id());
+    let var_hir_id = cx.tcx.hir().node_to_hir_id(freevar.var_id());
     let upvar_id = ty::UpvarId {
         var_path: ty::UpvarPath { hir_id: var_hir_id },
-        closure_expr_id: cx.tcx.hir.local_def_id(closure_expr.id).to_local(),
+        closure_expr_id: cx.tcx.hir().local_def_id(closure_expr.id).to_local(),
     };
     let upvar_capture = cx.tables().upvar_capture(upvar_id);
     let temp_lifetime = cx.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id);
@@ -1212,7 +1212,7 @@
     }
 }
 
-/// Converts a list of named fields (i.e. for struct-like struct/enum ADTs) into FieldExprRef.
+/// Converts a list of named fields (i.e., for struct-like struct/enum ADTs) into FieldExprRef.
 fn field_refs<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                               fields: &'tcx [hir::Field])
                               -> Vec<FieldExprRef<'tcx>> {
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index c414088..a0b2d99 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -62,8 +62,8 @@
     pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
                src_id: ast::NodeId) -> Cx<'a, 'gcx, 'tcx> {
         let tcx = infcx.tcx;
-        let src_def_id = tcx.hir.local_def_id(src_id);
-        let body_owner_kind = tcx.hir.body_owner_kind(src_id);
+        let src_def_id = tcx.hir().local_def_id(src_id);
+        let body_owner_kind = tcx.hir().body_owner_kind(src_id);
 
         let constness = match body_owner_kind {
             hir::BodyOwnerKind::Const |
@@ -71,7 +71,7 @@
             hir::BodyOwnerKind::Fn => hir::Constness::NotConst,
         };
 
-        let attrs = tcx.hir.attrs(src_id);
+        let attrs = tcx.hir().attrs(src_id);
 
         // Some functions always have overflow checks enabled,
         // however, they may not get codegen'd, depending on
@@ -157,7 +157,7 @@
 
     pub fn pattern_from_hir(&mut self, p: &hir::Pat) -> Pattern<'tcx> {
         let tcx = self.tcx.global_tcx();
-        let p = match tcx.hir.get(p.id) {
+        let p = match tcx.hir().get(p.id) {
             Node::Pat(p) | Node::Binding(p) => p,
             node => bug!("pattern became {:?}", node)
         };
@@ -202,7 +202,7 @@
     }
 
     fn lint_level_of(&self, node_id: ast::NodeId) -> LintLevel {
-        let hir_id = self.tcx.hir.definitions().node_to_hir_id(node_id);
+        let hir_id = self.tcx.hir().definitions().node_to_hir_id(node_id);
         let has_lint_level = self.tcx.dep_graph.with_ignore(|| {
             self.tcx.lint_levels(LOCAL_CRATE).lint_level_set(hir_id).is_some()
         });
@@ -253,11 +253,11 @@
     tcx.dep_graph.with_ignore(|| {
         let sets = tcx.lint_levels(LOCAL_CRATE);
         loop {
-            let hir_id = tcx.hir.definitions().node_to_hir_id(id);
+            let hir_id = tcx.hir().definitions().node_to_hir_id(id);
             if sets.lint_level_set(hir_id).is_some() {
                 return id
             }
-            let next = tcx.hir.get_parent_node(id);
+            let next = tcx.hir().get_parent_node(id);
             if next == id {
                 bug!("lint traversal reached the root of the crate");
             }
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 0570cd2..5cfcc16 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -29,9 +29,9 @@
 ///
 /// If we have this predicate, then we can easily compute both exhaustiveness of an
 /// entire set of patterns and the individual usefulness of each one.
-/// (a) the set of patterns is exhaustive iff `U(P, _)` is false (i.e. adding a wildcard
+/// (a) the set of patterns is exhaustive iff `U(P, _)` is false (i.e., adding a wildcard
 /// match doesn't increase the number of values we're matching)
-/// (b) a pattern `p_i` is not useful if `U(P[0..=(i-1), p_i)` is false (i.e. adding a
+/// (b) a pattern `p_i` is not useful if `U(P[0..=(i-1), p_i)` is false (i.e., adding a
 /// pattern to those that have come before it doesn't increase the number of values
 /// we're matching).
 ///
@@ -90,17 +90,17 @@
 ///
 /// The algorithm for computing `U`
 /// -------------------------------
-/// The algorithm is inductive (on the number of columns: i.e. components of tuple patterns).
+/// The algorithm is inductive (on the number of columns: i.e., components of tuple patterns).
 /// That means we're going to check the components from left-to-right, so the algorithm
 /// operates principally on the first component of the matrix and new pattern `p_{m + 1}`.
 /// This algorithm is realised in the `is_useful` function.
 ///
-/// Base case. (`n = 0`, i.e. an empty tuple pattern)
-///     - If `P` already contains an empty pattern (i.e. if the number of patterns `m > 0`),
+/// Base case. (`n = 0`, i.e., an empty tuple pattern)
+///     - If `P` already contains an empty pattern (i.e., if the number of patterns `m > 0`),
 ///       then `U(P, p_{m + 1})` is false.
 ///     - Otherwise, `P` must be empty, so `U(P, p_{m + 1})` is true.
 ///
-/// Inductive step. (`n > 0`, i.e. whether there's at least one column
+/// Inductive step. (`n > 0`, i.e., whether there's at least one column
 ///                  [which may then be expanded into further columns later])
 ///     We're going to match on the new pattern, `p_{m + 1}`.
 ///         - If `p_{m + 1} == c(r_1, .., r_a)`, then we have a constructor pattern.
@@ -113,7 +113,7 @@
 ///             + All the constructors of the first component of the type exist within
 ///               all the rows (after having expanded OR-patterns). In this case:
 ///               `U(P, p_{m + 1}) := ∨(k ϵ constructors) U(S(k, P), S(k, p_{m + 1}))`
-///               I.e. the pattern `p_{m + 1}` is only useful when all the constructors are
+///               I.e., the pattern `p_{m + 1}` is only useful when all the constructors are
 ///               present *if* its later components are useful for the respective constructors
 ///               covered by `p_{m + 1}` (usually a single constructor, but all in the case of `_`).
 ///             + Some constructors are not present in the existing rows (after having expanded
@@ -156,14 +156,14 @@
 /// - When we're testing for usefulness of a pattern and the pattern's first component is a
 ///   wildcard.
 ///     + If all the constructors appear in the matrix, we have a slight complication. By default,
-///       the behaviour (i.e. a disjunction over specialised matrices for each constructor) is
+///       the behaviour (i.e., a disjunction over specialised matrices for each constructor) is
 ///       invalid, because we want a disjunction over every *integer* in each range, not just a
 ///       disjunction over every range. This is a bit more tricky to deal with: essentially we need
 ///       to form equivalence classes of subranges of the constructor range for which the behaviour
 ///       of the matrix `P` and new pattern `p_{m + 1}` are the same. This is described in more
 ///       detail in `split_grouped_constructors`.
 ///     + If some constructors are missing from the matrix, it turns out we don't need to do
-///       anything special (because we know none of the integers are actually wildcards: i.e. we
+///       anything special (because we know none of the integers are actually wildcards: i.e., we
 ///       can't span wildcards using ranges).
 
 use self::Constructor::*;
@@ -178,11 +178,11 @@
 
 use rustc::hir::def_id::DefId;
 use rustc::hir::RangeEnd;
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc::ty::layout::{Integer, IntegerExt, VariantIdx};
+use rustc::ty::{self, Ty, TyCtxt, TypeFoldable, Const};
+use rustc::ty::layout::{Integer, IntegerExt, VariantIdx, Size};
 
 use rustc::mir::Field;
-use rustc::mir::interpret::ConstValue;
+use rustc::mir::interpret::{ConstValue, Pointer, Scalar};
 use rustc::util::common::ErrorReported;
 
 use syntax::attr::{SignedInt, UnsignedInt};
@@ -190,6 +190,7 @@
 
 use arena::TypedArena;
 
+use smallvec::{SmallVec, smallvec};
 use std::cmp::{self, Ordering, min, max};
 use std::fmt;
 use std::iter::{FromIterator, IntoIterator};
@@ -199,14 +200,60 @@
 pub fn expand_pattern<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>, pat: Pattern<'tcx>)
                                 -> &'a Pattern<'tcx>
 {
-    cx.pattern_arena.alloc(LiteralExpander.fold_pattern(&pat))
+    cx.pattern_arena.alloc(LiteralExpander { tcx: cx.tcx }.fold_pattern(&pat))
 }
 
-struct LiteralExpander;
-impl<'tcx> PatternFolder<'tcx> for LiteralExpander {
+struct LiteralExpander<'a, 'tcx> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>
+}
+
+impl<'a, 'tcx> LiteralExpander<'a, 'tcx> {
+    /// Derefs `val` and potentially unsizes the value if `crty` is an array and `rty` a slice.
+    ///
+    /// `crty` and `rty` can differ because you can use array constants in the presence of slice
+    /// patterns. So the pattern may end up being a slice, but the constant is an array. We convert
+    /// the array to a slice in that case.
+    fn fold_const_value_deref(
+        &mut self,
+        val: ConstValue<'tcx>,
+        // the pattern's pointee type
+        rty: Ty<'tcx>,
+        // the constant's pointee type
+        crty: Ty<'tcx>,
+    ) -> ConstValue<'tcx> {
+        match (val, &crty.sty, &rty.sty) {
+            // the easy case, deref a reference
+            (ConstValue::Scalar(Scalar::Ptr(p)), x, y) if x == y => ConstValue::ByRef(
+                p.alloc_id,
+                self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id),
+                p.offset,
+            ),
+            // unsize array to slice if pattern is array but match value or other patterns are slice
+            (ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => {
+                assert_eq!(t, u);
+                ConstValue::ScalarPair(
+                    Scalar::Ptr(p),
+                    n.val.try_to_scalar().unwrap(),
+                )
+            },
+            // fat pointers stay the same
+            (ConstValue::ScalarPair(..), _, _) => val,
+            // FIXME(oli-obk): this is reachable for `const FOO: &&&u32 = &&&42;` being used
+            _ => bug!("cannot deref {:#?}, {} -> {}", val, crty, rty),
+        }
+    }
+}
+
+impl<'a, 'tcx> PatternFolder<'tcx> for LiteralExpander<'a, 'tcx> {
     fn fold_pattern(&mut self, pat: &Pattern<'tcx>) -> Pattern<'tcx> {
         match (&pat.ty.sty, &*pat.kind) {
-            (&ty::Ref(_, rty, _), &PatternKind::Constant { ref value }) => {
+            (
+                &ty::Ref(_, rty, _),
+                &PatternKind::Constant { value: Const {
+                    val,
+                    ty: ty::TyS { sty: ty::Ref(_, crty, _), .. },
+                } },
+            ) => {
                 Pattern {
                     ty: pat.ty,
                     span: pat.span,
@@ -214,7 +261,11 @@
                         subpattern: Pattern {
                             ty: rty,
                             span: pat.span,
-                            kind: box PatternKind::Constant { value: value.clone() },
+                            kind: box PatternKind::Constant { value: Const::from_const_value(
+                                self.tcx,
+                                self.fold_const_value_deref(*val, rty, crty),
+                                rty,
+                            ) },
                         }
                     }
                 }
@@ -237,14 +288,16 @@
     }
 }
 
-pub struct Matrix<'a, 'tcx: 'a>(Vec<Vec<&'a Pattern<'tcx>>>);
+/// A 2D matrix. Nx1 matrices are very common, which is why `SmallVec[_; 2]`
+/// works well for each row.
+pub struct Matrix<'p, 'tcx: 'p>(Vec<SmallVec<[&'p Pattern<'tcx>; 2]>>);
 
-impl<'a, 'tcx> Matrix<'a, 'tcx> {
+impl<'p, 'tcx> Matrix<'p, 'tcx> {
     pub fn empty() -> Self {
         Matrix(vec![])
     }
 
-    pub fn push(&mut self, row: Vec<&'a Pattern<'tcx>>) {
+    pub fn push(&mut self, row: SmallVec<[&'p Pattern<'tcx>; 2]>) {
         self.0.push(row)
     }
 }
@@ -261,7 +314,7 @@
 /// ++++++++++++++++++++++++++
 /// + _     + [_, _, ..tail] +
 /// ++++++++++++++++++++++++++
-impl<'a, 'tcx> fmt::Debug for Matrix<'a, 'tcx> {
+impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "\n")?;
 
@@ -293,8 +346,9 @@
     }
 }
 
-impl<'a, 'tcx> FromIterator<Vec<&'a Pattern<'tcx>>> for Matrix<'a, 'tcx> {
-    fn from_iter<T: IntoIterator<Item=Vec<&'a Pattern<'tcx>>>>(iter: T) -> Self
+impl<'p, 'tcx> FromIterator<SmallVec<[&'p Pattern<'tcx>; 2]>> for Matrix<'p, 'tcx> {
+    fn from_iter<T>(iter: T) -> Self
+        where T: IntoIterator<Item=SmallVec<[&'p Pattern<'tcx>; 2]>>
     {
         Matrix(iter.into_iter().collect())
     }
@@ -371,7 +425,7 @@
 #[derive(Clone, Debug, PartialEq)]
 pub enum Constructor<'tcx> {
     /// The constructor of all patterns that don't vary by constructor,
-    /// e.g. struct patterns and fixed-length arrays.
+    /// e.g., struct patterns and fixed-length arrays.
     Single,
     /// Enum variants.
     Variant(DefId),
@@ -488,7 +542,7 @@
     /// patterns expanded by the specialization step.
     ///
     /// When a pattern P is discovered to be useful, this function is used bottom-up
-    /// to reconstruct a complete witness, e.g. a pattern P' that covers a subset
+    /// to reconstruct a complete witness, e.g., a pattern P' that covers a subset
     /// of values, V, where each value in that set is not covered by any previously
     /// used patterns and is covered by the pattern P'. Examples:
     ///
@@ -584,7 +638,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| {
@@ -614,7 +667,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,
@@ -629,14 +682,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);
@@ -729,15 +782,17 @@
     for row in patterns {
         match *row.kind {
             PatternKind::Constant { value } => {
-                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);
-                    if is_array_ptr {
-                        let alloc = cx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
-                        max_fixed_len = cmp::max(max_fixed_len, alloc.bytes.len() as u64);
-                    }
+                // extract the length of an array/slice from a constant
+                match (value.val, &value.ty.sty) {
+                    (_, ty::Array(_, n)) => max_fixed_len = cmp::max(
+                        max_fixed_len,
+                        n.unwrap_usize(cx.tcx),
+                    ),
+                    (ConstValue::ScalarPair(_, n), ty::Slice(_)) => max_fixed_len = cmp::max(
+                        max_fixed_len,
+                        n.to_usize(&cx.tcx).unwrap(),
+                    ),
+                    _ => {},
                 }
             }
             PatternKind::Slice { ref prefix, slice: None, ref suffix } => {
@@ -764,7 +819,7 @@
 /// straightforward. See `signed_bias` for details.
 ///
 /// `IntRange` is never used to encode an empty range or a "range" that wraps
-/// around the (offset) space: i.e. `range.lo <= range.hi`.
+/// around the (offset) space: i.e., `range.lo <= range.hi`.
 #[derive(Clone)]
 struct IntRange<'tcx> {
     pub range: RangeInclusive<u128>,
@@ -775,8 +830,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);
@@ -789,7 +853,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);
@@ -799,9 +863,7 @@
                     None
                 }
             }
-            Single | Variant(_) | Slice(_) => {
-                None
-            }
+            _ => None,
         }
     }
 
@@ -848,7 +910,7 @@
     }
 
     /// Return a collection of ranges that spans the values covered by `ranges`, subtracted
-    /// by the values covered by `self`: i.e. `ranges \ self` (in set notation).
+    /// by the values covered by `self`: i.e., `ranges \ self` (in set notation).
     fn subtract_from(self,
                      tcx: TyCtxt<'_, 'tcx, 'tcx>,
                      ranges: Vec<Constructor<'tcx>>)
@@ -933,12 +995,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
@@ -994,7 +1054,7 @@
 /// matrix isn't exhaustive).
 pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                                        matrix: &Matrix<'p, 'tcx>,
-                                       v: &[&'p Pattern<'tcx>],
+                                       v: &[&Pattern<'tcx>],
                                        witness: WitnessPreference)
                                        -> Usefulness<'tcx> {
     let &Matrix(ref rows) = matrix;
@@ -1094,7 +1154,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| {
@@ -1103,7 +1164,7 @@
         } else {
             let matrix = rows.iter().filter_map(|r| {
                 if r[0].is_wildcard() {
-                    Some(r[1..].to_vec())
+                    Some(SmallVec::from_slice(&r[1..]))
                 } else {
                     None
                 }
@@ -1117,7 +1178,7 @@
                     //
                     // There are 2 ways we can report a witness here.
                     // Commonly, we can report all the "free"
-                    // constructors as witnesses, e.g. if we have:
+                    // constructors as witnesses, e.g., if we have:
                     //
                     // ```
                     //     enum Direction { N, S, E, W }
@@ -1132,7 +1193,7 @@
                     // 1) If the user is matching against a non-exhaustive
                     // enum, there is no point in enumerating all possible
                     // variants, because the user can't actually match
-                    // against them himself, e.g. in an example like:
+                    // against them himself, e.g., in an example like:
                     // ```
                     //     let err: io::ErrorKind = ...;
                     //     match err {
@@ -1146,7 +1207,7 @@
                     // case).
                     //
                     // 2) If the user didn't actually specify a constructor
-                    // in this arm, e.g. in
+                    // in this arm, e.g., in
                     // ```
                     //     let x: (Direction, Direction, bool) = ...;
                     //     let (_, _, false) = x;
@@ -1192,12 +1253,12 @@
     }
 }
 
-/// A shorthand for the `U(S(c, P), S(c, q))` operation from the paper. I.e. `is_useful` applied
+/// A shorthand for the `U(S(c, P), S(c, q))` operation from the paper. I.e., `is_useful` applied
 /// to the specialised version of both the pattern matrix `P` and the new pattern `q`.
-fn is_useful_specialized<'p, 'a:'p, 'tcx: 'a>(
+fn is_useful_specialized<'p, 'a: 'p, 'tcx: 'a>(
     cx: &mut MatchCheckCtxt<'a, 'tcx>,
     &Matrix(ref m): &Matrix<'p, 'tcx>,
-    v: &[&'p Pattern<'tcx>],
+    v: &[&Pattern<'tcx>],
     ctor: Constructor<'tcx>,
     lty: Ty<'tcx>,
     witness: WitnessPreference,
@@ -1339,28 +1400,62 @@
     }
 }
 
-fn slice_pat_covered_by_constructor<'tcx>(
+// checks whether a constant is equal to a user-written slice pattern. Only supports byte slices,
+// meaning all other types will compare unequal and thus equal patterns often do not cause the
+// second pattern to lint about unreachable match arms.
+fn slice_pat_covered_by_const<'tcx>(
     tcx: TyCtxt<'_, 'tcx, '_>,
     _span: Span,
-    ctor: &Constructor,
+    const_val: &ty::Const<'tcx>,
     prefix: &[Pattern<'tcx>],
     slice: &Option<Pattern<'tcx>>,
     suffix: &[Pattern<'tcx>]
 ) -> Result<bool, ErrorReported> {
-    let data: &[u8] = match *ctor {
-        ConstantValue(const_val) => {
-            let val = match const_val.val {
-                ConstValue::Unevaluated(..) |
-                ConstValue::ByRef(..) => bug!("unexpected ConstValue: {:?}", const_val),
-                ConstValue::Scalar(val) | ConstValue::ScalarPair(val, _) => val,
-            };
-            if let Ok(ptr) = val.to_ptr() {
-                tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id).bytes.as_ref()
-            } else {
-                bug!("unexpected non-ptr ConstantValue")
+    let data: &[u8] = match (const_val.val, &const_val.ty.sty) {
+        (ConstValue::ByRef(id, alloc, offset), ty::Array(t, n)) => {
+            if *t != tcx.types.u8 {
+                // FIXME(oli-obk): can't mix const patterns with slice patterns and get
+                // any sort of exhaustiveness/unreachable check yet
+                // This solely means that we don't lint about unreachable patterns, even if some
+                // are definitely unreachable.
+                return Ok(false);
             }
-        }
-        _ => bug!()
+            let ptr = Pointer::new(id, offset);
+            let n = n.assert_usize(tcx).unwrap();
+            alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap()
+        },
+        // a slice fat pointer to a zero length slice
+        (ConstValue::ScalarPair(Scalar::Bits { .. }, n), ty::Slice(t)) => {
+            if *t != tcx.types.u8 {
+                // FIXME(oli-obk): can't mix const patterns with slice patterns and get
+                // any sort of exhaustiveness/unreachable check yet
+                // This solely means that we don't lint about unreachable patterns, even if some
+                // are definitely unreachable.
+                return Ok(false);
+            }
+            assert_eq!(n.to_usize(&tcx).unwrap(), 0);
+            &[]
+        },
+        //
+        (ConstValue::ScalarPair(Scalar::Ptr(ptr), n), ty::Slice(t)) => {
+            if *t != tcx.types.u8 {
+                // FIXME(oli-obk): can't mix const patterns with slice patterns and get
+                // any sort of exhaustiveness/unreachable check yet
+                // This solely means that we don't lint about unreachable patterns, even if some
+                // are definitely unreachable.
+                return Ok(false);
+            }
+            let n = n.to_usize(&tcx).unwrap();
+            tcx.alloc_map
+                .lock()
+                .unwrap_memory(ptr.alloc_id)
+                .get_bytes(&tcx, ptr, Size::from_bytes(n))
+                .unwrap()
+        },
+        _ => bug!(
+            "slice_pat_covered_by_const: {:#?}, {:#?}, {:#?}, {:#?}",
+            const_val, prefix, slice, suffix,
+        ),
     };
 
     let pat_len = prefix.len() + suffix.len();
@@ -1390,17 +1485,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
@@ -1409,7 +1503,7 @@
 /// the groups (the ranges). Thus we need to split the groups up. Splitting them up naïvely would
 /// mean creating a separate constructor for every single value in the range, which is clearly
 /// impractical. However, observe that for some ranges of integers, the specialisation will be
-/// identical across all values in that range (i.e. there are equivalence classes of ranges of
+/// identical across all values in that range (i.e., there are equivalence classes of ranges of
 /// constructors based on their `is_useful_specialized` outcome). These classes are grouped by
 /// the patterns that apply to them (in the matrix `P`). We can split the range whenever the
 /// patterns that apply to that range (specifically: the patterns that *intersect* with that range)
@@ -1418,7 +1512,7 @@
 /// the group of intersecting patterns changes (using the method described below).
 /// And voilà! We're testing precisely those ranges that we need to, without any exhaustive matching
 /// on actual integers. The nice thing about this is that the number of subranges is linear in the
-/// number of rows in the matrix (i.e. the number of cases in the `match` statement), so we don't
+/// number of rows in the matrix (i.e., the number of cases in the `match` statement), so we don't
 /// need to be worried about matching over gargantuan ranges.
 ///
 /// Essentially, given the first column of a matrix representing ranges, looking like the following:
@@ -1517,7 +1611,7 @@
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     ctor: &Constructor<'tcx>,
     pat: &'p Pattern<'tcx>,
-) -> Option<Vec<&'p Pattern<'tcx>>> {
+) -> Option<SmallVec<[&'p Pattern<'tcx>; 2]>> {
     if should_treat_range_exhaustively(tcx, ctor) {
         match (IntRange::from_ctor(tcx, ctor), IntRange::from_pat(tcx, pat)) {
             (Some(ctor), Some(pat)) => {
@@ -1525,7 +1619,7 @@
                     let (pat_lo, pat_hi) = pat.range.into_inner();
                     let (ctor_lo, ctor_hi) = ctor.range.into_inner();
                     assert!(pat_lo <= ctor_lo && ctor_hi <= pat_hi);
-                    vec![]
+                    smallvec![]
                 })
             }
             _ => None,
@@ -1535,7 +1629,7 @@
         // conveniently handled by `IntRange`. For these cases, the constructor may not be a range
         // so intersection actually devolves into being covered by the pattern.
         match constructor_covered_by_range(tcx, ctor, pat) {
-            Ok(true) => Some(vec![]),
+            Ok(true) => Some(smallvec![]),
             Ok(false) | Err(ErrorReported) => None,
         }
     }
@@ -1606,9 +1700,9 @@
 fn patterns_for_variant<'p, 'a: 'p, 'tcx: 'a>(
     subpatterns: &'p [FieldPattern<'tcx>],
     wild_patterns: &[&'p Pattern<'tcx>])
-    -> Vec<&'p Pattern<'tcx>>
+    -> SmallVec<[&'p Pattern<'tcx>; 2]>
 {
-    let mut result = wild_patterns.to_owned();
+    let mut result = SmallVec::from_slice(wild_patterns);
 
     for subpat in subpatterns {
         result[subpat.field.index()] = &subpat.pattern;
@@ -1631,15 +1725,16 @@
     r: &[&'p Pattern<'tcx>],
     constructor: &Constructor<'tcx>,
     wild_patterns: &[&'p Pattern<'tcx>],
-) -> Option<Vec<&'p Pattern<'tcx>>> {
+) -> Option<SmallVec<[&'p Pattern<'tcx>; 2]>> {
     let pat = &r[0];
 
-    let head: Option<Vec<&Pattern>> = match *pat.kind {
-        PatternKind::AscribeUserType { ref subpattern, .. } =>
-            specialize(cx, ::std::slice::from_ref(&subpattern), constructor, wild_patterns),
+    let head = match *pat.kind {
+        PatternKind::AscribeUserType { ref subpattern, .. } => {
+            specialize(cx, ::std::slice::from_ref(&subpattern), constructor, wild_patterns)
+        }
 
         PatternKind::Binding { .. } | PatternKind::Wild => {
-            Some(wild_patterns.to_owned())
+            Some(SmallVec::from_slice(wild_patterns))
         }
 
         PatternKind::Variant { adt_def, variant_index, ref subpatterns, .. } => {
@@ -1656,7 +1751,7 @@
         }
 
         PatternKind::Deref { ref subpattern } => {
-            Some(vec![subpattern])
+            Some(smallvec![subpattern])
         }
 
         PatternKind::Constant { value } => {
@@ -1666,22 +1761,23 @@
                     // 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,
-                                ),
-                            }
-                        },
+                    let (opt_ptr, n, ty) = match (value.val, &value.ty.sty) {
+                        (ConstValue::ByRef(id, alloc, offset), ty::TyKind::Array(t, n)) => (
+                            Some((
+                                Pointer::new(id, offset),
+                                alloc,
+                            )),
+                            n.unwrap_usize(cx.tcx),
+                            t,
+                        ),
+                        (ConstValue::ScalarPair(ptr, n), ty::TyKind::Slice(t)) => (
+                            ptr.to_ptr().ok().map(|ptr| (
+                                ptr,
+                                cx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id),
+                            )),
+                            n.to_bits(cx.tcx.data_layout.pointer_size).unwrap() as u64,
+                            t,
+                        ),
                         _ => span_bug!(
                             pat.span,
                             "unexpected const-val {:?} with ctor {:?}",
@@ -1692,9 +1788,8 @@
                     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);
+                            (0, _) => Some(SmallVec::new()),
+                            (_, Some((ptr, alloc))) => {
                                 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()?;
@@ -1757,11 +1852,9 @@
                         None
                     }
                 }
-                ConstantValue(..) => {
-                    match slice_pat_covered_by_constructor(
-                        cx.tcx, pat.span, constructor, prefix, slice, suffix
-                            ) {
-                        Ok(true) => Some(vec![]),
+                ConstantValue(cv) => {
+                    match slice_pat_covered_by_const(cx.tcx, pat.span, cv, prefix, slice, suffix) {
+                        Ok(true) => Some(smallvec![]),
                         Ok(false) => None,
                         Err(ErrorReported) => None
                     }
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index db6d9b6..bfa2e53 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -31,6 +31,7 @@
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::{self, Pat, PatKind};
 
+use smallvec::smallvec;
 use std::slice;
 
 use syntax::ast;
@@ -41,18 +42,18 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_body(&mut self, body: &'tcx hir::Body) {
         intravisit::walk_body(self, body);
-        let def_id = self.tcx.hir.body_owner_def_id(body.id());
+        let def_id = self.tcx.hir().body_owner_def_id(body.id());
         let _ = self.tcx.check_match(def_id);
     }
 }
 
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    tcx.hir.krate().visit_all_item_likes(&mut OuterVisitor { tcx }.as_deep_visitor());
+    tcx.hir().krate().visit_all_item_likes(&mut OuterVisitor { tcx }.as_deep_visitor());
     tcx.sess.abort_if_errors();
 }
 
@@ -60,8 +61,8 @@
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     def_id: DefId,
 ) -> Result<(), ErrorReported> {
-    let body_id = if let Some(id) = tcx.hir.as_local_node_id(def_id) {
-        tcx.hir.body_owned_by(id)
+    let body_id = if let Some(id) = tcx.hir().as_local_node_id(def_id) {
+        tcx.hir().body_owned_by(id)
     } else {
         return Ok(());
     };
@@ -73,7 +74,7 @@
             region_scope_tree: &tcx.region_scope_tree(def_id),
             param_env: tcx.param_env(def_id),
             identity_substs: Substs::identity_for_item(tcx, def_id),
-        }.visit_body(tcx.hir.body(body_id));
+        }.visit_body(tcx.hir().body(body_id));
     })
 }
 
@@ -188,11 +189,11 @@
 
             // Third, perform some lints.
             for pat in &arm.pats {
-                check_for_bindings_named_the_same_as_variants(self, pat);
+                check_for_bindings_named_same_as_variants(self, pat);
             }
         }
 
-        let module = self.tcx.hir.get_module_parent(scrut.id);
+        let module = self.tcx.hir().get_module_parent(scrut.id);
         MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
             let mut have_errors = false;
 
@@ -224,7 +225,7 @@
             // Then, if the match has no arms, check whether the scrutinee
             // is uninhabited.
             let pat_ty = self.tables.node_id_to_type(scrut.hir_id);
-            let module = self.tcx.hir.get_module_parent(scrut.id);
+            let module = self.tcx.hir().get_module_parent(scrut.id);
             if inlined_arms.is_empty() {
                 let scrutinee_is_uninhabited = if self.tcx.features().exhaustive_patterns {
                     self.tcx.is_ty_uninhabited_from(module, pat_ty)
@@ -250,7 +251,7 @@
                 .iter()
                 .filter(|&&(_, guard)| guard.is_none())
                 .flat_map(|arm| &arm.0)
-                .map(|pat| vec![pat.0])
+                .map(|pat| smallvec![pat.0])
                 .collect();
             let scrut_ty = self.tables.node_id_to_type(scrut.hir_id);
             check_exhaustive(cx, scrut_ty, scrut.span, &matrix);
@@ -267,14 +268,14 @@
     }
 
     fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) {
-        let module = self.tcx.hir.get_module_parent(pat.id);
+        let module = self.tcx.hir().get_module_parent(pat.id);
         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);
             let pattern = patcx.lower_pattern(pat);
             let pattern_ty = pattern.ty;
-            let pats: Matrix = vec![vec![
+            let pats: Matrix = vec![smallvec![
                 expand_pattern(cx, pattern)
             ]].into_iter().collect();
 
@@ -309,7 +310,7 @@
     }
 }
 
-fn check_for_bindings_named_the_same_as_variants(cx: &MatchVisitor, pat: &Pat) {
+fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor, pat: &Pat) {
     pat.walk(|p| {
         if let PatKind::Binding(_, _, ident, None) = p.node {
             if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
@@ -367,7 +368,7 @@
     let mut printed_if_let_err = false;
     for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() {
         for &(pat, hir_pat) in pats {
-            let v = vec![pat];
+            let v = smallvec![pat];
 
             match is_useful(cx, &seen, &v, LeaveOutWitness) {
                 NotUseful => {
@@ -462,10 +463,10 @@
     }
 }
 
-fn check_exhaustive<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
+fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                               scrut_ty: Ty<'tcx>,
                               sp: Span,
-                              matrix: &Matrix<'a, 'tcx>) {
+                              matrix: &Matrix<'p, 'tcx>) {
     let wild_pattern = Pattern {
         ty: scrut_ty,
         span: DUMMY_SP,
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 61d8297..ddd6a70 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -228,7 +228,7 @@
 
     /// matches against a slice, checking the length and extracting elements.
     /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
-    /// e.g. `&[ref xs..]`.
+    /// e.g., `&[ref xs..]`.
     Slice {
         prefix: Vec<Pattern<'tcx>>,
         slice: Option<Pattern<'tcx>>,
@@ -954,7 +954,7 @@
         };
         let kind = match cv.ty.sty {
             ty::Float(_) => {
-                let id = self.tcx.hir.hir_to_node_id(id);
+                let id = self.tcx.hir().hir_to_node_id(id);
                 self.tcx.lint_node(
                     ::rustc::lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
                     id,
@@ -1259,34 +1259,32 @@
         }
     }
 
-    if let ty::Ref(_, rty, _) = ty.value.sty {
-        if let ty::Str = rty.sty {
-            match (a.val, b.val) {
-                (
-                    ConstValue::ScalarPair(
-                        Scalar::Ptr(ptr_a),
-                        len_a,
-                    ),
-                    ConstValue::ScalarPair(
-                        Scalar::Ptr(ptr_b),
-                        len_b,
-                    ),
-                ) if ptr_a.offset.bytes() == 0 && ptr_b.offset.bytes() == 0 => {
-                    if let Ok(len_a) = len_a.to_bits(tcx.data_layout.pointer_size) {
-                        if let Ok(len_b) = len_b.to_bits(tcx.data_layout.pointer_size) {
-                            if len_a == len_b {
-                                let map = tcx.alloc_map.lock();
-                                let alloc_a = map.unwrap_memory(ptr_a.alloc_id);
-                                let alloc_b = map.unwrap_memory(ptr_b.alloc_id);
-                                if alloc_a.bytes.len() as u128 == len_a {
-                                    return from_bool(alloc_a == alloc_b);
-                                }
+    if let ty::Str = ty.value.sty {
+        match (a.val, b.val) {
+            (
+                ConstValue::ScalarPair(
+                    Scalar::Ptr(ptr_a),
+                    len_a,
+                ),
+                ConstValue::ScalarPair(
+                    Scalar::Ptr(ptr_b),
+                    len_b,
+                ),
+            ) if ptr_a.offset.bytes() == 0 && ptr_b.offset.bytes() == 0 => {
+                if let Ok(len_a) = len_a.to_bits(tcx.data_layout.pointer_size) {
+                    if let Ok(len_b) = len_b.to_bits(tcx.data_layout.pointer_size) {
+                        if len_a == len_b {
+                            let map = tcx.alloc_map.lock();
+                            let alloc_a = map.unwrap_memory(ptr_a.alloc_id);
+                            let alloc_b = map.unwrap_memory(ptr_b.alloc_id);
+                            if alloc_a.bytes.len() as u128 == len_a {
+                                return from_bool(alloc_a == alloc_b);
                             }
                         }
                     }
                 }
-                _ => (),
             }
+            _ => (),
         }
     }
 
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index bbee6e0..cbe2e25 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -103,7 +103,7 @@
                     if bits == 0 {
                         return err!(Intrinsic(format!("{} called on 0", intrinsic_name)));
                     }
-                    numeric_intrinsic(intrinsic_name.trim_right_matches("_nonzero"), bits, kind)?
+                    numeric_intrinsic(intrinsic_name.trim_end_matches("_nonzero"), bits, kind)?
                 } else {
                     numeric_intrinsic(intrinsic_name, bits, kind)?
                 };
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index f43cfb9..4c7aa88 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -81,7 +81,7 @@
     type FrameExtra;
 
     /// Extra data stored in memory.  A reference to this is available when `AllocExtra`
-    /// gets initialized, so you can e.g. have an `Rc` here if there is global state you
+    /// gets initialized, so you can e.g., have an `Rc` here if there is global state you
     /// need access to in the `AllocExtra` hooks.
     type MemoryExtra: Default;
 
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 97d7e15..420fe26 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -29,7 +29,7 @@
 
 use super::{
     Pointer, AllocId, Allocation, GlobalId, AllocationExtra,
-    EvalResult, Scalar, EvalErrorKind, AllocType, PointerArithmetic,
+    EvalResult, Scalar, EvalErrorKind, AllocKind, PointerArithmetic,
     Machine, AllocMap, MayLeak, ErrorHandled, InboundsCheck,
 };
 
@@ -55,7 +55,7 @@
 }
 
 // `Memory` has to depend on the `Machine` because some of its operations
-// (e.g. `get`) call a `Machine` hook.
+// (e.g., `get`) call a `Machine` hook.
 pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
     /// Allocations local to this instance of the miri engine.  The kind
     /// helps ensure that the same mechanism is used for allocation and
@@ -204,12 +204,12 @@
             None => {
                 // Deallocating static memory -- always an error
                 return match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
-                    Some(AllocType::Function(..)) => err!(DeallocatedWrongMemoryKind(
+                    Some(AllocKind::Function(..)) => err!(DeallocatedWrongMemoryKind(
                         "function".to_string(),
                         format!("{:?}", kind),
                     )),
-                    Some(AllocType::Static(..)) |
-                    Some(AllocType::Memory(..)) => err!(DeallocatedWrongMemoryKind(
+                    Some(AllocKind::Static(..)) |
+                    Some(AllocKind::Memory(..)) => err!(DeallocatedWrongMemoryKind(
                         "static".to_string(),
                         format!("{:?}", kind),
                     )),
@@ -326,15 +326,15 @@
     ) -> EvalResult<'tcx, Cow<'tcx, Allocation<M::PointerTag, M::AllocExtra>>> {
         let alloc = tcx.alloc_map.lock().get(id);
         let def_id = match alloc {
-            Some(AllocType::Memory(mem)) => {
+            Some(AllocKind::Memory(mem)) => {
                 // We got tcx memory. Let the machine figure out whether and how to
                 // turn that into memory with the right pointer tag.
                 return Ok(M::adjust_static_allocation(mem, memory_extra))
             }
-            Some(AllocType::Function(..)) => {
+            Some(AllocKind::Function(..)) => {
                 return err!(DerefFunctionPointer)
             }
-            Some(AllocType::Static(did)) => {
+            Some(AllocKind::Static(did)) => {
                 did
             }
             None =>
@@ -435,8 +435,8 @@
         }
         // Could also be a fn ptr or extern static
         match self.tcx.alloc_map.lock().get(id) {
-            Some(AllocType::Function(..)) => (Size::ZERO, Align::from_bytes(1).unwrap()),
-            Some(AllocType::Static(did)) => {
+            Some(AllocKind::Function(..)) => (Size::ZERO, Align::from_bytes(1).unwrap()),
+            Some(AllocKind::Static(did)) => {
                 // The only way `get` couldn't have worked here is if this is an extern static
                 assert!(self.tcx.is_foreign_item(did));
                 // Use size and align of the type
@@ -459,7 +459,7 @@
         }
         trace!("reading fn ptr: {}", ptr.alloc_id);
         match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
-            Some(AllocType::Function(instance)) => Ok(instance),
+            Some(AllocKind::Function(instance)) => Ok(instance),
             _ => Err(EvalErrorKind::ExecuteMemory.into()),
         }
     }
@@ -557,16 +557,16 @@
                 Err(()) => {
                     // static alloc?
                     match self.tcx.alloc_map.lock().get(id) {
-                        Some(AllocType::Memory(alloc)) => {
+                        Some(AllocKind::Memory(alloc)) => {
                             self.dump_alloc_helper(
                                 &mut allocs_seen, &mut allocs_to_print,
                                 msg, alloc, " (immutable)".to_owned()
                             );
                         }
-                        Some(AllocType::Function(func)) => {
+                        Some(AllocKind::Function(func)) => {
                             trace!("{} {}", msg, func);
                         }
-                        Some(AllocType::Static(did)) => {
+                        Some(AllocKind::Static(did)) => {
                             trace!("{} {:?}", msg, did);
                         }
                         None => {
@@ -638,7 +638,7 @@
         // ensure llvm knows not to put this into immutable memory
         alloc.mutability = mutability;
         let alloc = self.tcx.intern_const_alloc(alloc);
-        self.tcx.alloc_map.lock().set_id_memory(alloc_id, alloc);
+        self.tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
         // recurse into inner allocations
         for &(_, alloc) in alloc.relocations.values() {
             // FIXME: Reusing the mutability here is likely incorrect.  It is originally
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 164a968..bae670b 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -35,7 +35,7 @@
     pub align: Align,
     /// Metadata for unsized places.  Interpretation is up to the type.
     /// Must not be present for sized types, but can be missing for unsized types
-    /// (e.g. `extern type`).
+    /// (e.g., `extern type`).
     pub meta: Option<Scalar<Tag, Id>>,
 }
 
@@ -236,7 +236,7 @@
             }
         } else {
             // Go through the layout.  There are lots of types that support a length,
-            // e.g. SIMD types.
+            // e.g., SIMD types.
             match self.layout.fields {
                 layout::FieldPlacement::Array { count, .. } => Ok(count),
                 _ => bug!("len not supported on sized type {:?}", self.layout.ty),
@@ -908,7 +908,7 @@
                         // a fake pointer?  Are we even called for ZST?
 
                         // We need the layout of the local.  We can NOT use the layout we got,
-                        // that might e.g. be an inner field of a struct with `Scalar` layout,
+                        // that might e.g., be an inner field of a struct with `Scalar` layout,
                         // that has different alignment than the outer field.
                         let local_layout = self.layout_of_local(&self.stack[frame], local)?;
                         let ptr = self.allocate(local_layout, MemoryKind::Stack)?;
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 84cc512..a6835e4 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -18,7 +18,7 @@
 
 use super::{EvalContext, Machine};
 
-/// Classify whether an operator is "left-homogeneous", i.e. the LHS has the
+/// Classify whether an operator is "left-homogeneous", i.e., the LHS has the
 /// same type as the result.
 #[inline]
 fn binop_left_homogeneous(op: mir::BinOp) -> bool {
@@ -31,7 +31,7 @@
             false,
     }
 }
-/// Classify whether an operator is "right-homogeneous", i.e. the RHS has the
+/// Classify whether an operator is "right-homogeneous", i.e., the RHS has the
 /// same type as the LHS.
 #[inline]
 fn binop_right_homogeneous(op: mir::BinOp) -> bool {
@@ -85,7 +85,7 @@
 
         use rustc::mir::StatementKind::*;
 
-        // Some statements (e.g. box) push new stack frames.
+        // Some statements (e.g., box) push new stack frames.
         // We have to record the stack frame number *before* executing the statement.
         let frame_idx = self.cur_frame();
         self.tcx.span = stmt.source_info.span;
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 300f3d6..4a672f1 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -252,7 +252,7 @@
                     return err!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic));
                 }
                 // The intrinsic itself cannot diverge, so if we got here without a return
-                // place... (can happen e.g. for transmute returning `!`)
+                // place... (can happen e.g., for transmute returning `!`)
                 let dest = match dest {
                     Some(dest) => dest,
                     None => return err!(Unreachable)
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index d98d05b..c7bfea8 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -17,7 +17,7 @@
 use rustc::ty;
 use rustc_data_structures::fx::FxHashSet;
 use rustc::mir::interpret::{
-    Scalar, AllocType, EvalResult, EvalErrorKind,
+    Scalar, AllocKind, EvalResult, EvalErrorKind,
 };
 
 use super::{
@@ -388,7 +388,7 @@
                             "integer pointer in non-ZST reference", self.path);
                         // Skip validation entirely for some external statics
                         let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id);
-                        if let Some(AllocType::Static(did)) = alloc_kind {
+                        if let Some(AllocKind::Static(did)) = alloc_kind {
                             // `extern static` cannot be validated as they have no body.
                             // FIXME: Statics from other crates are also skipped.
                             // They might be checked at a different type, but for now we
@@ -408,7 +408,7 @@
                     // Check if we have encountered this pointer+layout combination
                     // before.  Proceed recursively even for integer pointers, no
                     // reason to skip them! They are (recursively) valid for some ZST,
-                    // but not for others (e.g. `!` is a ZST).
+                    // but not for others (e.g., `!` is a ZST).
                     let op = place.into();
                     if ref_tracking.seen.insert(op) {
                         trace!("Recursing below ptr {:#?}", *op);
@@ -548,7 +548,7 @@
                 // NOTE: Keep this in sync with the handling of integer and float
                 // types above, in `visit_primitive`.
                 // In run-time mode, we accept pointers in here.  This is actually more
-                // permissive than a per-element check would be, e.g. we accept
+                // permissive than a per-element check would be, e.g., we accept
                 // an &[u8] that contains a pointer even though bytewise checking would
                 // reject it.  However, that's good: We don't inherently want
                 // to reject those pointers, we just do not have the machinery to
diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs
index 81e56f3..4773f56 100644
--- a/src/librustc_mir/interpret/visitor.rs
+++ b/src/librustc_mir/interpret/visitor.rs
@@ -272,7 +272,7 @@
                 // is very relevant for `NonNull` and similar structs: We need to visit them
                 // at their scalar layout *before* descending into their fields.
                 // FIXME: We could avoid some redundant checks here. For newtypes wrapping
-                // scalars, we do the same check on every "level" (e.g. first we check
+                // scalars, we do the same check on every "level" (e.g., first we check
                 // MyNewtype and then the scalar in there).
                 match v.layout().abi {
                     layout::Abi::Uninhabited => {
diff --git a/src/librustc_mir/lints.rs b/src/librustc_mir/lints.rs
index 4c79385..775431e 100644
--- a/src/librustc_mir/lints.rs
+++ b/src/librustc_mir/lints.rs
@@ -20,9 +20,9 @@
 pub fn check(tcx: TyCtxt<'a, 'tcx, 'tcx>,
              mir: &Mir<'tcx>,
              def_id: DefId) {
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
 
-    if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir.get(node_id)) {
+    if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get(node_id)) {
         check_fn_for_unconditional_recursion(tcx, fn_like_node.kind(), mir, def_id);
     }
 }
@@ -39,11 +39,11 @@
     //FIXME(#54444) rewrite this lint to use the dataflow framework
 
     // Walk through this function (say `f`) looking to see if
-    // every possible path references itself, i.e. the function is
+    // every possible path references itself, i.e., the function is
     // called recursively unconditionally. This is done by trying
     // to find a path from the entry node to the exit node that
     // *doesn't* call `f` by traversing from the entry while
-    // pretending that calls of `f` are sinks (i.e. ignoring any
+    // pretending that calls of `f` are sinks (i.e., ignoring any
     // exit edges from them).
     //
     // NB. this has an edge case with non-returning statements,
@@ -62,7 +62,7 @@
     // considers this to be an error for two reasons, (a) it is
     // easier to implement, and (b) it seems rare to actually want
     // to have behaviour like the above, rather than
-    // e.g. accidentally recursing after an assert.
+    // e.g., accidentally recursing after an assert.
 
     let basic_blocks = mir.basic_blocks();
     let mut reachable_without_self_call_queue = vec![mir::START_BLOCK];
@@ -135,12 +135,12 @@
     }
 
     // Check the number of self calls because a function that
-    // doesn't return (e.g. calls a `-> !` function or `loop { /*
+    // doesn't return (e.g., calls a `-> !` function or `loop { /*
     // no break */ }`) shouldn't be linted unless it actually
     // recurs.
     if !reached_exit_without_self_call && !self_call_locations.is_empty() {
-        let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-        let sp = tcx.sess.source_map().def_span(tcx.hir.span(node_id));
+        let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+        let sp = tcx.sess.source_map().def_span(tcx.hir().span(node_id));
         let mut db = tcx.struct_span_lint_node(UNCONDITIONAL_RECURSION,
                                                 node_id,
                                                 sp,
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 7531f62..a6239a8 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -197,7 +197,7 @@
 use rustc::mir::{self, Location, Promoted};
 use rustc::mir::visit::Visitor as MirVisitor;
 use rustc::mir::mono::MonoItem;
-use rustc::mir::interpret::{Scalar, GlobalId, AllocType, ErrorHandled};
+use rustc::mir::interpret::{Scalar, GlobalId, AllocKind, ErrorHandled};
 
 use monomorphize::{self, Instance};
 use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap};
@@ -332,7 +332,7 @@
 
     {
         let entry_fn = tcx.sess.entry_fn.borrow().map(|(node_id, _, _)| {
-            tcx.hir.local_def_id(node_id)
+            tcx.hir().local_def_id(node_id)
         });
 
         debug!("collect_roots: entry_fn = {:?}", entry_fn);
@@ -344,7 +344,7 @@
             output: &mut roots,
         };
 
-        tcx.hir.krate().visit_all_item_likes(&mut visitor);
+        tcx.hir().krate().visit_all_item_likes(&mut visitor);
 
         visitor.push_extra_entry_roots();
     }
@@ -462,8 +462,8 @@
     if recursion_depth > *tcx.sess.recursion_limit.get() {
         let error = format!("reached the recursion limit while instantiating `{}`",
                             instance);
-        if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-            tcx.sess.span_fatal(tcx.hir.span(node_id), &error);
+        if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
+            tcx.sess.span_fatal(tcx.hir().span(node_id), &error);
         } else {
             tcx.sess.fatal(&error);
         }
@@ -494,8 +494,8 @@
         let instance_name = instance.to_string();
         let msg = format!("reached the type-length limit while instantiating `{:.64}...`",
                           instance_name);
-        let mut diag = if let Some(node_id) = tcx.hir.as_local_node_id(instance.def_id()) {
-            tcx.sess.struct_span_fatal(tcx.hir.span(node_id), &msg)
+        let mut diag = if let Some(node_id) = tcx.hir().as_local_node_id(instance.def_id()) {
+            tcx.sess.struct_span_fatal(tcx.hir().span(node_id), &msg)
         } else {
             tcx.sess.struct_fatal(&msg)
         };
@@ -821,7 +821,7 @@
 /// Again, we want this `find_vtable_types_for_unsizing()` to provide the pair
 /// `(SomeStruct, SomeTrait)`.
 ///
-/// Finally, there is also the case of custom unsizing coercions, e.g. for
+/// Finally, there is also the case of custom unsizing coercions, e.g., for
 /// smart pointers such as `Rc` and `Arc`.
 fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                             source_ty: Ty<'tcx>,
@@ -961,7 +961,7 @@
             hir::ItemKind::Union(_, ref generics) => {
                 if generics.params.is_empty() {
                     if self.mode == MonoItemCollectionMode::Eager {
-                        let def_id = self.tcx.hir.local_def_id(item.id);
+                        let def_id = self.tcx.hir().local_def_id(item.id);
                         debug!("RootCollector: ADT drop-glue for {}",
                                def_id_to_string(self.tcx, def_id));
 
@@ -973,11 +973,11 @@
             hir::ItemKind::GlobalAsm(..) => {
                 debug!("RootCollector: ItemKind::GlobalAsm({})",
                        def_id_to_string(self.tcx,
-                                        self.tcx.hir.local_def_id(item.id)));
+                                        self.tcx.hir().local_def_id(item.id)));
                 self.output.push(MonoItem::GlobalAsm(item.id));
             }
             hir::ItemKind::Static(..) => {
-                let def_id = self.tcx.hir.local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id(item.id);
                 debug!("RootCollector: ItemKind::Static({})",
                        def_id_to_string(self.tcx, def_id));
                 self.output.push(MonoItem::Static(def_id));
@@ -987,7 +987,7 @@
                 // actually used somewhere. Just declaring them is insufficient.
 
                 // but even just declaring them must collect the items they refer to
-                let def_id = self.tcx.hir.local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id(item.id);
 
                 let instance = Instance::mono(self.tcx, def_id);
                 let cid = GlobalId {
@@ -1001,7 +1001,7 @@
                 }
             }
             hir::ItemKind::Fn(..) => {
-                let def_id = self.tcx.hir.local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id(item.id);
                 self.push_if_root(def_id);
             }
         }
@@ -1015,7 +1015,7 @@
     fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
         match ii.node {
             hir::ImplItemKind::Method(hir::MethodSig { .. }, _) => {
-                let def_id = self.tcx.hir.local_def_id(ii.id);
+                let def_id = self.tcx.hir().local_def_id(ii.id);
                 self.push_if_root(def_id);
             }
             _ => { /* Nothing to do here */ }
@@ -1108,7 +1108,7 @@
                 }
             }
 
-            let impl_def_id = tcx.hir.local_def_id(item.id);
+            let impl_def_id = tcx.hir().local_def_id(item.id);
 
             debug!("create_mono_items_for_default_impls(item={})",
                    def_id_to_string(tcx, impl_def_id));
@@ -1161,22 +1161,22 @@
     alloc_id: AllocId,
     output: &mut Vec<MonoItem<'tcx>>,
 ) {
-    let alloc_type = tcx.alloc_map.lock().get(alloc_id);
-    match alloc_type {
-        Some(AllocType::Static(did)) => {
+    let alloc_kind = tcx.alloc_map.lock().get(alloc_id);
+    match alloc_kind {
+        Some(AllocKind::Static(did)) => {
             let instance = Instance::mono(tcx, did);
             if should_monomorphize_locally(tcx, &instance) {
                 trace!("collecting static {:?}", did);
                 output.push(MonoItem::Static(did));
             }
         }
-        Some(AllocType::Memory(alloc)) => {
+        Some(AllocKind::Memory(alloc)) => {
             trace!("collecting {:?} with {:#?}", alloc_id, alloc);
             for &((), inner) in alloc.relocations.values() {
                 collect_miri(tcx, inner, output);
             }
         },
-        Some(AllocType::Function(fn_instance)) => {
+        Some(AllocKind::Function(fn_instance)) => {
             if should_monomorphize_locally(tcx, &fn_instance) {
                 trace!("collecting {:?} with {:#?}", alloc_id, fn_instance);
                 output.push(create_fn_mono_item(fn_instance));
diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs
index 24de92e..2bc6e93 100644
--- a/src/librustc_mir/monomorphize/item.rs
+++ b/src/librustc_mir/monomorphize/item.rs
@@ -68,7 +68,7 @@
                 tcx.symbol_name(Instance::mono(tcx, def_id))
             }
             MonoItem::GlobalAsm(node_id) => {
-                let def_id = tcx.hir.local_def_id(node_id);
+                let def_id = tcx.hir().local_def_id(node_id);
                 ty::SymbolName {
                     name: Symbol::intern(&format!("global_asm_{:?}", def_id)).as_interned_str()
                 }
@@ -86,7 +86,7 @@
         match *self.as_mono_item() {
             MonoItem::Fn(ref instance) => {
                 let entry_def_id =
-                    tcx.sess.entry_fn.borrow().map(|(id, _, _)| tcx.hir.local_def_id(id));
+                    tcx.sess.entry_fn.borrow().map(|(id, _, _)| tcx.hir().local_def_id(id));
                 // If this function isn't inlined or otherwise has explicit
                 // linkage, then we'll be creating a globally shared version.
                 if self.explicit_linkage(tcx).is_some() ||
@@ -199,15 +199,15 @@
     fn local_span(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Span> {
         match *self.as_mono_item() {
             MonoItem::Fn(Instance { def, .. }) => {
-                tcx.hir.as_local_node_id(def.def_id())
+                tcx.hir().as_local_node_id(def.def_id())
             }
             MonoItem::Static(def_id) => {
-                tcx.hir.as_local_node_id(def_id)
+                tcx.hir().as_local_node_id(def_id)
             }
             MonoItem::GlobalAsm(node_id) => {
                 Some(node_id)
             }
-        }.map(|node_id| tcx.hir.span(node_id))
+        }.map(|node_id| tcx.hir().span(node_id))
     }
 }
 
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index 528942d..00974d4 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -51,7 +51,7 @@
 //!
 //! - There are two codegen units for every source-level module:
 //! - One for "stable", that is non-generic, code
-//! - One for more "volatile" code, i.e. monomorphized instances of functions
+//! - One for more "volatile" code, i.e., monomorphized instances of functions
 //!   defined in that module
 //!
 //! In order to see why this heuristic makes sense, let's take a look at when a
@@ -184,7 +184,7 @@
                         // the codegen tests and can even make item order
                         // unstable.
                         InstanceDef::Item(def_id) => {
-                            tcx.hir.as_local_node_id(def_id)
+                            tcx.hir().as_local_node_id(def_id)
                         }
                         InstanceDef::VtableShim(..) |
                         InstanceDef::Intrinsic(..) |
@@ -198,7 +198,7 @@
                     }
                 }
                 MonoItem::Static(def_id) => {
-                    tcx.hir.as_local_node_id(def_id)
+                    tcx.hir().as_local_node_id(def_id)
                 }
                 MonoItem::GlobalAsm(node_id) => {
                     Some(node_id)
@@ -415,7 +415,7 @@
             };
         }
         MonoItem::GlobalAsm(node_id) => {
-            let def_id = tcx.hir.local_def_id(*node_id);
+            let def_id = tcx.hir().local_def_id(*node_id);
             return if tcx.is_reachable_non_generic(def_id) {
                 *can_be_internalized = false;
                 default_visibility(tcx, def_id, false)
@@ -799,7 +799,7 @@
             Some(def_id)
         }
         MonoItem::Static(def_id) => Some(def_id),
-        MonoItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)),
+        MonoItem::GlobalAsm(node_id) => Some(tcx.hir().local_def_id(node_id)),
     }
 }
 
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 3a53cc6..1141629 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -860,7 +860,7 @@
 {
     let tcx = infcx.tcx;
     let gcx = tcx.global_tcx();
-    let def_id = tcx.hir.local_def_id(ctor_id);
+    let def_id = tcx.hir().local_def_id(ctor_id);
     let param_env = gcx.param_env(def_id);
 
     // Normalize the sig.
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 75f8045..6af29b7 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -473,8 +473,8 @@
                                  unsafe_blocks: &'a mut Vec<(ast::NodeId, bool)>)
 {
     let body_id =
-        tcx.hir.as_local_node_id(def_id).and_then(|node_id| {
-            tcx.hir.maybe_body_owned_by(node_id)
+        tcx.hir().as_local_node_id(def_id).and_then(|node_id| {
+            tcx.hir().maybe_body_owned_by(node_id)
         });
 
     let body_id = match body_id {
@@ -484,7 +484,7 @@
             return
         }
     };
-    let body = tcx.hir.body(body_id);
+    let body = tcx.hir().body(body_id);
     debug!("check_unused_unsafe({:?}, body={:?}, used_unsafe={:?})",
            def_id, body, used_unsafe);
 
@@ -497,7 +497,7 @@
 {
     debug!("unsafety_violations({:?})", def_id);
 
-    // NB: this borrow is valid because all the consumers of
+    // N.B., this borrow is valid because all the consumers of
     // `mir_built` force this.
     let mir = &tcx.mir_built(def_id).borrow();
 
@@ -526,7 +526,7 @@
 }
 
 fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
-    let lint_node_id = match tcx.hir.as_local_node_id(def_id) {
+    let lint_node_id = match tcx.hir().as_local_node_id(def_id) {
         Some(node_id) => node_id,
         None => bug!("checking unsafety for non-local def id {:?}", def_id)
     };
@@ -550,14 +550,14 @@
 fn is_enclosed(tcx: TyCtxt,
                used_unsafe: &FxHashSet<ast::NodeId>,
                id: ast::NodeId) -> Option<(String, ast::NodeId)> {
-    let parent_id = tcx.hir.get_parent_node(id);
+    let parent_id = tcx.hir().get_parent_node(id);
     if parent_id != id {
         if used_unsafe.contains(&parent_id) {
             Some(("block".to_string(), parent_id))
         } else if let Some(Node::Item(&hir::Item {
             node: hir::ItemKind::Fn(_, header, _, _),
             ..
-        })) = tcx.hir.find(parent_id) {
+        })) = tcx.hir().find(parent_id) {
             match header.unsafety {
                 hir::Unsafety::Unsafe => Some(("fn".to_string(), parent_id)),
                 hir::Unsafety::Normal => None,
@@ -571,12 +571,12 @@
 }
 
 fn report_unused_unsafe(tcx: TyCtxt, used_unsafe: &FxHashSet<ast::NodeId>, id: ast::NodeId) {
-    let span = tcx.sess.source_map().def_span(tcx.hir.span(id));
+    let span = tcx.sess.source_map().def_span(tcx.hir().span(id));
     let msg = "unnecessary `unsafe` block";
     let mut db = tcx.struct_span_lint_node(UNUSED_UNSAFE, id, span, msg);
     db.span_label(span, msg);
     if let Some((kind, id)) = is_enclosed(tcx, used_unsafe, id) {
-        db.span_label(tcx.sess.source_map().def_span(tcx.hir.span(id)),
+        db.span_label(tcx.sess.source_map().def_span(tcx.hir().span(id)),
                       format!("because it's nested under this `unsafe` {}", kind));
     }
     db.emit();
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index f21efaa..acae03f 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -47,10 +47,10 @@
         }
 
         use rustc::hir::map::blocks::FnLikeNode;
-        let node_id = tcx.hir.as_local_node_id(source.def_id)
+        let node_id = tcx.hir().as_local_node_id(source.def_id)
                              .expect("Non-local call to local provider is_const_fn");
 
-        let is_fn_like = FnLikeNode::from_node(tcx.hir.get(node_id)).is_some();
+        let is_fn_like = FnLikeNode::from_node(tcx.hir().get(node_id)).is_some();
         let is_assoc_const = match tcx.describe_def(source.def_id) {
             Some(Def::AssociatedConst(_)) => true,
             _ => false,
@@ -289,7 +289,7 @@
                     })?;
                     Some((res, span))
                 },
-                // We could get more projections by using e.g. `operand_projection`,
+                // We could get more projections by using e.g., `operand_projection`,
                 // but we do not even have the stack frame set up properly so
                 // an `Index` projection would throw us off-track.
                 _ => None,
@@ -618,7 +618,7 @@
                         .span;
                     let node_id = self
                         .tcx
-                        .hir
+                        .hir()
                         .as_local_node_id(self.source.def_id)
                         .expect("some part of a failing const eval must be local");
                     use rustc::mir::interpret::EvalErrorKind::*;
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 2b3fd55..c8056ea 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -38,7 +38,7 @@
     {
         debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
 
-        let id = tcx.hir.as_local_node_id(src.def_id).unwrap();
+        let id = tcx.hir().as_local_node_id(src.def_id).unwrap();
         let param_env = tcx.param_env(src.def_id).with_reveal_all();
         let move_data = match MoveData::gather_moves(mir, tcx) {
             Ok(move_data) => move_data,
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 24cc4cc..f870e4a 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -379,7 +379,7 @@
     FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>,
 ) {
     let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
-    let node_id = tcx.hir.as_local_node_id(source.def_id).unwrap();
+    let node_id = tcx.hir().as_local_node_id(source.def_id).unwrap();
 
     // Calculate when MIR locals have live storage. This gives us an upper bound of their
     // lifetimes.
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index ab71cef..afe0066 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -83,8 +83,8 @@
         let param_env = self.tcx.param_env(self.source.def_id);
 
         // Only do inlining into fn bodies.
-        let id = self.tcx.hir.as_local_node_id(self.source.def_id).unwrap();
-        let body_owner_kind = self.tcx.hir.body_owner_kind(id);
+        let id = self.tcx.hir().as_local_node_id(self.source.def_id).unwrap();
+        let body_owner_kind = self.tcx.hir().body_owner_kind(id);
 
         if let (hir::BodyOwnerKind::Fn, None) = (body_owner_kind, self.source.promoted) {
 
@@ -575,10 +575,10 @@
             // The `tmp0`, `tmp1`, and `tmp2` in our example abonve.
             let tuple_tmp_args =
                 tuple_tys.iter().enumerate().map(|(i, ty)| {
-                    // This is e.g. `tuple_tmp.0` in our example above.
+                    // This is e.g., `tuple_tmp.0` in our example above.
                     let tuple_field = Operand::Move(tuple.clone().field(Field::new(i), ty));
 
-                    // Spill to a local to make e.g. `tmp0`.
+                    // Spill to a local to make e.g., `tmp0`.
                     self.create_temp_if_necessary(tuple_field, callsite, caller_mir)
                 });
 
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index a77e9b5..005c1a0 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -91,7 +91,7 @@
                               _: ast::NodeId,
                               _: Span) {
             if let hir::VariantData::Tuple(_, node_id) = *v {
-                self.set.insert(self.tcx.hir.local_def_id(node_id));
+                self.set.insert(self.tcx.hir().local_def_id(node_id));
             }
             intravisit::walk_struct_def(self, v)
         }
@@ -99,7 +99,7 @@
             NestedVisitorMap::None
         }
     }
-    tcx.hir.krate().visit_all_item_likes(&mut GatherCtors {
+    tcx.hir().krate().visit_all_item_likes(&mut GatherCtors {
         tcx,
         set: &mut set,
     }.as_deep_visitor());
@@ -219,8 +219,8 @@
 }
 
 fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    if let hir::BodyOwnerKind::Const = tcx.hir.body_owner_kind(node_id) {
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    if let hir::BodyOwnerKind::Const = tcx.hir().body_owner_kind(node_id) {
         // Ensure that we compute the `mir_const_qualif` for constants at
         // this point, before we steal the mir-const result.
         let _ = tcx.mir_const_qualif(def_id);
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index c5add62..7f8dfc1 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -123,7 +123,7 @@
             }
         } else if let TempState::Defined { ref mut uses, .. } = *temp {
             // We always allow borrows, even mutable ones, as we need
-            // to promote mutable borrows of some ZSTs e.g. `&mut []`.
+            // to promote mutable borrows of some ZSTs e.g., `&mut []`.
             let allowed_use = context.is_borrow() || context.is_nonmutating_use();
             debug!("visit_local: allowed_use={:?}", allowed_use);
             if allowed_use {
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index bcee6d7..5f08dee 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -17,6 +17,8 @@
 use rustc_data_structures::bit_set::BitSet;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::sync::Lrc;
+use rustc_target::spec::abi::Abi;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::mir::interpret::ConstValue;
@@ -28,13 +30,12 @@
 use rustc::mir::traversal::ReversePostorder;
 use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
 use rustc::middle::lang_items;
-use rustc_target::spec::abi::Abi;
+use rustc::session::config::nightly_options;
 use syntax::ast::LitKind;
 use syntax::feature_gate::{UnstableFeatures, feature_err, emit_feature_err, GateIssue};
 use syntax_pos::{Span, DUMMY_SP};
 
 use std::fmt;
-use rustc_data_structures::sync::Lrc;
 use std::usize;
 
 use transform::{MirPass, MirSource};
@@ -639,7 +640,7 @@
                         self.add(qualif);
 
                         // Just in case the type is more specific than
-                        // the definition, e.g. impl associated const
+                        // the definition, e.g., impl associated const
                         // with type parameters, take it into account.
                         self.qualif.restrict(constant.literal.ty, self.tcx, self.param_env);
                     }
@@ -952,10 +953,10 @@
                             }
                         }
                         _ => {
-                            // in normal functions we only care about promotion
+                            // In normal functions we only care about promotion.
                             if self.mode == Mode::Fn {
-                                // never promote const fn calls of
-                                // functions without #[rustc_promotable]
+                                // 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;
@@ -963,19 +964,19 @@
                                     is_const_fn = true;
                                 }
                             } else {
-                                // stable const fn or unstable const fns with their feature gate
+                                // stable const fns 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
+                                    // 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
+                                    // since the macro is marked with the attribute.
                                     if self.tcx.features().const_panic {
                                         is_const_fn = true;
                                     } else {
-                                        // don't allow panics in constants without the feature gate
+                                        // Don't allow panics in constants without the feature gate.
                                         emit_feature_err(
                                             &self.tcx.sess.parse_sess,
                                             "const_panic",
@@ -984,25 +985,28 @@
                                             &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
+                                } 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 in
+                                    // order to report a better error message than the one below.
                                     if self.span.allows_unstable() {
-                                        // `allow_internal_unstable` can make such calls stable
+                                        // `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);
+                                        if nightly_options::is_nightly_build() {
+                                            help!(&mut err,
+                                                  "add `#![feature({})]` to the \
+                                                   crate attributes to enable",
+                                                  feature);
+                                        }
                                         err.emit();
                                     }
                                 } else {
-                                    // FIXME(#24111) Remove this check when const fn stabilizes
+                                    // 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 \
@@ -1081,7 +1085,7 @@
                     // we care about constness, not promotability.
                     // If we checked for promotability, we'd miss out on
                     // the results of function calls (which are never promoted
-                    // in runtime code)
+                    // in runtime code).
                     // This is not a problem, because the argument explicitly
                     // requests constness, in contrast to regular promotion
                     // which happens even without the user requesting it.
@@ -1098,7 +1102,7 @@
                 });
             }
 
-            // non-const fn calls.
+            // non-const fn calls
             if !is_const_fn {
                 self.qualif = Qualif::NOT_CONST;
                 if self.mode != Mode::Fn {
@@ -1131,7 +1135,7 @@
 
             // Deny *any* live drops anywhere other than functions.
             if self.mode != Mode::Fn {
-                // HACK(eddyb) Emulate a bit of dataflow analysis,
+                // HACK(eddyb): emulate a bit of dataflow analysis,
                 // conservatively, that drop elaboration will do.
                 let needs_drop = if let Place::Local(local) = *place {
                     if self.local_qualif[local].map_or(true, |q| q.contains(Qualif::NEEDS_DROP)) {
@@ -1259,7 +1263,7 @@
 fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               def_id: DefId)
                               -> (u8, Lrc<BitSet<Local>>) {
-    // NB: This `borrow()` is guaranteed to be valid (i.e., the value
+    // N.B., this `borrow()` is guaranteed to be valid (i.e., the value
     // cannot yet be stolen), because `mir_validated()`, which steals
     // from `mir_const(), forces this query to execute before
     // performing the steal.
@@ -1293,9 +1297,9 @@
         }
 
         let def_id = src.def_id;
-        let id = tcx.hir.as_local_node_id(def_id).unwrap();
+        let id = tcx.hir().as_local_node_id(def_id).unwrap();
         let mut const_promoted_temps = None;
-        let mode = match tcx.hir.body_owner_kind(id) {
+        let mode = match tcx.hir().body_owner_kind(id) {
             hir::BodyOwnerKind::Fn => {
                 if tcx.is_const_fn(def_id) {
                     Mode::ConstFn
diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs
index a31d12b..81b010e 100644
--- a/src/librustc_mir/transform/remove_noop_landing_pads.rs
+++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs
@@ -58,7 +58,7 @@
                 }
 
                 StatementKind::Assign(Place::Local(_), box Rvalue::Use(_)) => {
-                    // Writing to a local (e.g. a drop flag) does not
+                    // Writing to a local (e.g., a drop flag) does not
                     // turn a landing pad to a non-nop
                 }
 
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index f852195..c996dc2 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -34,7 +34,7 @@
     fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           src: MirSource, mir: &mut Mir<'tcx>) {
         let def_id = src.def_id;
-        let id = tcx.hir.as_local_node_id(def_id).unwrap();
+        let id = tcx.hir().as_local_node_id(def_id).unwrap();
         if !tcx.has_attr(def_id, "rustc_mir") {
             debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
             return;
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 2c7f337..4f381e0 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -24,8 +24,8 @@
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
 pub enum DropFlagState {
-    Present, // i.e. initialized
-    Absent, // i.e. deinitialized or "moved"
+    Present, // i.e., initialized
+    Absent, // i.e., deinitialized or "moved"
 }
 
 impl DropFlagState {
diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs
index 0b883f6..58963a4 100644
--- a/src/librustc_mir/util/graphviz.rs
+++ b/src/librustc_mir/util/graphviz.rs
@@ -38,7 +38,7 @@
                                       w: &mut W) -> io::Result<()>
     where W: Write
 {
-    writeln!(w, "digraph Mir_{} {{", tcx.hir.as_local_node_id(def_id).unwrap())?;
+    writeln!(w, "digraph Mir_{} {{", tcx.hir().as_local_node_id(def_id).unwrap())?;
 
     // Global graph properties
     writeln!(w, r#"    graph [fontname="monospace"];"#)?;
diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs
index 12c13b8..22554ac 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -29,7 +29,7 @@
 //! ```
 //!
 //! This means that users of this analysis still have to check whether
-//! pre-existing references can be used to access the value (e.g. at movable
+//! pre-existing references can be used to access the value (e.g., at movable
 //! generator yield points, all pre-existing references are invalidated, so this
 //! doesn't matter).
 
@@ -343,7 +343,7 @@
 ) {
     let mut file_path = PathBuf::new();
     file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
-    let item_id = tcx.hir.as_local_node_id(source.def_id).unwrap();
+    let item_id = tcx.hir().as_local_node_id(source.def_id).unwrap();
     let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name);
     file_path.push(&file_name);
     let _ = fs::File::create(&file_path).and_then(|mut file| {
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index c74492f..0db9b23 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;
 
@@ -193,7 +193,7 @@
     let mut file_path = PathBuf::new();
     file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
 
-    let item_name = tcx.hir
+    let item_name = tcx.hir()
         .def_path(source.def_id)
         .to_filename_friendly_no_crate();
 
@@ -569,8 +569,8 @@
 }
 
 fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut dyn Write) -> io::Result<()> {
-    let id = tcx.hir.as_local_node_id(src.def_id).unwrap();
-    let body_owner_kind = tcx.hir.body_owner_kind(id);
+    let id = tcx.hir().as_local_node_id(src.def_id).unwrap();
+    let body_owner_kind = tcx.hir().body_owner_kind(id);
     match (body_owner_kind, src.promoted) {
         (_, Some(i)) => write!(w, "{:?} in", i)?,
         (hir::BodyOwnerKind::Fn, _) => write!(w, "fn")?,
diff --git a/src/librustc_msan/Cargo.toml b/src/librustc_msan/Cargo.toml
index 2916567..78c39d0 100644
--- a/src/librustc_msan/Cargo.toml
+++ b/src/librustc_msan/Cargo.toml
@@ -16,4 +16,4 @@
 [dependencies]
 alloc = { path = "../liballoc" }
 core = { path = "../libcore" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
+compiler_builtins = "0.1.0"
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index b878a33..9a35721 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -404,7 +404,7 @@
                 }
             }
             ItemKind::Mod(_) => {
-                // Ensure that `path` attributes on modules are recorded as used (c.f. #35584).
+                // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
                 attr::first_attr_value_str_by_name(&item.attrs, "path");
                 if attr::contains_name(&item.attrs, "warn_directory_ownership") {
                     let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP;
@@ -529,7 +529,7 @@
     }
 }
 
-// Bans nested `impl Trait`, e.g. `impl Into<impl Debug>`.
+// Bans nested `impl Trait`, e.g., `impl Into<impl Debug>`.
 // Nested `impl Trait` _is_ allowed in associated type position,
 // e.g `impl Iterator<Item=impl Debug>`
 struct NestedImplTraitVisitor<'a> {
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 099c6df..bfe8b67 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -50,8 +50,8 @@
 }
 
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    for &body_id in &tcx.hir.krate().body_ids {
-        let def_id = tcx.hir.body_owner_def_id(body_id);
+    for &body_id in &tcx.hir().krate().body_ids {
+        let def_id = tcx.hir().body_owner_def_id(body_id);
         tcx.const_is_rvalue_promotable_to_static(def_id);
     }
     tcx.sess.abort_if_errors();
@@ -63,10 +63,10 @@
 {
     assert!(def_id.is_local());
 
-    let node_id = tcx.hir.as_local_node_id(def_id)
+    let node_id = tcx.hir().as_local_node_id(def_id)
         .expect("rvalue_promotable_map invoked with non-local def-id");
-    let body_id = tcx.hir.body_owned_by(node_id);
-    let body_hir_id = tcx.hir.node_to_hir_id(body_id.node_id);
+    let body_id = tcx.hir().body_owned_by(node_id);
+    let body_hir_id = tcx.hir().node_to_hir_id(body_id.node_id);
     tcx.rvalue_promotable_map(def_id).contains(&body_hir_id.local_id)
 }
 
@@ -91,9 +91,9 @@
     };
 
     // `def_id` should be a `Body` owner
-    let node_id = tcx.hir.as_local_node_id(def_id)
+    let node_id = tcx.hir().as_local_node_id(def_id)
         .expect("rvalue_promotable_map invoked with non-local def-id");
-    let body_id = tcx.hir.body_owned_by(node_id);
+    let body_id = tcx.hir().body_owned_by(node_id);
     let _ = visitor.check_nested_body(body_id);
 
     Lrc::new(visitor.result)
@@ -189,8 +189,8 @@
 
 impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
     fn check_nested_body(&mut self, body_id: hir::BodyId) -> Promotability {
-        let item_id = self.tcx.hir.body_owner(body_id);
-        let item_def_id = self.tcx.hir.local_def_id(item_id);
+        let item_id = self.tcx.hir().body_owner(body_id);
+        let item_def_id = self.tcx.hir().local_def_id(item_id);
 
         let outer_in_fn = self.in_fn;
         let outer_tables = self.tables;
@@ -200,7 +200,7 @@
         self.in_fn = false;
         self.in_static = false;
 
-        match self.tcx.hir.body_owner_kind(item_id) {
+        match self.tcx.hir().body_owner_kind(item_id) {
             hir::BodyOwnerKind::Fn => self.in_fn = true,
             hir::BodyOwnerKind::Static(_) => self.in_static = true,
             _ => {}
@@ -211,7 +211,7 @@
         self.param_env = self.tcx.param_env(item_def_id);
         self.identity_substs = Substs::identity_for_item(self.tcx, item_def_id);
 
-        let body = self.tcx.hir.body(body_id);
+        let body = self.tcx.hir().body(body_id);
 
         let tcx = self.tcx;
         let param_env = self.param_env;
@@ -383,7 +383,7 @@
                         NotPromotable
                     };
                     // Just in case the type is more specific than the definition,
-                    // e.g. impl associated const with type parameters, check it.
+                    // e.g., impl associated const with type parameters, check it.
                     // Also, trait associated consts are relaxed by this.
                     promotable | v.type_promotability(node_ty)
                 }
diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs
index bf59165..ad55672f 100644
--- a/src/librustc_plugin/load.rs
+++ b/src/librustc_plugin/load.rs
@@ -144,7 +144,7 @@
 
             // Intentionally leak the dynamic library. We can't ever unload it
             // since the library can make things that will live arbitrarily long
-            // (e.g. an @-box cycle or a thread).
+            // (e.g., an @-box cycle or a thread).
             mem::forget(lib);
 
             registrar
diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs
index 6c10ac7..2fb28a8 100644
--- a/src/librustc_plugin/registry.rs
+++ b/src/librustc_plugin/registry.rs
@@ -60,8 +60,6 @@
 
     #[doc(hidden)]
     pub attributes: Vec<(String, AttributeType)>,
-
-    whitelisted_custom_derives: Vec<ast::Name>,
 }
 
 impl<'a> Registry<'a> {
@@ -77,7 +75,6 @@
             lint_groups: FxHashMap::default(),
             llvm_passes: vec![],
             attributes: vec![],
-            whitelisted_custom_derives: Vec::new(),
         }
     }
 
@@ -130,19 +127,6 @@
         }));
     }
 
-    /// This can be used in place of `register_syntax_extension` to register legacy custom derives
-    /// (i.e. attribute syntax extensions whose name begins with `derive_`). Legacy custom
-    /// derives defined by this function do not trigger deprecation warnings when used.
-    pub fn register_custom_derive(&mut self, name: ast::Name, extension: SyntaxExtension) {
-        assert!(name.as_str().starts_with("derive_"));
-        self.whitelisted_custom_derives.push(name);
-        self.register_syntax_extension(name, extension);
-    }
-
-    pub fn take_whitelisted_custom_derives(&mut self) -> Vec<ast::Name> {
-        ::std::mem::replace(&mut self.whitelisted_custom_derives, Vec::new())
-    }
-
     /// Register a macro of the usual kind.
     ///
     /// This is a convenience wrapper for `register_syntax_extension`.
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 6d9abbf..86e3b23 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -23,8 +23,7 @@
 extern crate syntax_pos;
 extern crate rustc_data_structures;
 
-use rustc::hir::{self, PatKind};
-use hir::Node;
+use rustc::hir::{self, Node, PatKind};
 use rustc::hir::def::Def;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
@@ -36,14 +35,14 @@
 use rustc::ty::query::Providers;
 use rustc::ty::subst::UnpackedKind;
 use rustc::util::nodemap::NodeSet;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::sync::Lrc;
 use syntax::ast::{self, CRATE_NODE_ID, Ident};
 use syntax::symbol::keywords;
 use syntax_pos::Span;
 
 use std::cmp;
 use std::mem::replace;
-use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::sync::Lrc;
 
 mod diagnostics;
 
@@ -60,7 +59,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for PubRestrictedVisitor<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.tcx.hir)
+        NestedVisitorMap::All(&self.tcx.hir())
     }
     fn visit_vis(&mut self, vis: &'tcx hir::Visibility) {
         self.has_pub_restricted = self.has_pub_restricted || vis.node.is_pub_restricted();
@@ -74,11 +73,11 @@
 struct EmbargoVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
-    // Accessibility levels for reachable nodes
+    // Accessibility levels for reachable nodes.
     access_levels: AccessLevels,
-    // Previous accessibility level, None means unreachable
+    // Previous accessibility level; `None` means unreachable.
     prev_level: Option<AccessLevel>,
-    // Have something changed in the level map?
+    // Has something changed in the level map?
     changed: bool,
 }
 
@@ -97,7 +96,7 @@
             ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id,
             _ => return Some(AccessLevel::Public)
         };
-        if let Some(node_id) = self.tcx.hir.as_local_node_id(ty_def_id) {
+        if let Some(node_id) = self.tcx.hir().as_local_node_id(ty_def_id) {
             self.get(node_id)
         } else {
             Some(AccessLevel::Public)
@@ -106,7 +105,7 @@
 
     fn impl_trait_level(&self, impl_def_id: DefId) -> Option<AccessLevel> {
         if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) {
-            if let Some(node_id) = self.tcx.hir.as_local_node_id(trait_ref.def_id) {
+            if let Some(node_id) = self.tcx.hir().as_local_node_id(trait_ref.def_id) {
                 return self.get(node_id);
             }
         }
@@ -117,10 +116,10 @@
         self.access_levels.map.get(&id).cloned()
     }
 
-    // Updates node level and returns the updated level
+    // Updates node level and returns the updated level.
     fn update(&mut self, id: ast::NodeId, level: Option<AccessLevel>) -> Option<AccessLevel> {
         let old_level = self.get(id);
-        // Accessibility levels can only grow
+        // Accessibility levels can only grow.
         if level > old_level {
             self.access_levels.map.insert(id, level.unwrap());
             self.changed = true;
@@ -134,7 +133,7 @@
                  -> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
         ReachEverythingInTheInterfaceVisitor {
             access_level: self.prev_level.map(|l| l.min(AccessLevel::Reachable)),
-            item_def_id: self.tcx.hir.local_def_id(item_id),
+            item_def_id: self.tcx.hir().local_def_id(item_id),
             ev: self,
         }
     }
@@ -144,21 +143,21 @@
     /// We want to visit items in the context of their containing
     /// module and so forth, so supply a crate for doing a deep walk.
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.tcx.hir)
+        NestedVisitorMap::All(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         let inherited_item_level = match item.node {
-            // Impls inherit level from their types and traits
+            // Impls inherit level from their types and traits.
             hir::ItemKind::Impl(..) => {
-                let def_id = self.tcx.hir.local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id(item.id);
                 cmp::min(self.item_ty_level(def_id), self.impl_trait_level(def_id))
             }
-            // Foreign mods inherit level from parents
+            // Foreign modules inherit level from parents.
             hir::ItemKind::ForeignMod(..) => {
                 self.prev_level
             }
-            // Other `pub` items inherit levels from parents
+            // Other `pub` items inherit levels from parents.
             hir::ItemKind::Const(..) | hir::ItemKind::Enum(..) | hir::ItemKind::ExternCrate(..) |
             hir::ItemKind::GlobalAsm(..) | hir::ItemKind::Fn(..) | hir::ItemKind::Mod(..) |
             hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) |
@@ -169,10 +168,10 @@
             }
         };
 
-        // Update level of the item itself
+        // Update level of the item itself.
         let item_level = self.update(item.id, inherited_item_level);
 
-        // Update levels of nested things
+        // Update levels of nested things.
         match item.node {
             hir::ItemKind::Enum(ref def, _) => {
                 for variant in &def.variants {
@@ -220,7 +219,7 @@
             // It (and its children) are revisited if the change applies.
             hir::ItemKind::Existential(ref ty_data) => {
                 if let Some(impl_trait_fn) = ty_data.impl_trait_fn {
-                    if let Some(node_id) = self.tcx.hir.as_local_node_id(impl_trait_fn) {
+                    if let Some(node_id) = self.tcx.hir().as_local_node_id(impl_trait_fn) {
                         self.update(node_id, Some(AccessLevel::ReachableFromImplTrait));
                     }
                 }
@@ -240,23 +239,23 @@
         // reachability level through interfaces and children.
         let orig_level = replace(&mut self.prev_level, item_level);
 
-        // Mark all items in interfaces of reachable items as reachable
+        // Mark all items in interfaces of reachable items as reachable.
         match item.node {
-            // The interface is empty
+            // The interface is empty.
             hir::ItemKind::ExternCrate(..) => {}
-            // All nested items are checked by visit_item
+            // All nested items are checked by `visit_item`.
             hir::ItemKind::Mod(..) => {}
-            // Re-exports are handled in visit_mod
+            // Re-exports are handled in `visit_mod`.
             hir::ItemKind::Use(..) => {}
-            // The interface is empty
+            // The interface is empty.
             hir::ItemKind::GlobalAsm(..) => {}
             hir::ItemKind::Existential(hir::ExistTy { impl_trait_fn: Some(_), .. }) => {
                 if item_level.is_some() {
-                    // Reach the (potentially private) type and the API being exposed
+                    // Reach the (potentially private) type and the API being exposed.
                     self.reach(item.id).ty().predicates();
                 }
             }
-            // Visit everything
+            // Visit everything.
             hir::ItemKind::Const(..) | hir::ItemKind::Static(..) |
             hir::ItemKind::Existential(..) |
             hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) => {
@@ -286,7 +285,7 @@
                     self.reach(item.id).generics().predicates();
                 }
             }
-            // Visit everything except for private impl items
+            // Visit everything except for private impl items.
             hir::ItemKind::Impl(.., ref trait_ref, _, ref impl_item_refs) => {
                 if item_level.is_some() {
                     self.reach(item.id).generics().predicates().impl_trait_ref();
@@ -300,7 +299,7 @@
                 }
             }
 
-            // Visit everything, but enum variants have their own levels
+            // Visit everything, but enum variants have their own levels.
             hir::ItemKind::Enum(ref def, _) => {
                 if item_level.is_some() {
                     self.reach(item.id).generics().predicates();
@@ -316,7 +315,7 @@
                     }
                 }
             }
-            // Visit everything, but foreign items have their own levels
+            // Visit everything, but foreign items have their own levels.
             hir::ItemKind::ForeignMod(ref foreign_mod) => {
                 for foreign_item in &foreign_mod.items {
                     if self.get(foreign_item.id).is_some() {
@@ -324,7 +323,7 @@
                     }
                 }
             }
-            // Visit everything except for private fields
+            // Visit everything except for private fields.
             hir::ItemKind::Struct(ref struct_def, _) |
             hir::ItemKind::Union(ref struct_def, _) => {
                 if item_level.is_some() {
@@ -348,7 +347,7 @@
 
         // Blocks can have public items, for example impls, but they always
         // start as completely private regardless of publicity of a function,
-        // constant, type, field, etc. in which this block resides
+        // constant, type, field, etc., in which this block resides.
         intravisit::walk_block(self, b);
 
         self.prev_level = orig_level;
@@ -358,12 +357,12 @@
         // This code is here instead of in visit_item so that the
         // crate module gets processed as well.
         if self.prev_level.is_some() {
-            let def_id = self.tcx.hir.local_def_id(id);
+            let def_id = self.tcx.hir().local_def_id(id);
             if let Some(exports) = self.tcx.module_exports(def_id) {
                 for export in exports.iter() {
                     if export.vis == ty::Visibility::Public {
                         if let Some(def_id) = export.def.opt_def_id() {
-                            if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
+                            if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
                                 self.update(node_id, Some(AccessLevel::Exported));
                             }
                         }
@@ -381,8 +380,11 @@
             return
         }
 
-        let module_did = ty::DefIdTree::parent(self.tcx, self.tcx.hir.local_def_id(md.id)).unwrap();
-        let mut module_id = self.tcx.hir.as_local_node_id(module_did).unwrap();
+        let module_did = ty::DefIdTree::parent(
+            self.tcx,
+            self.tcx.hir().local_def_id(md.id)
+        ).unwrap();
+        let mut module_id = self.tcx.hir().as_local_node_id(module_did).unwrap();
         let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
         let level = self.update(md.id, level);
         if level.is_none() {
@@ -391,9 +393,9 @@
 
         loop {
             let module = if module_id == ast::CRATE_NODE_ID {
-                &self.tcx.hir.krate().module
-            } else if let hir::ItemKind::Mod(ref module) = self.tcx.hir.expect_item(module_id).node
-            {
+                &self.tcx.hir().krate().module
+            } else if let hir::ItemKind::Mod(ref module) =
+                          self.tcx.hir().expect_item(module_id).node {
                 module
             } else {
                 unreachable!()
@@ -401,10 +403,10 @@
             for id in &module.item_ids {
                 self.update(id.id, level);
             }
-            let def_id = self.tcx.hir.local_def_id(module_id);
+            let def_id = self.tcx.hir().local_def_id(module_id);
             if let Some(exports) = self.tcx.module_exports(def_id) {
                 for export in exports.iter() {
-                    if let Some(node_id) = self.tcx.hir.as_local_node_id(export.def.def_id()) {
+                    if let Some(node_id) = self.tcx.hir().as_local_node_id(export.def.def_id()) {
                         self.update(node_id, level);
                     }
                 }
@@ -413,7 +415,7 @@
             if module_id == ast::CRATE_NODE_ID {
                 break
             }
-            module_id = self.tcx.hir.get_parent_node(module_id);
+            module_id = self.tcx.hir().get_parent_node(module_id);
         }
     }
 }
@@ -473,8 +475,8 @@
     }
 
     fn check_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) {
-        if let Some(node_id) = self.ev.tcx.hir.as_local_node_id(trait_ref.def_id) {
-            let item = self.ev.tcx.hir.expect_item(node_id);
+        if let Some(node_id) = self.ev.tcx.hir().as_local_node_id(trait_ref.def_id) {
+            let item = self.ev.tcx.hir().expect_item(node_id);
             self.ev.update(item.id, self.access_level);
         }
     }
@@ -495,7 +497,7 @@
         };
 
         if let Some(def_id) = ty_def_id {
-            if let Some(node_id) = self.ev.tcx.hir.as_local_node_id(def_id) {
+            if let Some(node_id) = self.ev.tcx.hir().as_local_node_id(def_id) {
                 self.ev.update(node_id, self.access_level);
             }
         }
@@ -521,10 +523,10 @@
 impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> {
     // Checks that a field in a struct constructor (expression or pattern) is accessible.
     fn check_field(&mut self,
-                   use_ctxt: Span, // Syntax context of the field name at the use site
-                   span: Span, // Span of the field pattern, e.g. `x: 0`
-                   def: &'tcx ty::AdtDef, // Definition of the struct or enum
-                   field: &'tcx ty::FieldDef) { // Definition of the field
+                   use_ctxt: Span, // syntax context of the field name at the use site
+                   span: Span, // span of the field pattern, e.g., `x: 0`
+                   def: &'tcx ty::AdtDef, // definition of the struct or enum
+                   field: &'tcx ty::FieldDef) { // definition of the field
         let ident = Ident::new(keywords::Invalid.name(), use_ctxt);
         let def_id = self.tcx.adjust_ident(ident, def.did, self.current_item).1;
         if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) {
@@ -536,14 +538,14 @@
     }
 }
 
-// Set the correct TypeckTables for the given `item_id` (or an empty table if
-// there is no TypeckTables for the item).
+// Set the correct `TypeckTables` for the given `item_id` (or an empty table if
+// there is no `TypeckTables` for the item).
 fn update_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            item_id: ast::NodeId,
                            tables: &mut &'a ty::TypeckTables<'tcx>,
                            empty_tables: &'a ty::TypeckTables<'tcx>)
                            -> &'a ty::TypeckTables<'tcx> {
-    let def_id = tcx.hir.local_def_id(item_id);
+    let def_id = tcx.hir().local_def_id(item_id);
 
     if tcx.has_typeck_tables(def_id) {
         replace(tables, tcx.typeck_tables_of(def_id))
@@ -556,12 +558,12 @@
     /// We want to visit items in the context of their containing
     /// module and so forth, so supply a crate for doing a deep walk.
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.tcx.hir)
+        NestedVisitorMap::All(&self.tcx.hir())
     }
 
     fn visit_nested_body(&mut self, body: hir::BodyId) {
         let orig_tables = replace(&mut self.tables, self.tcx.body_tables(body));
-        let body = self.tcx.hir.body(body);
+        let body = self.tcx.hir().body(body);
         self.visit_body(body);
         self.tables = orig_tables;
     }
@@ -657,19 +659,19 @@
 
 impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
     fn def_id_visibility(&self, did: DefId) -> ty::Visibility {
-        match self.tcx.hir.as_local_node_id(did) {
+        match self.tcx.hir().as_local_node_id(did) {
             Some(node_id) => {
-                let vis = match self.tcx.hir.get(node_id) {
+                let vis = match self.tcx.hir().get(node_id) {
                     Node::Item(item) => &item.vis,
                     Node::ForeignItem(foreign_item) => &foreign_item.vis,
                     Node::ImplItem(impl_item) => &impl_item.vis,
                     Node::TraitItem(..) |
                     Node::Variant(..) => {
-                        return self.def_id_visibility(self.tcx.hir.get_parent_did(node_id));
+                        return self.def_id_visibility(self.tcx.hir().get_parent_did(node_id));
                     }
                     Node::StructCtor(vdata) => {
-                        let struct_node_id = self.tcx.hir.get_parent(node_id);
-                        let struct_vis = match self.tcx.hir.get(struct_node_id) {
+                        let struct_node_id = self.tcx.hir().get_parent(node_id);
+                        let struct_vis = match self.tcx.hir().get(struct_node_id) {
                             Node::Item(item) => &item.vis,
                             node => bug!("unexpected node kind: {:?}", node),
                         };
@@ -684,7 +686,7 @@
 
                         // If the structure is marked as non_exhaustive then lower the
                         // visibility to within the crate.
-                        let struct_def_id = self.tcx.hir.get_parent_did(node_id);
+                        let struct_def_id = self.tcx.hir().get_parent_did(node_id);
                         let adt_def = self.tcx.adt_def(struct_def_id);
                         if adt_def.non_enum_variant().is_field_list_non_exhaustive()
                             && ctor_vis == ty::Visibility::Public
@@ -707,7 +709,7 @@
         self.def_id_visibility(did).is_accessible_from(self.current_item, self.tcx)
     }
 
-    // Take node ID of an expression or pattern and check its type for privacy.
+    // Take node-id of an expression or pattern and check its type for privacy.
     fn check_expr_pat_type(&mut self, id: hir::HirId, span: Span) -> bool {
         self.span = span;
         if self.tables.node_id_to_type(id).visit_with(self) {
@@ -741,13 +743,13 @@
     /// We want to visit items in the context of their containing
     /// module and so forth, so supply a crate for doing a deep walk.
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.tcx.hir)
+        NestedVisitorMap::All(&self.tcx.hir())
     }
 
     fn visit_nested_body(&mut self, body: hir::BodyId) {
         let orig_tables = replace(&mut self.tables, self.tcx.body_tables(body));
         let orig_in_body = replace(&mut self.in_body, true);
-        let body = self.tcx.hir.body(body);
+        let body = self.tcx.hir().body(body);
         self.visit_body(body);
         self.tables = orig_tables;
         self.in_body = orig_in_body;
@@ -859,7 +861,7 @@
         intravisit::walk_qpath(self, qpath, id, span);
     }
 
-    // Check types of patterns
+    // Check types of patterns.
     fn visit_pat(&mut self, pattern: &'tcx hir::Pat) {
         if self.check_expr_pat_type(pattern.hir_id, pattern.span) {
             // Do not check nested patterns if the error already happened.
@@ -880,7 +882,7 @@
         intravisit::walk_local(self, local);
     }
 
-    // Check types in item interfaces
+    // Check types in item interfaces.
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         let orig_current_item = self.current_item;
         let orig_tables = update_tables(self.tcx,
@@ -888,7 +890,7 @@
                                         &mut self.tables,
                                         self.empty_tables);
         let orig_in_body = replace(&mut self.in_body, false);
-        self.current_item = self.tcx.hir.local_def_id(item.id);
+        self.current_item = self.tcx.hir().local_def_id(item.id);
         intravisit::walk_item(self, item);
         self.tables = orig_tables;
         self.in_body = orig_in_body;
@@ -1012,18 +1014,18 @@
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     access_levels: &'a AccessLevels,
     in_variant: bool,
-    // set of errors produced by this obsolete visitor
+    // Set of errors produced by this obsolete visitor.
     old_error_set: NodeSet,
 }
 
 struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b: 'a, 'tcx: 'b> {
     inner: &'a ObsoleteVisiblePrivateTypesVisitor<'b, 'tcx>,
-    /// whether the type refers to private types.
+    /// Whether the type refers to private types.
     contains_private: bool,
-    /// whether we've recurred at all (i.e. if we're pointing at the
-    /// first type on which visit_ty was called).
+    /// Whether we've recurred at all (i.e., if we're pointing at the
+    /// first type on which `visit_ty` was called).
     at_outer_type: bool,
-    // whether that first type is a public path.
+    /// Whether that first type is a public path.
     outer_type_is_public_path: bool,
 }
 
@@ -1036,10 +1038,10 @@
 
         // A path can only be private if:
         // it's in this crate...
-        if let Some(node_id) = self.tcx.hir.as_local_node_id(did) {
+        if let Some(node_id) = self.tcx.hir().as_local_node_id(did) {
             // .. and it corresponds to a private type in the AST (this returns
-            // None for type parameters)
-            match self.tcx.hir.find(node_id) {
+            // `None` for type parameters).
+            match self.tcx.hir().find(node_id) {
                 Some(Node::Item(ref item)) => !item.vis.node.is_pub(),
                 Some(_) | None => false,
             }
@@ -1050,7 +1052,7 @@
 
     fn trait_is_public(&self, trait_id: ast::NodeId) -> bool {
         // FIXME: this would preferably be using `exported_items`, but all
-        // traits are exported currently (see `EmbargoVisitor.exported_trait`)
+        // traits are exported currently (see `EmbargoVisitor.exported_trait`).
         self.access_levels.is_public(trait_id)
     }
 
@@ -1076,8 +1078,7 @@
         if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = ty.node {
             if self.inner.path_is_private_type(path) {
                 self.contains_private = true;
-                // found what we're looking for so let's stop
-                // working.
+                // Found what we're looking for, so let's stop working.
                 return
             }
         }
@@ -1090,7 +1091,7 @@
         intravisit::walk_ty(self, ty)
     }
 
-    // don't want to recurse into [, .. expr]
+    // Don't want to recurse into `[, .. expr]`.
     fn visit_expr(&mut self, _: &hir::Expr) {}
 }
 
@@ -1098,12 +1099,12 @@
     /// We want to visit items in the context of their containing
     /// module and so forth, so supply a crate for doing a deep walk.
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.tcx.hir)
+        NestedVisitorMap::All(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         match item.node {
-            // contents of a private mod can be re-exported, so we need
+            // Contents of a private mod can be re-exported, so we need
             // to check internals.
             hir::ItemKind::Mod(_) => {}
 
@@ -1121,19 +1122,19 @@
                 }
             }
 
-            // impls need some special handling to try to offer useful
+            // Impls need some special handling to try to offer useful
             // error messages without (too many) false positives
-            // (i.e. we could just return here to not check them at
+            // (i.e., we could just return here to not check them at
             // all, or some worse estimation of whether an impl is
             // publicly visible).
             hir::ItemKind::Impl(.., ref g, ref trait_ref, ref self_, ref impl_item_refs) => {
                 // `impl [... for] Private` is never visible.
                 let self_contains_private;
-                // impl [... for] Public<...>, but not `impl [... for]
-                // Vec<Public>` or `(Public,)` etc.
+                // `impl [... for] Public<...>`, but not `impl [... for]
+                // Vec<Public>` or `(Public,)`, etc.
                 let self_is_public_path;
 
-                // check the properties of the Self type:
+                // Check the properties of the `Self` type:
                 {
                     let mut visitor = ObsoleteCheckTypeForPrivatenessVisitor {
                         inner: self,
@@ -1146,7 +1147,7 @@
                     self_is_public_path = visitor.outer_type_is_public_path;
                 }
 
-                // miscellaneous info about the impl
+                // Miscellaneous info about the impl:
 
                 // `true` iff this is `impl Private for ...`.
                 let not_private_trait =
@@ -1154,7 +1155,7 @@
                                               |tr| {
                         let did = tr.path.def.def_id();
 
-                        if let Some(node_id) = self.tcx.hir.as_local_node_id(did) {
+                        if let Some(node_id) = self.tcx.hir().as_local_node_id(did) {
                             self.trait_is_public(node_id)
                         } else {
                             true // external traits must be public
@@ -1173,7 +1174,7 @@
                     trait_ref.is_some() ||
                     impl_item_refs.iter()
                                  .any(|impl_item_ref| {
-                                     let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
+                                     let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                                      match impl_item.node {
                                          hir::ImplItemKind::Const(..) |
                                          hir::ImplItemKind::Method(..) => {
@@ -1198,7 +1199,7 @@
                                 // should only walk into public items so that we
                                 // don't erroneously report errors for private
                                 // types in private items.
-                                let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
+                                let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                                 match impl_item.node {
                                     hir::ImplItemKind::Const(..) |
                                     hir::ImplItemKind::Method(..)
@@ -1231,7 +1232,7 @@
 
                             // Those in 3. are warned with this call.
                             for impl_item_ref in impl_item_refs {
-                                let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
+                                let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                                 if let hir::ImplItemKind::Type(ref ty) = impl_item.node {
                                     self.visit_ty(ty);
                                 }
@@ -1239,12 +1240,12 @@
                         }
                     }
                 } else if trait_ref.is_none() && self_is_public_path {
-                    // impl Public<Private> { ... }. Any public static
+                    // `impl Public<Private> { ... }`. Any public static
                     // methods will be visible as `Public::foo`.
                     let mut found_pub_static = false;
                     for impl_item_ref in impl_item_refs {
                         if self.item_is_public(&impl_item_ref.id.node_id, &impl_item_ref.vis) {
-                            let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
+                            let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                             match impl_item_ref.kind {
                                 hir::AssociatedItemKind::Const => {
                                     found_pub_static = true;
@@ -1269,7 +1270,7 @@
             // we're introducing a new name.
             hir::ItemKind::Ty(..) => return,
 
-            // not at all public, so we don't care
+            // Not at all public, so we don't care.
             _ if !self.item_is_public(&item.id, &item.vis) => {
                 return;
             }
@@ -1279,7 +1280,7 @@
 
         // We've carefully constructed it so that if we're here, then
         // any `visit_ty`'s will be called on things that are in
-        // public signatures, i.e. things that we're interested in for
+        // public signatures, i.e., things that we're interested in for
         // this visitor.
         intravisit::walk_item(self, item);
     }
@@ -1337,7 +1338,7 @@
         }
     }
 
-    // we don't need to introspect into these at all: an
+    // We don't need to introspect into these at all: an
     // expression/block context can't possibly contain exported things.
     // (Making them no-ops stops us from traversing the whole AST without
     // having to be super careful about our `walk_...` calls above.)
@@ -1356,9 +1357,9 @@
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     item_def_id: DefId,
     span: Span,
-    /// The visitor checks that each component type is at least this visible
+    /// The visitor checks that each component type is at least this visible.
     required_visibility: ty::Visibility,
-    /// The visibility of the least visible component that has been visited
+    /// The visibility of the least visible component that has been visited.
     min_visibility: ty::Visibility,
     has_pub_restricted: bool,
     has_old_errors: bool,
@@ -1381,7 +1382,7 @@
     }
 
     fn predicates(&mut self) -> &mut Self {
-        // NB: We use `explicit_predicates_of` and not `predicates_of`
+        // N.B., we use `explicit_predicates_of` and not `predicates_of`
         // because we don't want to report privacy errors due to where
         // clauses that the compiler inferred. We only want to
         // consider the ones that the user wrote. This is important
@@ -1426,9 +1427,9 @@
     }
 
     fn check_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) {
-        // Non-local means public (private items can't leave their crate, modulo bugs)
-        if let Some(node_id) = self.tcx.hir.as_local_node_id(trait_ref.def_id) {
-            let item = self.tcx.hir.expect_item(node_id);
+        // Non-local means public (private items can't leave their crate, modulo bugs).
+        if let Some(node_id) = self.tcx.hir().as_local_node_id(trait_ref.def_id) {
+            let item = self.tcx.hir().expect_item(node_id);
             let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx);
             if !vis.is_at_least(self.min_visibility, self.tcx) {
                 self.min_visibility = vis;
@@ -1475,9 +1476,9 @@
         };
 
         if let Some(def_id) = ty_def_id {
-            // Non-local means public (private items can't leave their crate, modulo bugs)
-            if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
-                let hir_vis = match self.tcx.hir.find(node_id) {
+            // Non-local means public (private items can't leave their crate, modulo bugs).
+            if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
+                let hir_vis = match self.tcx.hir().find(node_id) {
                     Some(Node::Item(item)) => &item.vis,
                     Some(Node::ForeignItem(item)) => &item.vis,
                     _ => bug!("expected item of foreign item"),
@@ -1537,7 +1538,7 @@
                     has_old_errors = true;
                     break;
                 }
-                let parent = self.tcx.hir.get_parent_node(id);
+                let parent = self.tcx.hir().get_parent_node(id);
                 if parent == id {
                     break;
                 }
@@ -1551,8 +1552,8 @@
 
         SearchInterfaceForPrivateItemsVisitor {
             tcx: self.tcx,
-            item_def_id: self.tcx.hir.local_def_id(item_id),
-            span: self.tcx.hir.span(item_id),
+            item_def_id: self.tcx.hir().local_def_id(item_id),
+            span: self.tcx.hir().span(item_id),
             min_visibility: ty::Visibility::Public,
             required_visibility,
             has_pub_restricted: self.has_pub_restricted,
@@ -1564,7 +1565,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
@@ -1576,30 +1577,29 @@
         let item_visibility = ty::Visibility::from_hir(&item.vis, item.id, tcx);
 
         match item.node {
-            // Crates are always public
+            // Crates are always public.
             hir::ItemKind::ExternCrate(..) => {}
-            // All nested items are checked by visit_item
+            // All nested items are checked by `visit_item`.
             hir::ItemKind::Mod(..) => {}
-            // Checked in resolve
+            // Checked in resolve.
             hir::ItemKind::Use(..) => {}
-            // No subitems
+            // No subitems.
             hir::ItemKind::GlobalAsm(..) => {}
             hir::ItemKind::Existential(hir::ExistTy { impl_trait_fn: Some(_), .. }) => {
                 // Check the traits being exposed, as they're separate,
-                // e.g. `impl Iterator<Item=T>` has two predicates,
+                // e.g., `impl Iterator<Item=T>` has two predicates,
                 // `X: Iterator` and `<X as Iterator>::Item == T`,
                 // where `X` is the `impl Iterator<Item=T>` itself,
                 // stored in `predicates_of`, not in the `Ty` itself.
-
                 self.check(item.id, item_visibility).predicates();
             }
-            // Subitems of these items have inherited publicity
+            // Subitems of these items have inherited publicity.
             hir::ItemKind::Const(..) | hir::ItemKind::Static(..) | hir::ItemKind::Fn(..) |
             hir::ItemKind::Existential(..) |
             hir::ItemKind::Ty(..) => {
                 self.check(item.id, item_visibility).generics().predicates().ty();
 
-                // Recurse for e.g. `impl Trait` (see `visit_ty`).
+                // Recurse for e.g., `impl Trait` (see `visit_ty`).
                 self.inner_visibility = item_visibility;
                 intravisit::walk_item(self, item);
             }
@@ -1631,14 +1631,14 @@
                     }
                 }
             }
-            // Subitems of foreign modules have their own publicity
+            // Subitems of foreign modules have their own publicity.
             hir::ItemKind::ForeignMod(ref foreign_mod) => {
                 for foreign_item in &foreign_mod.items {
                     let vis = ty::Visibility::from_hir(&foreign_item.vis, item.id, tcx);
                     self.check(foreign_item.id, vis).generics().predicates().ty();
                 }
             }
-            // Subitems of structs and unions have their own publicity
+            // Subitems of structs and unions have their own publicity.
             hir::ItemKind::Struct(ref struct_def, _) |
             hir::ItemKind::Union(ref struct_def, _) => {
                 self.check(item.id, item_visibility).generics().predicates();
@@ -1649,37 +1649,37 @@
                 }
             }
             // An inherent impl is public when its type is public
-            // Subitems of inherent impls have their own publicity
+            // Subitems of inherent impls have their own publicity.
             hir::ItemKind::Impl(.., None, _, ref impl_item_refs) => {
                 let ty_vis =
                     self.check(item.id, ty::Visibility::Invisible).ty().min_visibility;
                 self.check(item.id, ty_vis).generics().predicates();
 
                 for impl_item_ref in impl_item_refs {
-                    let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
+                    let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                     let impl_item_vis = ty::Visibility::from_hir(&impl_item.vis, item.id, tcx);
                     let mut check = self.check(impl_item.id, min(impl_item_vis, ty_vis));
                     check.in_assoc_ty = impl_item_ref.kind == hir::AssociatedItemKind::Type;
                     check.generics().predicates().ty();
 
-                    // Recurse for e.g. `impl Trait` (see `visit_ty`).
+                    // Recurse for e.g., `impl Trait` (see `visit_ty`).
                     self.inner_visibility = impl_item_vis;
                     intravisit::walk_impl_item(self, impl_item);
                 }
             }
             // A trait impl is public when both its type and its trait are public
-            // Subitems of trait impls have inherited publicity
+            // Subitems of trait impls have inherited publicity.
             hir::ItemKind::Impl(.., Some(_), _, ref impl_item_refs) => {
                 let vis = self.check(item.id, ty::Visibility::Invisible)
                               .ty().impl_trait_ref().min_visibility;
                 self.check(item.id, vis).generics().predicates();
                 for impl_item_ref in impl_item_refs {
-                    let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
+                    let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                     let mut check = self.check(impl_item.id, vis);
                     check.in_assoc_ty = impl_item_ref.kind == hir::AssociatedItemKind::Type;
                     check.generics().predicates().ty();
 
-                    // Recurse for e.g. `impl Trait` (see `visit_ty`).
+                    // Recurse for e.g., `impl Trait` (see `visit_ty`).
                     self.inner_visibility = vis;
                     intravisit::walk_impl_item(self, impl_item);
                 }
@@ -1688,12 +1688,12 @@
     }
 
     fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) {
-        // handled in `visit_item` above
+        // Handled in `visit_item` above.
     }
 
-    // Don't recurse into expressions in array sizes or const initializers
+    // Don't recurse into expressions in array sizes or const initializers.
     fn visit_expr(&mut self, _: &'tcx hir::Expr) {}
-    // Don't recurse into patterns in function arguments
+    // Don't recurse into patterns in function arguments.
     fn visit_pat(&mut self, _: &'tcx hir::Pat) {}
 }
 
@@ -1713,7 +1713,7 @@
                                    -> Lrc<AccessLevels> {
     assert_eq!(krate, LOCAL_CRATE);
 
-    let krate = tcx.hir.krate();
+    let krate = tcx.hir().krate();
     let empty_tables = ty::TypeckTables::empty(None);
 
     // Check privacy of names not checked in previous compilation stages.
@@ -1775,7 +1775,7 @@
             pub_restricted_visitor.has_pub_restricted
         };
 
-        // Check for private types and traits in public interfaces
+        // Check for private types and traits in public interfaces.
         let mut visitor = PrivateItemsInPublicInterfacesVisitor {
             tcx,
             has_pub_restricted,
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index da4cd73..191e4e8 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -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)),
@@ -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,13 +349,13 @@
             }
 
             ItemKind::ExternCrate(orig_name) => {
-                let module = if orig_name.is_none() && ident.name == keywords::SelfValue.name() {
+                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::SelfValue.name()) {
+                } 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");
@@ -623,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 {
@@ -783,7 +792,7 @@
                         "an `extern crate` loading macros must be at the crate root");
                 }
                 if let ItemKind::ExternCrate(Some(orig_name)) = item.node {
-                    if orig_name == keywords::SelfValue.name() {
+                    if orig_name == keywords::SelfLower.name() {
                         self.session.span_err(attr.span,
                             "`macro_use` is not supported on `extern crate self`");
                     }
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 2681295..7730239 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -295,9 +295,8 @@
 Erroneous code example:
 
 ```compile_fail,E0259
-# #![feature(libc)]
 extern crate core;
-extern crate libc as core;
+extern crate std as core;
 
 fn main() {}
 ```
@@ -308,9 +307,8 @@
 Correct example:
 
 ```
-# #![feature(libc)]
 extern crate core;
-extern crate libc as other_name;
+extern crate std as other_name;
 
 fn main() {}
 ```
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 fdac1e3..e449fec 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -84,7 +84,7 @@
 use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
 use macros::{InvocationData, LegacyBinding, ParentScope};
 
-// NB: This module needs to be declared first so diagnostics are
+// N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
 mod diagnostics;
 mod error_reporting;
@@ -638,7 +638,7 @@
 
 // A minimal representation of a path segment. We use this in resolve because
 // we synthesize 'path segments' which don't have the rest of an AST or HIR
-// PathSegment.
+// `PathSegment`.
 #[derive(Clone, Copy, Debug)]
 pub struct Segment {
     ident: Ident,
@@ -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,
@@ -1584,7 +1588,6 @@
     macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
     macro_defs: FxHashMap<Mark, DefId>,
     local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
-    pub whitelisted_legacy_custom_derives: Vec<Name>,
     pub found_unresolved_macro: bool,
 
     /// List of crate local macros that we need to warn about as being unused.
@@ -1679,7 +1682,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 +1724,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 +1874,7 @@
             current_self_type: None,
             current_self_item: None,
             last_import_segment: false,
+            blacklisted_binding: None,
 
             primitive_type_table: PrimitiveTypeTable::new(),
 
@@ -1917,7 +1921,6 @@
             macro_defs,
             local_macro_def_scopes: FxHashMap::default(),
             name_already_seen: FxHashMap::default(),
-            whitelisted_legacy_custom_derives: Vec::new(),
             potentially_unused_imports: Vec::new(),
             struct_constructors: Default::default(),
             found_unresolved_macro: false,
@@ -2036,7 +2039,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 {
@@ -2605,7 +2608,7 @@
         result
     }
 
-    /// This is called to resolve a trait reference from an `impl` (i.e. `impl Trait for Foo`)
+    /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`)
     fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
         where F: FnOnce(&mut Resolver, Option<DefId>) -> T
     {
@@ -2649,7 +2652,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();
@@ -2660,7 +2663,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();
@@ -2887,7 +2890,7 @@
             self.resolve_pattern(&pattern, PatternSource::Match, &mut bindings_list);
         }
 
-        // This has to happen *after* we determine which pat_idents are variants
+        // This has to happen *after* we determine which pat_idents are variants.
         self.check_consistent_bindings(&arm.pats);
 
         if let Some(ast::Guard::If(ref expr)) = arm.guard {
@@ -3007,6 +3010,7 @@
         // Visit all direct subpatterns of this pattern.
         let outer_pat_id = pat.id;
         pat.walk(&mut |pat| {
+            debug!("resolve_pattern pat={:?} node={:?}", pat, pat.node);
             match pat.node {
                 PatKind::Ident(bmode, ident, ref opt_pat) => {
                     // First try to resolve the identifier as some existing
@@ -3029,8 +3033,8 @@
                             Def::StructCtor(..) | Def::VariantCtor(..) |
                             Def::Const(..) | Def::Static(..) => {
                                 // This is unambiguously a fresh binding, either syntactically
-                                // (e.g. `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
-                                // to something unusable as a pattern (e.g. constructor function),
+                                // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
+                                // to something unusable as a pattern (e.g., constructor function),
                                 // but we still conservatively report an error, see
                                 // issues/33118#issuecomment-233962221 for one reason why.
                                 resolve_error(
@@ -3146,7 +3150,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];
@@ -3163,6 +3167,7 @@
                  format!("not found in {}", mod_str),
                  item_span)
             };
+
             let code = DiagnosticId::Error(code.into());
             let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
 
@@ -3186,11 +3191,22 @@
                 return (err, Vec::new());
             }
             if is_self_value(path, ns) {
+                debug!("smart_resolve_path_fragment E0424 source:{:?}", source);
+
                 __diagnostic_used!(E0424);
                 err.code(DiagnosticId::Error("E0424".into()));
-                err.span_label(span, format!("`self` value is a keyword \
-                                               only available in \
-                                               methods with `self` parameter"));
+                err.span_label(span, match source {
+                    PathSource::Pat => {
+                        format!("`self` value is a keyword \
+                                and may not be bound to \
+                                variables or shadowed")
+                    }
+                    _ => {
+                        format!("`self` value is a keyword \
+                                only available in methods \
+                                with `self` parameter")
+                    }
+                });
                 return (err, Vec::new());
             }
 
@@ -3206,9 +3222,9 @@
                 for (sp, variant_path, enum_path) in enum_candidates {
                     if sp.is_dummy() {
                         let msg = format!("there is an enum variant `{}`, \
-                                        try using `{}`?",
-                                        variant_path,
-                                        enum_path);
+                                           try using `{}`?",
+                                          variant_path,
+                                          enum_path);
                         err.help(&msg);
                     } else {
                         err.span_suggestion_with_applicability(
@@ -3260,7 +3276,7 @@
 
             let mut levenshtein_worked = false;
 
-            // Try Levenshtein.
+            // Try Levenshtein algorithm.
             if let Some(candidate) = this.lookup_typo_candidate(path, ns, is_expected, span) {
                 err.span_label(ident_span, format!("did you mean `{}`?", candidate));
                 levenshtein_worked = true;
@@ -3515,13 +3531,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 }
     }
@@ -3614,7 +3630,7 @@
             let res = self.smart_resolve_path_fragment(
                 id,
                 None,
-                &path[..qself.position + 1],
+                &path[..=qself.position],
                 span,
                 PathSource::TraitItem(ns),
                 CrateLint::QPathTrait {
@@ -3673,7 +3689,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(
@@ -3755,7 +3771,7 @@
             let name = ident.name;
 
             allow_super &= ns == TypeNS &&
-                (name == keywords::SelfValue.name() ||
+                (name == keywords::SelfLower.name() ||
                  name == keywords::Super.name());
 
             if ns == TypeNS {
@@ -3779,24 +3795,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`
@@ -3809,12 +3825,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)
@@ -3944,7 +3960,7 @@
 
         // 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
         }
 
@@ -3953,7 +3969,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,
@@ -4322,7 +4338,7 @@
                     for pat in pats {
                         this.resolve_pattern(pat, PatternSource::WhileLet, &mut bindings_list);
                     }
-                    // This has to happen *after* we determine which pat_idents are variants
+                    // This has to happen *after* we determine which pat_idents are variants.
                     this.check_consistent_bindings(pats);
                     this.visit_block(block);
                     this.ribs[ValueNS].pop();
@@ -4608,7 +4624,7 @@
     /// When name resolution fails, this method can be used to look up candidate
     /// entities with the expected name. It allows filtering them using the
     /// supplied predicate (which should be used to only accept the types of
-    /// definitions expected e.g. traits). The lookup spans across all crates.
+    /// definitions expected e.g., traits). The lookup spans across all crates.
     ///
     /// NOTE: The method does not look into imports, but this is not a problem,
     /// since we report the definitions (thus, the de-aliased imports).
@@ -4740,7 +4756,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)
                     )))
                 };
 
@@ -5090,17 +5106,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..3f57c74 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -21,22 +21,18 @@
 use rustc::hir::def::{Def, NonMacroAttrKind};
 use rustc::hir::map::{self, DefCollector};
 use rustc::{ty, lint};
-use syntax::ast::{self, Name, Ident};
+use syntax::ast::{self, Ident};
 use syntax::attr;
 use syntax::errors::DiagnosticBuilder;
 use syntax::ext::base::{self, Determinacy};
-use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
+use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
 use syntax::ext::hygiene::{self, Mark};
 use syntax::ext::tt::macro_rules;
-use syntax::feature_gate::{self, feature_err, emit_feature_err, is_builtin_attr_name, GateIssue};
-use syntax::feature_gate::EXPLAIN_DERIVE_UNDERSCORE;
+use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue};
 use syntax::fold::{self, Folder};
-use syntax::parse::parser::PathStyle;
-use syntax::parse::token::{self, Token};
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, keywords};
-use syntax::tokenstream::{TokenStream, TokenTree, Delimited, DelimSpan};
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::{Span, DUMMY_SP};
 use errors::Applicability;
@@ -167,7 +163,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 {
@@ -194,10 +190,6 @@
         ret.into_iter().next().unwrap()
     }
 
-    fn is_whitelisted_legacy_custom_derive(&self, name: Name) -> bool {
-        self.whitelisted_legacy_custom_derives.contains(&name)
-    }
-
     fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
                                             derives: &[Mark]) {
         let invocation = self.invocations[&mark];
@@ -240,79 +232,6 @@
         ImportResolver { resolver: self }.resolve_imports()
     }
 
-    // Resolves attribute and derive legacy macros from `#![plugin(..)]`.
-    fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_derive: bool)
-                              -> Option<ast::Attribute> {
-        if !allow_derive {
-            return None;
-        }
-
-        // Check for legacy derives
-        for i in 0..attrs.len() {
-            let name = attrs[i].name();
-
-            if name == "derive" {
-                let result = attrs[i].parse_list(&self.session.parse_sess, |parser| {
-                    parser.parse_path_allowing_meta(PathStyle::Mod)
-                });
-
-                let mut traits = match result {
-                    Ok(traits) => traits,
-                    Err(mut e) => {
-                        e.cancel();
-                        continue
-                    }
-                };
-
-                for j in 0..traits.len() {
-                    if traits[j].segments.len() > 1 {
-                        continue
-                    }
-                    let trait_name = traits[j].segments[0].ident.name;
-                    let legacy_name = Symbol::intern(&format!("derive_{}", trait_name));
-                    if !self.builtin_macros.contains_key(&legacy_name) {
-                        continue
-                    }
-                    let span = traits.remove(j).span;
-                    self.gate_legacy_custom_derive(legacy_name, span);
-                    if traits.is_empty() {
-                        attrs.remove(i);
-                    } else {
-                        let mut tokens = Vec::with_capacity(traits.len() - 1);
-                        for (j, path) in traits.iter().enumerate() {
-                            if j > 0 {
-                                tokens.push(TokenTree::Token(attrs[i].span, Token::Comma).into());
-                            }
-                            tokens.reserve((path.segments.len() * 2).saturating_sub(1));
-                            for (k, segment) in path.segments.iter().enumerate() {
-                                if k > 0 {
-                                    tokens.push(TokenTree::Token(path.span, Token::ModSep).into());
-                                }
-                                let tok = Token::from_ast_ident(segment.ident);
-                                tokens.push(TokenTree::Token(path.span, tok).into());
-                            }
-                        }
-                        let delim_span = DelimSpan::from_single(attrs[i].span);
-                        attrs[i].tokens = TokenTree::Delimited(delim_span, Delimited {
-                            delim: token::Paren,
-                            tts: TokenStream::concat(tokens).into(),
-                        }).into();
-                    }
-                    return Some(ast::Attribute {
-                        path: ast::Path::from_ident(Ident::new(legacy_name, span)),
-                        tokens: TokenStream::empty(),
-                        id: attr::mk_attr_id(),
-                        style: ast::AttrStyle::Outer,
-                        is_sugared_doc: false,
-                        span,
-                    });
-                }
-            }
-        }
-
-        None
-    }
-
     fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool)
                                 -> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
         let (path, kind, derives_in_scope, after_derive) = match invoc.kind {
@@ -430,11 +349,6 @@
                                 feature_err(&self.session.parse_sess, "rustc_attrs", path.span,
                                             GateIssue::Language, &msg).emit();
                             }
-                        } else if name.starts_with("derive_") {
-                            if !features.custom_derive {
-                                feature_err(&self.session.parse_sess, "custom_derive", path.span,
-                                            GateIssue::Language, EXPLAIN_DERIVE_UNDERSCORE).emit();
-                            }
                         } else if !features.custom_attribute {
                             let msg = format!("The attribute `{}` is currently unknown to the \
                                                compiler and may have meaning added to it in the \
@@ -445,7 +359,7 @@
                     }
                 } else {
                     // Not only attributes, but anything in macro namespace can result in
-                    // `Def::NonMacroAttr` definition (e.g. `inline!()`), so we must report
+                    // `Def::NonMacroAttr` definition (e.g., `inline!()`), so we must report
                     // an error for those cases.
                     let msg = format!("expected a macro, found {}", def.kind_name());
                     self.session.span_err(path.span, &msg);
@@ -522,7 +436,7 @@
     // Resolve an identifier in lexical scope.
     // This is a variation of `fn resolve_ident_in_lexical_scope` that can be run during
     // expansion and import resolution (perhaps they can be merged in the future).
-    // The function is used for resolving initial segments of macro paths (e.g. `foo` in
+    // The function is used for resolving initial segments of macro paths (e.g., `foo` in
     // `foo::bar!(); or `foo!();`) and also for import paths on 2018 edition.
     crate fn early_resolve_ident_in_lexical_scope(
         &mut self,
@@ -674,7 +588,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 +874,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 +891,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();
             }
 
@@ -1216,14 +1132,4 @@
             self.define(module, ident, MacroNS, (def, vis, item.span, expansion));
         }
     }
-
-    fn gate_legacy_custom_derive(&mut self, name: Symbol, span: Span) {
-        if !self.session.features_untracked().custom_derive {
-            let sess = &self.session.parse_sess;
-            let explain = feature_gate::EXPLAIN_CUSTOM_DERIVE;
-            emit_feature_err(sess, "custom_derive", span, GateIssue::Language, explain);
-        } else if !self.is_whitelisted_legacy_custom_derive(name) {
-            self.session.span_warn(span, feature_gate::EXPLAIN_DEPR_CUSTOM_DERIVE);
-        }
-    }
 }
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index e7cd32f..015cd31 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();
@@ -419,7 +430,7 @@
     crate fn import(&self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
                     -> &'a NameBinding<'a> {
         let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) ||
-                     // c.f. `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
+                     // cf. `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
                      !directive.is_glob() && binding.is_extern_crate() {
             directive.vis.get()
         } else {
@@ -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);
@@ -829,14 +843,16 @@
         self.current_module = directive.parent_scope.module;
 
         let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
+        let prev_ambiguity_errors_len = self.ambiguity_errors.len();
         let path_res = self.resolve_path(&directive.module_path, None, &directive.parent_scope,
                                          true, directive.span, directive.crate_lint());
+        let no_ambiguity = self.ambiguity_errors.len() == prev_ambiguity_errors_len;
         directive.vis.set(orig_vis);
         let module = match path_res {
             PathResult::Module(module) => {
                 // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
                 if let Some(initial_module) = directive.imported_module.get() {
-                    if module != initial_module && self.ambiguity_errors.is_empty() {
+                    if module != initial_module && no_ambiguity {
                         span_bug!(directive.span, "inconsistent resolution for an import");
                     }
                 } else {
@@ -850,37 +866,42 @@
                 module
             }
             PathResult::Failed(span, msg, false) => {
-                assert!(!self.ambiguity_errors.is_empty() ||
-                        directive.imported_module.get().is_none());
-                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
+                if no_ambiguity {
+                    assert!(directive.imported_module.get().is_none());
+                    resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
+                }
                 return None;
             }
             PathResult::Failed(span, msg, true) => {
-                assert!(!self.ambiguity_errors.is_empty() ||
-                        directive.imported_module.get().is_none());
-                return if let Some((suggested_path, note)) = self.make_path_suggestion(
-                    span, directive.module_path.clone(), &directive.parent_scope
-                ) {
-                    Some((
-                        span,
-                        format!("did you mean `{}`?", Segment::names_to_string(&suggested_path)),
-                        note,
-                    ))
-                } else {
-                    Some((span, msg, None))
-                };
+                if no_ambiguity {
+                    assert!(directive.imported_module.get().is_none());
+                    return Some(match self.make_path_suggestion(span, directive.module_path.clone(),
+                                                                &directive.parent_scope) {
+                        Some((suggestion, note)) => (
+                            span,
+                            format!("did you mean `{}`?", Segment::names_to_string(&suggestion)),
+                            note,
+                        ),
+                        None => (span, msg, None),
+                    });
+                }
+                return None;
             }
             PathResult::NonModule(path_res) if path_res.base_def() == Def::Err => {
+                if no_ambiguity {
+                    assert!(directive.imported_module.get().is_none());
+                }
                 // The error was already reported earlier.
-                assert!(!self.ambiguity_errors.is_empty() ||
-                        directive.imported_module.get().is_none());
                 return None;
             }
             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 +940,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();
@@ -986,7 +1015,7 @@
                                 NameBindingKind::Import { binding, .. } => {
                                     match binding.kind {
                                         // Never suggest the name that has binding error
-                                        // i.e. the name that cannot be previously resolved
+                                        // i.e., the name that cannot be previously resolved
                                         NameBindingKind::Def(Def::Err, _) => return None,
                                         _ => Some(&i.name),
                                     }
@@ -1034,7 +1063,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 +1107,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 +1121,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 +1292,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_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 15c8861..b1c1c96 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -126,7 +126,7 @@
     where
         F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, O>),
     {
-        let item_def_id = self.tcx.hir.local_def_id(item_id);
+        let item_def_id = self.tcx.hir().local_def_id(item_id);
         if self.tcx.has_typeck_tables(item_def_id) {
             let tables = self.tcx.typeck_tables_of(item_def_id);
             let old_tables = self.save_ctxt.tables;
@@ -249,7 +249,7 @@
             collector.visit_pat(&arg.pat);
 
             for (id, ident, ..) in collector.collected_idents {
-                let hir_id = self.tcx.hir.node_to_hir_id(id);
+                let hir_id = self.tcx.hir().node_to_hir_id(id);
                 let typ = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) {
                     Some(s) => s.to_string(),
                     None => continue,
@@ -673,7 +673,7 @@
         }
         self.process_generic_params(type_parameters, "", item.id);
         for impl_item in impl_items {
-            let map = &self.tcx.hir;
+            let map = &self.tcx.hir();
             self.process_impl_item(impl_item, map.local_def_id(item.id));
         }
     }
@@ -752,7 +752,7 @@
         // walk generics and methods
         self.process_generic_params(generics, &qualname, item.id);
         for method in methods {
-            let map = &self.tcx.hir;
+            let map = &self.tcx.hir();
             self.process_trait_item(method, map.local_def_id(item.id))
         }
     }
@@ -866,7 +866,7 @@
         match p.node {
             PatKind::Struct(ref _path, ref fields, _) => {
                 // FIXME do something with _path?
-                let hir_id = self.tcx.hir.node_to_hir_id(p.id);
+                let hir_id = self.tcx.hir().node_to_hir_id(p.id);
                 let adt = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) {
                     Some(ty) => ty.ty_adt_def().unwrap(),
                     None => {
@@ -911,7 +911,7 @@
                     } else {
                         "<mutable>".to_owned()
                     };
-                    let hir_id = self.tcx.hir.node_to_hir_id(id);
+                    let hir_id = self.tcx.hir().node_to_hir_id(id);
                     let typ = self.save_ctxt
                         .tables
                         .node_id_to_type_opt(hir_id)
@@ -982,7 +982,7 @@
                 ast::Mutability::Immutable => value.to_string(),
                 _ => String::new(),
             };
-            let hir_id = self.tcx.hir.node_to_hir_id(id);
+            let hir_id = self.tcx.hir().node_to_hir_id(id);
             let typ = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) {
                 Some(typ) => {
                     let typ = typ.to_string();
@@ -1204,7 +1204,7 @@
         let access = access_from!(self.save_ctxt, root_item.vis, id);
 
         // The parent def id of a given use tree is always the enclosing item.
-        let parent = self.save_ctxt.tcx.hir.opt_local_def_id(id)
+        let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id)
             .and_then(|id| self.save_ctxt.tcx.parent_def_id(id))
             .map(::id_from_def_id);
 
@@ -1357,7 +1357,7 @@
                 let name_span = item.ident.span;
                 if !self.span.filter_generated(name_span) {
                     let span = self.span_from_span(name_span);
-                    let parent = self.save_ctxt.tcx.hir.opt_local_def_id(item.id)
+                    let parent = self.save_ctxt.tcx.hir().opt_local_def_id(item.id)
                         .and_then(|id| self.save_ctxt.tcx.parent_def_id(id))
                         .map(::id_from_def_id);
                     self.dumper.import(
@@ -1510,7 +1510,7 @@
         self.process_macro_use(ex.span);
         match ex.node {
             ast::ExprKind::Struct(ref path, ref fields, ref base) => {
-                let hir_expr = self.save_ctxt.tcx.hir.expect_expr(ex.id);
+                let hir_expr = self.save_ctxt.tcx.hir().expect_expr(ex.id);
                 let adt = match self.save_ctxt.tables.expr_ty_opt(&hir_expr) {
                     Some(ty) if ty.ty_adt_def().is_some() => ty.ty_adt_def().unwrap(),
                     _ => {
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 82c4795..e0acc15 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -110,7 +110,7 @@
         }
     }
 
-    // Returns path to the compilation output (e.g. libfoo-12345678.rmeta)
+    // Returns path to the compilation output (e.g., libfoo-12345678.rmeta)
     pub fn compilation_output(&self, crate_name: &str) -> PathBuf {
         let sess = &self.tcx.sess;
         // Save-analysis is emitted per whole session, not per each crate type
@@ -383,7 +383,7 @@
             let name = ident.to_string();
             let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident);
             filter!(self.span_utils, ident.span);
-            let def_id = self.tcx.hir.local_def_id(field.id);
+            let def_id = self.tcx.hir().local_def_id(field.id);
             let typ = self.tcx.type_of(def_id).to_string();
 
 
@@ -415,18 +415,18 @@
         // The qualname for a method is the trait name or name of the struct in an impl in
         // which the method is declared in, followed by the method's name.
         let (qualname, parent_scope, decl_id, docs, attributes) =
-            match self.tcx.impl_of_method(self.tcx.hir.local_def_id(id)) {
-                Some(impl_id) => match self.tcx.hir.get_if_local(impl_id) {
+            match self.tcx.impl_of_method(self.tcx.hir().local_def_id(id)) {
+                Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) {
                     Some(Node::Item(item)) => match item.node {
                         hir::ItemKind::Impl(.., ref ty, _) => {
                             let mut qualname = String::from("<");
-                            qualname.push_str(&self.tcx.hir.node_to_pretty_string(ty.id));
+                            qualname.push_str(&self.tcx.hir().node_to_pretty_string(ty.id));
 
                             let trait_id = self.tcx.trait_id_of_impl(impl_id);
                             let mut decl_id = None;
                             let mut docs = String::new();
                             let mut attrs = vec![];
-                            if let Some(Node::ImplItem(item)) = self.tcx.hir.find(id) {
+                            if let Some(Node::ImplItem(item)) = self.tcx.hir().find(id) {
                                 docs = self.docs_for_attrs(&item.attrs);
                                 attrs = item.attrs.to_vec();
                             }
@@ -463,12 +463,12 @@
                         );
                     }
                 },
-                None => match self.tcx.trait_of_item(self.tcx.hir.local_def_id(id)) {
+                None => match self.tcx.trait_of_item(self.tcx.hir().local_def_id(id)) {
                     Some(def_id) => {
                         let mut docs = String::new();
                         let mut attrs = vec![];
 
-                        if let Some(Node::TraitItem(item)) = self.tcx.hir.find(id) {
+                        if let Some(Node::TraitItem(item)) = self.tcx.hir().find(id) {
                             docs = self.docs_for_attrs(&item.attrs);
                             attrs = item.attrs.to_vec();
                         }
@@ -529,14 +529,14 @@
     }
 
     pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
-        let hir_node = self.tcx.hir.expect_expr(expr.id);
+        let hir_node = self.tcx.hir().expect_expr(expr.id);
         let ty = self.tables.expr_ty_adjusted_opt(&hir_node);
         if ty.is_none() || ty.unwrap().sty == ty::Error {
             return None;
         }
         match expr.node {
             ast::ExprKind::Field(ref sub_ex, ident) => {
-                let hir_node = match self.tcx.hir.find(sub_ex.id) {
+                let hir_node = match self.tcx.hir().find(sub_ex.id) {
                     Some(Node::Expr(expr)) => expr,
                     _ => {
                         debug!(
@@ -587,7 +587,7 @@
                 }
             }
             ast::ExprKind::MethodCall(ref seg, ..) => {
-                let expr_hir_id = self.tcx.hir.definitions().node_to_hir_id(expr.id);
+                let expr_hir_id = self.tcx.hir().definitions().node_to_hir_id(expr.id);
                 let method_id = match self.tables.type_dependent_defs().get(expr_hir_id) {
                     Some(id) => id.def_id(),
                     None => {
@@ -622,7 +622,7 @@
     }
 
     pub fn get_path_def(&self, id: NodeId) -> HirDef {
-        match self.tcx.hir.get(id) {
+        match self.tcx.hir().get(id) {
             Node::TraitRef(tr) => tr.path.def,
 
             Node::Item(&hir::Item {
@@ -656,7 +656,7 @@
                 node: hir::PatKind::TupleStruct(ref qpath, ..),
                 ..
             }) => {
-                let hir_id = self.tcx.hir.node_to_hir_id(id);
+                let hir_id = self.tcx.hir().node_to_hir_id(id);
                 self.tables.qpath_def(qpath, hir_id)
             }
 
@@ -1183,7 +1183,7 @@
 }
 
 fn id_from_node_id(id: NodeId, scx: &SaveContext) -> rls_data::Id {
-    let def_id = scx.tcx.hir.opt_local_def_id(id);
+    let def_id = scx.tcx.hir().opt_local_def_id(id);
     def_id.map(|id| id_from_def_id(id)).unwrap_or_else(|| {
         // Create a *fake* `DefId` out of a `NodeId` by subtracting the `NodeId`
         // out of the maximum u32 value. This will work unless you have *billions*
diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs
index 489bb37..1c3763c 100644
--- a/src/librustc_target/abi/call/mod.rs
+++ b/src/librustc_target/abi/call/mod.rs
@@ -164,7 +164,7 @@
 }
 
 /// An argument passed entirely registers with the
-/// same kind (e.g. HFA / HVA on PPC64 and AArch64).
+/// same kind (e.g., HFA / HVA on PPC64 and AArch64).
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct Uniform {
     pub unit: Reg,
@@ -173,7 +173,7 @@
     /// * equal to `unit.size` (one scalar/vector)
     /// * a multiple of `unit.size` (an array of scalar/vectors)
     /// * if `unit.kind` is `Integer`, the last element
-    ///   can be shorter, i.e. `{ i64, i64, i32 }` for
+    ///   can be shorter, i.e., `{ i64, i64, i32 }` for
     ///   64-bit integers with a total size of 20 bytes
     pub total: Size,
 }
diff --git a/src/librustc_target/abi/call/s390x.rs b/src/librustc_target/abi/call/s390x.rs
index d6d8ea7..fe1c875 100644
--- a/src/librustc_target/abi/call/s390x.rs
+++ b/src/librustc_target/abi/call/s390x.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// FIXME: The assumes we're using the non-vector ABI, i.e. compiling
+// FIXME: The assumes we're using the non-vector ABI, i.e., compiling
 // for a pre-z13 machine or using -mno-vx.
 
 use abi::call::{FnType, ArgType, Reg};
diff --git a/src/librustc_target/abi/call/x86_64.rs b/src/librustc_target/abi/call/x86_64.rs
index f091f80..0f27300 100644
--- a/src/librustc_target/abi/call/x86_64.rs
+++ b/src/librustc_target/abi/call/x86_64.rs
@@ -15,7 +15,7 @@
 use abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods};
 
 /// Classification of "eightbyte" components.
-// NB: the order of the variants is from general to specific,
+// N.B., the order of the variants is from general to specific,
 // such that `unify(a, b)` is the "smaller" of `a` and `b`.
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
 enum Class {
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index 50ce0ad..5912da9 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -409,7 +409,7 @@
     /// Compute the best alignment possible for the given offset
     /// (the largest power of two that the offset is a multiple of).
     ///
-    /// NB: for an offset of `0`, this happens to return `2^64`.
+    /// N.B., for an offset of `0`, this happens to return `2^64`.
     pub fn max_for_offset(offset: Size) -> Align {
         Align {
             pow2: offset.bytes().trailing_zeros() as u8,
@@ -639,7 +639,7 @@
     ///
     /// This is intended specifically to mirror LLVM’s `!range` metadata,
     /// semantics.
-    // FIXME(eddyb) always use the shortest range, e.g. by finding
+    // FIXME(eddyb) always use the shortest range, e.g., by finding
     // the largest space between two consecutive valid values and
     // taking everything else as the (shortest) valid range.
     pub valid_range: RangeInclusive<u128>,
@@ -887,12 +887,12 @@
 }
 
 /// The details of the layout of a type, alongside the type itself.
-/// Provides various type traversal APIs (e.g. recursing into fields).
+/// Provides various type traversal APIs (e.g., recursing into fields).
 ///
 /// Note that the details are NOT guaranteed to always be identical
 /// to those obtained from `layout_of(ty)`, as we need to produce
 /// layouts for which Rust types do not exist, such as enum variants
-/// or synthetic fields of enums (i.e. discriminants) and fat pointers.
+/// or synthetic fields of enums (i.e., discriminants) and fat pointers.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub struct TyLayout<'a, Ty> {
     pub ty: Ty,
diff --git a/src/librustc_target/spec/abi.rs b/src/librustc_target/spec/abi.rs
index 6d8c8eb..919744f 100644
--- a/src/librustc_target/spec/abi.rs
+++ b/src/librustc_target/spec/abi.rs
@@ -12,7 +12,7 @@
 
 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)]
 pub enum Abi {
-    // NB: This ordering MUST match the AbiDatas array below.
+    // N.B., this ordering MUST match the AbiDatas array below.
     // (This is ensured by the test indices_are_correct().)
 
     // Single platform ABIs
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 5b8070c..aef8770 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -68,6 +68,7 @@
 mod openbsd_base;
 mod netbsd_base;
 mod solaris_base;
+mod uefi_base;
 mod windows_base;
 mod windows_msvc_base;
 mod thumb_base;
@@ -234,7 +235,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 {
@@ -254,12 +255,12 @@
             }
         }
 
-        pub fn get_targets() -> Box<dyn Iterator<Item=String>> {
-            Box::new(TARGETS.iter().filter_map(|t| -> Option<String> {
+        pub fn get_targets() -> impl Iterator<Item = String> {
+            TARGETS.iter().filter_map(|t| -> Option<String> {
                 load_specific(t)
                     .and(Ok(t.to_string()))
                     .ok()
-            }))
+            })
         }
 
         #[cfg(test)]
@@ -400,6 +401,8 @@
     ("thumbv7em-none-eabi", thumbv7em_none_eabi),
     ("thumbv7em-none-eabihf", thumbv7em_none_eabihf),
     ("thumbv8m.base-none-eabi", thumbv8m_base_none_eabi),
+    ("thumbv8m.main-none-eabi", thumbv8m_main_none_eabi),
+    ("thumbv8m.main-none-eabihf", thumbv8m_main_none_eabihf),
 
     ("msp430-none-elf", msp430_none_elf),
 
@@ -417,6 +420,8 @@
     ("aarch64-unknown-none", aarch64_unknown_none),
 
     ("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx),
+
+    ("x86_64-unknown-uefi", x86_64_unknown_uefi),
 }
 
 /// Everything `rustc` knows about how to compile for a specific target.
@@ -603,7 +608,7 @@
     /// `eh_unwind_resume` lang item.
     pub custom_unwind_resume: bool,
 
-    /// Flag indicating whether ELF TLS (e.g. #[thread_local]) is available for
+    /// Flag indicating whether ELF TLS (e.g., #[thread_local]) is available for
     /// this target.
     pub has_elf_tls: bool,
     // This is mainly for easy compatibility with emscripten.
diff --git a/src/librustc_target/spec/thumb_base.rs b/src/librustc_target/spec/thumb_base.rs
index 22e5f49..d760f5b 100644
--- a/src/librustc_target/spec/thumb_base.rs
+++ b/src/librustc_target/spec/thumb_base.rs
@@ -18,8 +18,9 @@
 // - Cortex-M4(F)
 // - Cortex-M7(F)
 // - Cortex-M23
+// - Cortex-M33
 //
-// We have opted for these 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_main_none_eabi.rs b/src/librustc_target/spec/thumbv8m_main_none_eabi.rs
new file mode 100644
index 0000000..6dc203e
--- /dev/null
+++ b/src/librustc_target/spec/thumbv8m_main_none_eabi.rs
@@ -0,0 +1,34 @@
+// 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-M33 processor (Armv8-M Mainline architecture profile),
+// without the Floating Point extension.
+
+use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "thumbv8m.main-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 {
+            max_atomic_width: Some(32),
+            .. super::thumb_base::opts()
+        },
+    })
+}
diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs b/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs
new file mode 100644
index 0000000..dc7728c
--- /dev/null
+++ b/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs
@@ -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.
+
+// Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile),
+// with the Floating Point extension.
+
+use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "thumbv8m.main-none-eabihf".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 {
+            // If the Floating Point extension is implemented in the Cortex-M33
+            // processor, the Cortex-M33 Technical Reference Manual states that
+            // the FPU uses the FPv5 architecture, single-precision instructions
+            // and 16 D registers.
+            // These parameters map to the following LLVM features.
+            features: "+fp-armv8,+fp-only-sp,+d16".to_string(),
+            max_atomic_width: Some(32),
+            .. super::thumb_base::opts()
+        },
+    })
+}
diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs
new file mode 100644
index 0000000..9b05158
--- /dev/null
+++ b/src/librustc_target/spec/uefi_base.rs
@@ -0,0 +1,74 @@
+// 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.
+
+// This defines a base target-configuration for native UEFI systems. The UEFI specification has
+// quite detailed sections on the ABI of all the supported target architectures. In almost all
+// cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN
+// documentation.
+// UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic
+// linker is supported. As native to COFF, binaries are position-dependent, but will be relocated
+// by the loader if the pre-chosen memory location is already in use.
+// UEFI forbids running code on anything but the boot-CPU. Not interrupts are allowed other than
+// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
+// code runs in the same environment, no process separation is supported.
+
+use spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
+use std::default::Default;
+
+pub fn opts() -> TargetOptions {
+    let mut pre_link_args = LinkArgs::new();
+
+    pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), vec![
+            // Suppress the verbose logo and authorship debugging output, which would needlessly
+            // clog any log files.
+            "/NOLOGO".to_string(),
+
+            // UEFI is fully compatible to non-executable data pages. Tell the compiler that
+            // non-code sections can be marked as non-executable, including stack pages.
+            "/NXCOMPAT".to_string(),
+
+            // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets
+            // must be freestanding.
+            "/nodefaultlib".to_string(),
+
+            // Non-standard subsystems have no default entry-point in PE+ files. We have to define
+            // one. "efi_main" seems to be a common choice amongst other implementations and the
+            // spec.
+            "/entry:efi_main".to_string(),
+
+            // COFF images have a "Subsystem" field in their header, which defines what kind of
+            // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
+            // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
+            // which is very likely the most common option. Individual projects can override this
+            // with custom linker flags.
+            // The subsystem-type only has minor effects on the application. It defines the memory
+            // regions the application is loaded into (runtime-drivers need to be put into
+            // reserved areas), as well as whether a return from the entry-point is treated as
+            // exit (default for applications).
+            "/subsystem:efi_application".to_string(),
+        ]);
+
+    TargetOptions {
+        dynamic_linking: false,
+        executables: true,
+        disable_redzone: true,
+        exe_suffix: ".efi".to_string(),
+        allows_weak_linkage: false,
+        panic_strategy: PanicStrategy::Abort,
+        singlethread: true,
+        emit_debug_gdb_scripts: false,
+
+        linker: Some("lld-link".to_string()),
+        lld_flavor: LldFlavor::Link,
+        pre_link_args,
+
+        .. Default::default()
+    }
+}
diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
index 07383b3..5b6d8ab 100644
--- a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
+++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
@@ -49,6 +49,7 @@
         max_atomic_width: Some(64),
         panic_strategy: PanicStrategy::Abort,
         cpu: "x86-64".into(),
+        features: "+rdrnd,+rdseed".into(),
         position_independent_executables: true,
         pre_link_args: iter::once(
                 (LinkerFlavor::Gcc, PRE_LINK_ARGS.iter().cloned().map(String::from).collect())
diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs
new file mode 100644
index 0000000..ea68afa
--- /dev/null
+++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs
@@ -0,0 +1,58 @@
+// 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.
+
+// This defines the amd64 target for UEFI systems as described in the UEFI specification. See the
+// uefi-base module for generic UEFI options. On x86_64 systems (mostly called "x64" in the spec)
+// UEFI systems always run in long-mode, have the interrupt-controller pre-configured and force a
+// single-CPU execution.
+// The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
+// LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
+
+use spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::uefi_base::opts();
+    base.cpu = "x86-64".to_string();
+    base.max_atomic_width = Some(64);
+
+    // We disable MMX and SSE for now. UEFI does not prevent these from being used, but there have
+    // been reports to GRUB that some firmware does not initialize the FP exception handlers
+    // properly. Therefore, using FP coprocessors will end you up at random memory locations when
+    // you throw FP exceptions.
+    // To be safe, we disable them for now and force soft-float. This can be revisited when we
+    // have more test coverage. Disabling FP served GRUB well so far, so it should be good for us
+    // as well.
+    base.features = "-mmx,-sse,+soft-float".to_string();
+
+    // UEFI systems run without a host OS, hence we cannot assume any code locality. We must tell
+    // LLVM to expect code to reference any address in the address-space. The "large" code-model
+    // places no locality-restrictions, so it fits well here.
+    base.code_model = Some("large".to_string());
+
+    // UEFI mostly mirrors the calling-conventions used on windows. In case of x86-64 this means
+    // small structs will be returned as int. This shouldn't matter much, since the restrictions
+    // placed by the UEFI specifications forbid any ABI to return structures.
+    base.abi_return_struct_as_int = true;
+
+    Ok(Target {
+        llvm_target: "x86_64-unknown-windows".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+        target_os: "uefi".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
+        arch: "x86_64".to_string(),
+        linker_flavor: LinkerFlavor::Lld(LldFlavor::Link),
+
+        options: base,
+    })
+}
diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml
index f057cbb..48a5864 100644
--- a/src/librustc_traits/Cargo.toml
+++ b/src/librustc_traits/Cargo.toml
@@ -18,4 +18,4 @@
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 chalk-engine = { version = "0.8.0", default-features=false }
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/librustc_traits/implied_outlives_bounds.rs b/src/librustc_traits/implied_outlives_bounds.rs
index 7514c2c..d46ce8b 100644
--- a/src/librustc_traits/implied_outlives_bounds.rs
+++ b/src/librustc_traits/implied_outlives_bounds.rs
@@ -77,7 +77,7 @@
         let obligations =
             wf::obligations(infcx, param_env, DUMMY_NODE_ID, ty, DUMMY_SP).unwrap_or(vec![]);
 
-        // NB: All of these predicates *ought* to be easily proven
+        // N.B., all of these predicates *ought* to be easily proven
         // true. In fact, their correctness is (mostly) implied by
         // other parts of the program. However, in #42552, we had
         // an annoying scenario where:
diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs
index 519b0ac..ad034bf 100644
--- a/src/librustc_traits/lowering/environment.rs
+++ b/src/librustc_traits/lowering/environment.rs
@@ -228,8 +228,8 @@
         // could bound lifetimes.
         .map(Clause::ForAll);
 
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let node = tcx.hir.get(node_id);
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let node = tcx.hir().get(node_id);
 
     let mut is_fn = false;
     let mut is_impl = false;
diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs
index 2d8e5b4..473eebb 100644
--- a/src/librustc_traits/lowering/mod.rs
+++ b/src/librustc_traits/lowering/mod.rs
@@ -43,7 +43,7 @@
 }
 
 crate trait Lower<T> {
-    /// Lower a rustc construct (e.g. `ty::TraitPredicate`) to a chalk-like type.
+    /// Lower a rustc construct (e.g., `ty::TraitPredicate`) to a chalk-like type.
     fn lower(&self) -> T;
 }
 
@@ -90,9 +90,9 @@
 }
 
 /// `ty::Binder` is used for wrapping a rustc construction possibly containing generic
-/// lifetimes, e.g. `for<'a> T: Fn(&'a i32)`. Instead of representing higher-ranked things
-/// in that leaf-form (i.e. `Holds(Implemented(Binder<TraitPredicate>))` in the previous
-/// example), we model them with quantified domain goals, e.g. as for the previous example:
+/// lifetimes, e.g., `for<'a> T: Fn(&'a i32)`. Instead of representing higher-ranked things
+/// in that leaf-form (i.e., `Holds(Implemented(Binder<TraitPredicate>))` in the previous
+/// example), we model them with quantified domain goals, e.g., as for the previous example:
 /// `forall<'a> { T: Fn(&'a i32) }` which corresponds to something like
 /// `Binder<Holds(Implemented(TraitPredicate))>`.
 impl<'tcx, T> Lower<PolyDomainGoal<'tcx>> for ty::Binder<T>
@@ -248,7 +248,7 @@
                 // and that named bound regions have a def-id, it is safe
                 // to just inject `hypotheses` (which contains named vars bound at index `0`)
                 // into this binding level. This may change if we ever allow where clauses
-                // to bind types (e.g. for GATs things), because bound types only use a `BoundVar`
+                // to bind types (e.g., for GATs things), because bound types only use a `BoundVar`
                 // index (no def-id).
                 hypotheses,
 
@@ -560,7 +560,7 @@
     // ```
     //
     // FIXME: For the moment, we don't account for where clauses written on the associated
-    // ty definition (i.e. in the trait def, as in `type AssocType<T> where T: Sized`).
+    // ty definition (i.e., in the trait def, as in `type AssocType<T> where T: Sized`).
     // ```
     // forall<P0..Pm> {
     //   forall<Pn+1..Pm> {
@@ -615,7 +615,7 @@
     }
 
     let mut visitor = ClauseDumper { tcx };
-    tcx.hir
+    tcx.hir()
         .krate()
         .visit_all_item_likes(&mut visitor.as_deep_visitor());
 }
@@ -626,7 +626,7 @@
 
 impl<'a, 'tcx> ClauseDumper<'a, 'tcx> {
     fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) {
-        let def_id = self.tcx.hir.local_def_id(node_id);
+        let def_id = self.tcx.hir().local_def_id(node_id);
         for attr in attrs {
             let mut clauses = None;
 
@@ -664,7 +664,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for ClauseDumper<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
diff --git a/src/librustc_tsan/Cargo.toml b/src/librustc_tsan/Cargo.toml
index baadb64..f061827 100644
--- a/src/librustc_tsan/Cargo.toml
+++ b/src/librustc_tsan/Cargo.toml
@@ -16,4 +16,4 @@
 [dependencies]
 alloc = { path = "../liballoc" }
 core = { path = "../libcore" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
+compiler_builtins = "0.1.0"
diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml
index 881fa26..87f11b0 100644
--- a/src/librustc_typeck/Cargo.toml
+++ b/src/librustc_typeck/Cargo.toml
@@ -17,6 +17,6 @@
 rustc_errors = { path = "../librustc_errors" }
 rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
 rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 4fbbe58..43e7aee 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -8,38 +8,38 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Conversion from AST representation of types to the `ty.rs`
-//! representation.  The main routine here is `ast_ty_to_ty()`: each use
-//! is parameterized by an instance of `AstConv`.
+//! Conversion from AST representation of types to the `ty.rs` representation.
+//! The main routine here is `ast_ty_to_ty()`; each use is is parameterized by
+//! an instance of `AstConv`.
 
-use smallvec::SmallVec;
+use errors::{Applicability, FatalError, DiagnosticId};
 use hir::{self, GenericArg, GenericArgs};
 use hir::def::Def;
 use hir::def_id::DefId;
 use hir::HirVec;
+use lint;
 use middle::resolve_lifetime as rl;
 use namespace::Namespace;
-use rustc::ty::subst::{Kind, Subst, Substs};
 use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
 use rustc::ty::{GenericParamDef, GenericParamDefKind};
+use rustc::ty::subst::{Kind, Subst, Substs};
 use rustc::ty::wf::object_region_bounds;
 use rustc_data_structures::sync::Lrc;
 use rustc_target::spec::abi;
-use std::collections::BTreeSet;
-use std::slice;
 use require_c_abi_if_variadic;
-use util::common::ErrorReported;
-use util::nodemap::FxHashMap;
-use errors::{Applicability, FatalError, DiagnosticId};
-use lint;
-
-use std::iter;
+use smallvec::SmallVec;
 use syntax::ast;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::ptr::P;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::{DUMMY_SP, Span, MultiSpan};
+use util::common::ErrorReported;
+use util::nodemap::FxHashMap;
+
+use std::collections::BTreeSet;
+use std::iter;
+use std::slice;
 
 pub trait AstConv<'gcx, 'tcx> {
     fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
@@ -80,7 +80,7 @@
     fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
 
     /// Invoked when we encounter an error from some prior pass
-    /// (e.g. resolve) that is translated into a ty-error. This is
+    /// (e.g., resolve) that is translated into a ty-error. This is
     /// used to help suppress derived errors typeck might otherwise
     /// report.
     fn set_tainted_by_errors(&self);
@@ -97,7 +97,7 @@
 #[derive(PartialEq)]
 enum GenericArgPosition {
     Type,
-    Value, // e.g. functions
+    Value, // e.g., functions
     MethodCall,
 }
 
@@ -106,7 +106,7 @@
 /// This type must not appear anywhere in other converted types.
 const TRAIT_OBJECT_DUMMY_SELF: ty::TyKind<'static> = ty::Infer(ty::FreshTy(0));
 
-impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
+impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
     pub fn ast_region_to_region(&self,
         lifetime: &hir::Lifetime,
         def: Option<&ty::GenericParamDef>)
@@ -114,10 +114,10 @@
     {
         let tcx = self.tcx();
         let lifetime_name = |def_id| {
-            tcx.hir.name(tcx.hir.as_local_node_id(def_id).unwrap()).as_interned_str()
+            tcx.hir().name(tcx.hir().as_local_node_id(def_id).unwrap()).as_interned_str()
         };
 
-        let hir_id = tcx.hir.node_to_hir_id(lifetime.id);
+        let hir_id = tcx.hir().node_to_hir_id(lifetime.id);
         let r = match tcx.named_region(hir_id) {
             Some(rl::Region::Static) => {
                 tcx.types.re_static
@@ -321,8 +321,8 @@
                                 provided,
                                 offset| {
             // We enforce the following: `required` <= `provided` <= `permitted`.
-            // For kinds without defaults (i.e. lifetimes), `required == permitted`.
-            // For other kinds (i.e. types), `permitted` may be greater than `required`.
+            // For kinds without defaults (i.e., lifetimes), `required == permitted`.
+            // For other kinds (i.e., types), `permitted` may be greater than `required`.
             if required <= provided && provided <= permitted {
                 return (false, None);
             }
@@ -411,24 +411,24 @@
     /// creating the substitutions for, and a partial set of
     /// substitutions `parent_substs`. In general, the substitutions
     /// for an item begin with substitutions for all the "parents" of
-    /// that item -- so e.g. for a method it might include the
+    /// that item -- e.g., for a method it might include the
     /// parameters from the impl.
     ///
     /// Therefore, the method begins by walking down these parents,
     /// starting with the outermost parent and proceed inwards until
-    /// it reaches `def_id`. For each parent P, it will check `parent_substs`
+    /// it reaches `def_id`. For each parent `P`, it will check `parent_substs`
     /// first to see if the parent's substitutions are listed in there. If so,
     /// we can append those and move on. Otherwise, it invokes the
     /// three callback functions:
     ///
-    /// - `args_for_def_id`: given the def-id P, supplies back the
+    /// - `args_for_def_id`: given the def-id `P`, supplies back the
     ///   generic arguments that were given to that parent from within
-    ///   the path; so e.g. if you have `<T as Foo>::Bar`, the def-id
+    ///   the path; so e.g., if you have `<T as Foo>::Bar`, the def-id
     ///   might refer to the trait `Foo`, and the arguments might be
     ///   `[T]`. The boolean value indicates whether to infer values
     ///   for arguments whose values were not explicitly provided.
     /// - `provided_kind`: given the generic parameter and the value from `args_for_def_id`,
-    ///   instantiate a `Kind`
+    ///   instantiate a `Kind`.
     /// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
     ///   creates a suitable inference variable.
     pub fn create_substs_for_generic_args<'a, 'b>(
@@ -441,7 +441,7 @@
         provided_kind: impl Fn(&GenericParamDef, &GenericArg) -> Kind<'tcx>,
         inferred_kind: impl Fn(Option<&[Kind<'tcx>]>, &GenericParamDef, bool) -> Kind<'tcx>,
     ) -> &'tcx Substs<'tcx> {
-        // Collect the segments of the path: we need to substitute arguments
+        // Collect the segments of the path; we need to substitute arguments
         // for parameters throughout the entire path (wherever there are
         // generic parameters).
         let mut parent_defs = tcx.generics_of(def_id);
@@ -453,8 +453,8 @@
         }
 
         // We manually build up the substitution, rather than using convenience
-        // methods in `subst.rs` so that we can iterate over the arguments and
-        // parameters in lock-step linearly, rather than trying to match each pair.
+        // methods in `subst.rs`, so that we can iterate over the arguments and
+        // parameters in lock-step linearly, instead of trying to match each pair.
         let mut substs: SmallVec<[Kind<'tcx>; 8]> = SmallVec::with_capacity(count);
 
         // Iterate over each segment of the path.
@@ -1087,13 +1087,10 @@
                 }
             }
             if !suggestions.is_empty() {
-                let msg = if suggestions.len() == 1 {
-                    "if you meant to specify the associated type, write"
-                } else {
-                    "if you meant to specify the associated types, write"
-                };
+                let msg = format!("if you meant to specify the associated {}, write",
+                    if suggestions.len() == 1 { "type" } else { "types" });
                 err.multipart_suggestion_with_applicability(
-                    msg,
+                    &msg,
                     suggestions,
                     Applicability::MaybeIncorrect,
                 );
@@ -1135,7 +1132,7 @@
             self.ast_region_to_region(lifetime, None)
         } else {
             self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
-                let hir_id = tcx.hir.node_to_hir_id(lifetime.id);
+                let hir_id = tcx.hir().node_to_hir_id(lifetime.id);
                 if tcx.named_region(hir_id).is_some() {
                     self.ast_region_to_region(lifetime, None)
                 } else {
@@ -1190,8 +1187,8 @@
         let suitable_bounds = traits::transitive_bounds(tcx, bounds)
             .filter(|b| self.trait_defines_associated_type_named(b.def_id(), assoc_name));
 
-        let param_node_id = tcx.hir.as_local_node_id(ty_param_def_id).unwrap();
-        let param_name = tcx.hir.ty_param_name(param_node_id);
+        let param_node_id = tcx.hir().as_local_node_id(ty_param_def_id).unwrap();
+        let param_name = tcx.hir().ty_param_name(param_node_id);
         self.one_bound_for_assoc_type(suitable_bounds,
                                       &param_name.as_str(),
                                       assoc_name,
@@ -1235,7 +1232,7 @@
                     item.kind == ty::AssociatedKind::Type &&
                         self.tcx().hygienic_eq(assoc_name, item.ident, bound.def_id())
                 })
-                .and_then(|item| self.tcx().hir.span_if_local(item.def_id));
+                .and_then(|item| self.tcx().hir().span_if_local(item.def_id));
 
                 if let Some(span) = bound_span {
                     err.span_label(span, format!("ambiguous `{}` from `{}`",
@@ -1279,7 +1276,7 @@
         // item is declared.
         let bound = match (&ty.sty, ty_path_def) {
             (_, Def::SelfTy(Some(_), Some(impl_def_id))) => {
-                // `Self` in an impl of a trait - we have a concrete `self` type and a
+                // `Self` in an impl of a trait -- we have a concrete `self` type and a
                 // trait reference.
                 let trait_ref = match tcx.impl_trait_ref(impl_def_id) {
                     Some(trait_ref) => trait_ref,
@@ -1485,12 +1482,12 @@
                 assert_eq!(opt_self_ty, None);
                 self.prohibit_generics(&path.segments);
 
-                let node_id = tcx.hir.as_local_node_id(did).unwrap();
-                let item_id = tcx.hir.get_parent_node(node_id);
-                let item_def_id = tcx.hir.local_def_id(item_id);
+                let node_id = tcx.hir().as_local_node_id(did).unwrap();
+                let item_id = tcx.hir().get_parent_node(node_id);
+                let item_def_id = tcx.hir().local_def_id(item_id);
                 let generics = tcx.generics_of(item_def_id);
-                let index = generics.param_def_id_to_index[&tcx.hir.local_def_id(node_id)];
-                tcx.mk_ty_param(index, tcx.hir.name(node_id).as_interned_str())
+                let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)];
+                tcx.mk_ty_param(index, tcx.hir().name(node_id).as_interned_str())
             }
             Def::SelfTy(_, Some(def_id)) => {
                 // `Self` in impl (we know the concrete type)
@@ -1579,7 +1576,7 @@
                 self.def_to_ty(opt_self_ty, path, false)
             }
             hir::TyKind::Def(item_id, ref lifetimes) => {
-                let did = tcx.hir.local_def_id(item_id.id);
+                let did = tcx.hir().local_def_id(item_id.id);
                 self.impl_trait_ty_to_ty(did, lifetimes)
             },
             hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
@@ -1594,7 +1591,7 @@
                 self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0
             }
             hir::TyKind::Array(ref ty, ref length) => {
-                let length_def_id = tcx.hir.local_def_id(length.id);
+                let length_def_id = tcx.hir().local_def_id(length.id);
                 let substs = Substs::identity_for_item(tcx, length_def_id);
                 let length = ty::Const::unevaluated(tcx, length_def_id, substs, tcx.types.usize);
                 let array_ty = tcx.mk_ty(ty::Array(self.ast_ty_to_ty(&ty), length));
@@ -1787,8 +1784,8 @@
     }
 }
 
-/// Divides a list of general trait bounds into two groups: auto traits (e.g. Sync and Send) and the
-/// remaining general trait bounds.
+/// Divides a list of general trait bounds into two groups: auto traits (e.g., Sync and Send) and
+/// the remaining general trait bounds.
 fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                          trait_bounds: &'b [hir::PolyTraitRef])
     -> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
@@ -1828,7 +1825,7 @@
     pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
                       -> Vec<(ty::Predicate<'tcx>, Span)>
     {
-        // If it could be sized, and is, add the sized predicate
+        // If it could be sized, and is, add the sized predicate.
         let sized_predicate = self.implicitly_sized.and_then(|span| {
             tcx.lang_items().sized_trait().map(|sized| {
                 let trait_ref = ty::TraitRef {
@@ -1841,8 +1838,8 @@
 
         sized_predicate.into_iter().chain(
             self.region_bounds.iter().map(|&(region_bound, span)| {
-                // account for the binder being introduced below; no need to shift `param_ty`
-                // because, at present at least, it can only refer to early-bound regions
+                // Account for the binder being introduced below; no need to shift `param_ty`
+                // because, at present at least, it can only refer to early-bound regions.
                 let region_bound = ty::fold::shift_region(tcx, region_bound, 1);
                 let outlives = ty::OutlivesPredicate(param_ty, region_bound);
                 (ty::Binder::dummy(outlives).to_predicate(), span)
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index a477df6..87ee903 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use check::{FnCtxt, Expectation, Diverges, Needs};
+use check::coercion::CoerceMany;
 use rustc::hir::{self, PatKind};
 use rustc::hir::def::{Def, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@@ -15,17 +17,15 @@
 use rustc::infer::type_variable::TypeVariableOrigin;
 use rustc::traits::ObligationCauseCode;
 use rustc::ty::{self, Ty, TypeFoldable};
-use check::{FnCtxt, Expectation, Diverges, Needs};
-use check::coercion::CoerceMany;
-use util::nodemap::FxHashMap;
-
-use std::collections::hash_map::Entry::{Occupied, Vacant};
-use std::cmp;
 use syntax::ast;
 use syntax::source_map::Spanned;
 use syntax::ptr::P;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::Span;
+use util::nodemap::FxHashMap;
+
+use std::collections::hash_map::Entry::{Occupied, Vacant};
+use std::cmp;
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     /// The `is_arg` argument indicates whether this pattern is the
@@ -545,7 +545,7 @@
         // the "discriminant type" (issue #23116).
         //
         // arielb1 [writes here in this comment thread][c] that there
-        // is certainly *some* potential danger, e.g. for an example
+        // is certainly *some* potential danger, e.g., for an example
         // like:
         //
         // [c]: https://github.com/rust-lang/rust/pull/43399#discussion_r130223956
@@ -729,10 +729,10 @@
             return self.tcx.types.err;
         };
 
-        // Type check the path.
+        // Type-check the path.
         self.demand_eqtype(pat.span, expected, pat_ty);
 
-        // Type check subpatterns.
+        // Type-check subpatterns.
         if self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm) {
             pat_ty
         } else {
@@ -750,7 +750,7 @@
             span_err!(tcx.sess, pat.span, E0533,
                       "expected unit struct/variant or constant, found {} `{}`",
                       def.kind_name(),
-                      hir::print::to_string(&tcx.hir, |s| s.print_qpath(qpath, false)));
+                      hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
         };
 
         // Resolve the path and check the definition for errors.
@@ -771,7 +771,7 @@
             _ => bug!("unexpected pattern definition: {:?}", def)
         }
 
-        // Type check the path.
+        // Type-check the path.
         let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id).0;
         self.demand_suptype(pat.span, expected, pat_ty);
         pat_ty
@@ -794,7 +794,7 @@
         let report_unexpected_def = |def: Def| {
             let msg = format!("expected tuple struct/variant, found {} `{}`",
                               def.kind_name(),
-                              hir::print::to_string(&tcx.hir, |s| s.print_qpath(qpath, false)));
+                              hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
             struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg)
                 .span_label(pat.span, "not a tuple variant or struct").emit();
             on_error();
@@ -808,7 +808,7 @@
             return self.tcx.types.err;
         }
 
-        // Type check the path.
+        // Type-check the path.
         let (pat_ty, def) = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
         if !pat_ty.is_fn() {
             report_unexpected_def(def);
@@ -838,7 +838,7 @@
 
         self.demand_eqtype(pat.span, expected, pat_ty);
 
-        // Type check subpatterns.
+        // Type-check subpatterns.
         if subpats.len() == variant.fields.len() ||
                 subpats.len() < variant.fields.len() && ddpos.is_some() {
             let substs = match pat_ty.sty {
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index 2cd2bb5..1b59434 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -203,7 +203,7 @@
     }
 
     /// also dereference through raw pointer types
-    /// e.g. assuming ptr_to_Foo is the type `*const Foo`
+    /// e.g., assuming ptr_to_Foo is the type `*const Foo`
     /// fcx.autoderef(span, ptr_to_Foo)  => [*const Foo]
     /// fcx.autoderef(span, ptr_to_Foo).include_raw_ptrs() => [*const Foo, Foo]
     pub fn include_raw_pointers(mut self) -> Self {
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 7a71cf5..e4ce049 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -38,7 +38,7 @@
 enum CallStep<'tcx> {
     Builtin(Ty<'tcx>),
     DeferredClosure(ty::FnSig<'tcx>),
-    /// e.g. enum variant constructors
+    /// e.g., enum variant constructors
     Overloaded(MethodCallee<'tcx>),
 }
 
@@ -206,7 +206,7 @@
                             -> Ty<'tcx> {
         let (fn_sig, def_span) = match callee_ty.sty {
             ty::FnDef(def_id, _) => {
-                (callee_ty.fn_sig(self.tcx), self.tcx.hir.span_if_local(def_id))
+                (callee_ty.fn_sig(self.tcx), self.tcx.hir().span_if_local(def_id))
             }
             ty::FnPtr(sig) => (sig, None),
             ref t => {
@@ -214,7 +214,7 @@
                 if let &ty::Adt(adt_def, ..) = t {
                     if adt_def.is_enum() {
                         if let hir::ExprKind::Call(ref expr, _) = call_expr.node {
-                            unit_variant = Some(self.tcx.hir.node_to_pretty_string(expr.id))
+                            unit_variant = Some(self.tcx.hir().node_to_pretty_string(expr.id))
                         }
                     }
                 }
@@ -278,9 +278,9 @@
                     let def_span = match def {
                         Def::Err => None,
                         Def::Local(id) | Def::Upvar(id, ..) => {
-                            Some(self.tcx.hir.span(id))
+                            Some(self.tcx.hir().span(id))
                         }
-                        _ => self.tcx.hir.span_if_local(def.def_id())
+                        _ => self.tcx.hir().span_if_local(def.def_id())
                     };
                     if let Some(span) = def_span {
                         let label = match (unit_variant, inner_callee_path) {
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index c35aee7..51271f0 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -27,7 +27,7 @@
 //!
 //! where `&.T` and `*T` are references of either mutability,
 //! and where pointer_kind(`T`) is the kind of the unsize info
-//! in `T` - the vtable for a trait definition (e.g. `fmt::Display` or
+//! in `T` - the vtable for a trait definition (e.g., `fmt::Display` or
 //! `Iterator`, not `Iterator<Item=u8>`) or a length (or `()` if `T: Sized`).
 //!
 //! Note that lengths are not adjusted when casting raw slices -
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 10ac244..be15503 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -64,7 +64,7 @@
             Some(ty) => self.deduce_expectations_from_expected_type(ty),
             None => (None, None),
         };
-        let body = self.tcx.hir.body(body_id);
+        let body = self.tcx.hir().body(body_id);
         self.check_closure(expr, expected_kind, decl, body, gen, expected_sig)
     }
 
@@ -82,7 +82,7 @@
             opt_kind, expected_sig
         );
 
-        let expr_def_id = self.tcx.hir.local_def_id(expr.id);
+        let expr_def_id = self.tcx.hir().local_def_id(expr.id);
 
         let ClosureSignatures {
             bound_sig,
@@ -266,7 +266,7 @@
                     ty::Predicate::ObjectSafe(..) => None,
                     ty::Predicate::ConstEvaluatable(..) => None,
 
-                    // NB: This predicate is created by breaking down a
+                    // N.B., this predicate is created by breaking down a
                     // `ClosureType: FnFoo()` predicate, where
                     // `ClosureType` represents some `Closure`. It can't
                     // possibly be referring to the current closure,
@@ -496,7 +496,7 @@
         body: &hir::Body,
         expected_sig: ExpectedSig<'tcx>,
     ) -> ClosureSignatures<'tcx> {
-        let expr_map_node = self.tcx.hir.get_if_local(expr_def_id).unwrap();
+        let expr_map_node = self.tcx.hir().get_if_local(expr_def_id).unwrap();
         let expected_args: Vec<_> = expected_sig
             .sig
             .inputs()
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 3bdd038..8d844fe 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -336,7 +336,7 @@
             //   the decision to region inference (and regionck, which will add
             //   some more edges to this variable). However, this can wind up
             //   creating a crippling number of variables in some cases --
-            //   e.g. #32278 -- so we optimize one particular case [3].
+            //   e.g., #32278 -- so we optimize one particular case [3].
             //   Let me try to explain with some examples:
             //   - The "running example" above represents the simple case,
             //     where we have one `&` reference at the outer level and
@@ -696,7 +696,7 @@
 
         let b = self.shallow_resolve(b);
 
-        let node_id_a = self.tcx.hir.as_local_node_id(def_id_a).unwrap();
+        let node_id_a = self.tcx.hir().as_local_node_id(def_id_a).unwrap();
         match b.sty {
             ty::FnPtr(_) if self.tcx.with_freevars(node_id_a, |v| v.is_empty()) => {
                 // We coerce the closure, which has fn type
@@ -809,7 +809,7 @@
         // Special-case that coercion alone cannot handle:
         // Two function item types of differing IDs or Substs.
         if let (&ty::FnDef(..), &ty::FnDef(..)) = (&prev_ty.sty, &new_ty.sty) {
-            // Don't reify if the function types have a LUB, i.e. they
+            // Don't reify if the function types have a LUB, i.e., they
             // are the same function and their parameters have a LUB.
             let lub_ty = self.commit_if_ok(|_| {
                 self.at(cause, self.param_env)
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index e30ebe0..984f1ca 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -93,7 +93,7 @@
     // This node-id should be used for the `body_id` field on each
     // `ObligationCause` (and the `FnCtxt`). This is what
     // `regionck_item` expects.
-    let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
+    let impl_m_node_id = tcx.hir().as_local_node_id(impl_m.def_id).unwrap();
 
     let cause = ObligationCause {
         span: impl_m_span,
@@ -391,7 +391,7 @@
     // the moment, give a kind of vague error message.
     if trait_params != impl_params {
         let def_span = tcx.sess.source_map().def_span(span);
-        let span = tcx.hir.get_generics_span(impl_m.def_id).unwrap_or(def_span);
+        let span = tcx.hir().get_generics_span(impl_m.def_id).unwrap_or(def_span);
         let mut err = struct_span_err!(
             tcx.sess,
             span,
@@ -400,9 +400,9 @@
             impl_m.ident,
         );
         err.span_label(span, "lifetimes do not match method in trait");
-        if let Some(sp) = tcx.hir.span_if_local(trait_m.def_id) {
+        if let Some(sp) = tcx.hir().span_if_local(trait_m.def_id) {
             let def_sp = tcx.sess.source_map().def_span(sp);
-            let sp = tcx.hir.get_generics_span(trait_m.def_id).unwrap_or(def_sp);
+            let sp = tcx.hir().get_generics_span(trait_m.def_id).unwrap_or(def_sp);
             err.span_label(sp, "lifetimes in impl do not match this method in trait");
         }
         err.emit();
@@ -422,8 +422,8 @@
                                                      trait_sig: ty::FnSig<'tcx>)
                                                      -> (Span, Option<Span>) {
     let tcx = infcx.tcx;
-    let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
-    let (impl_m_output, impl_m_iter) = match tcx.hir.expect_impl_item(impl_m_node_id).node {
+    let impl_m_node_id = tcx.hir().as_local_node_id(impl_m.def_id).unwrap();
+    let (impl_m_output, impl_m_iter) = match tcx.hir().expect_impl_item(impl_m_node_id).node {
         ImplItemKind::Method(ref impl_m_sig, _) => {
             (&impl_m_sig.decl.output, impl_m_sig.decl.inputs.iter())
         }
@@ -432,8 +432,8 @@
 
     match *terr {
         TypeError::Mutability => {
-            if let Some(trait_m_node_id) = tcx.hir.as_local_node_id(trait_m.def_id) {
-                let trait_m_iter = match tcx.hir.expect_trait_item(trait_m_node_id).node {
+            if let Some(trait_m_node_id) = tcx.hir().as_local_node_id(trait_m.def_id) {
+                let trait_m_iter = match tcx.hir().expect_trait_item(trait_m_node_id).node {
                     TraitItemKind::Method(ref trait_m_sig, _) => {
                         trait_m_sig.decl.inputs.iter()
                     }
@@ -451,15 +451,15 @@
                 }).map(|(ref impl_arg, ref trait_arg)| {
                     (impl_arg.span, Some(trait_arg.span))
                 })
-                .unwrap_or_else(|| (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id)))
+                .unwrap_or_else(|| (cause.span(&tcx), tcx.hir().span_if_local(trait_m.def_id)))
             } else {
-                (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id))
+                (cause.span(&tcx), tcx.hir().span_if_local(trait_m.def_id))
             }
         }
         TypeError::Sorts(ExpectedFound { .. }) => {
-            if let Some(trait_m_node_id) = tcx.hir.as_local_node_id(trait_m.def_id) {
+            if let Some(trait_m_node_id) = tcx.hir().as_local_node_id(trait_m.def_id) {
                 let (trait_m_output, trait_m_iter) =
-                    match tcx.hir.expect_trait_item(trait_m_node_id).node {
+                    match tcx.hir().expect_trait_item(trait_m_node_id).node {
                         TraitItemKind::Method(ref trait_m_sig, _) => {
                             (&trait_m_sig.decl.output, trait_m_sig.decl.inputs.iter())
                         }
@@ -486,14 +486,14 @@
                              {
                                  (impl_m_output.span(), Some(trait_m_output.span()))
                              } else {
-                                 (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id))
+                                 (cause.span(&tcx), tcx.hir().span_if_local(trait_m.def_id))
                              }
                          )
             } else {
-                (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id))
+                (cause.span(&tcx), tcx.hir().span_if_local(trait_m.def_id))
             }
         }
-        _ => (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id)),
+        _ => (cause.span(&tcx), tcx.hir().span_if_local(trait_m.def_id)),
     }
 }
 
@@ -548,7 +548,7 @@
                                            trait_m.ident,
                                            self_descr);
             err.span_label(impl_m_span, format!("`{}` used in impl", self_descr));
-            if let Some(span) = tcx.hir.span_if_local(trait_m.def_id) {
+            if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
                 err.span_label(span, format!("trait method declared without `{}`", self_descr));
             } else {
                 err.note_trait_signature(trait_m.ident.to_string(),
@@ -568,7 +568,7 @@
                                            trait_m.ident,
                                            self_descr);
             err.span_label(impl_m_span, format!("expected `{}` in impl", self_descr));
-            if let Some(span) = tcx.hir.span_if_local(trait_m.def_id) {
+            if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
                 err.span_label(span, format!("`{}` used in trait", self_descr));
             } else {
                 err.note_trait_signature(trait_m.ident.to_string(),
@@ -594,8 +594,8 @@
     let num_trait_m_type_params = trait_m_generics.own_counts().types;
 
     if num_impl_m_type_params != num_trait_m_type_params {
-        let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
-        let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
+        let impl_m_node_id = tcx.hir().as_local_node_id(impl_m.def_id).unwrap();
+        let impl_m_item = tcx.hir().expect_impl_item(impl_m_node_id);
         let span = if impl_m_item.generics.params.is_empty()
             || impl_m_item.generics.span.is_dummy()  // impl Trait in argument position (#55374)
         {
@@ -644,16 +644,23 @@
     let trait_number_args = trait_m_fty.inputs().skip_binder().len();
     let impl_number_args = impl_m_fty.inputs().skip_binder().len();
     if trait_number_args != impl_number_args {
-        let trait_m_node_id = tcx.hir.as_local_node_id(trait_m.def_id);
+        let trait_m_node_id = tcx.hir().as_local_node_id(trait_m.def_id);
         let trait_span = if let Some(trait_id) = trait_m_node_id {
-            match tcx.hir.expect_trait_item(trait_id).node {
+            match tcx.hir().expect_trait_item(trait_id).node {
                 TraitItemKind::Method(ref trait_m_sig, _) => {
-                    if let Some(arg) = trait_m_sig.decl.inputs.get(if trait_number_args > 0 {
+                    let pos = if trait_number_args > 0 {
                         trait_number_args - 1
                     } else {
                         0
-                    }) {
-                        Some(arg.span)
+                    };
+                    if let Some(arg) = trait_m_sig.decl.inputs.get(pos) {
+                        Some(if pos == 0 {
+                            arg.span
+                        } else {
+                            Span::new(trait_m_sig.decl.inputs[0].span.lo(),
+                                      arg.span.hi(),
+                                      arg.span.ctxt())
+                        })
                     } else {
                         trait_item_span
                     }
@@ -663,15 +670,22 @@
         } else {
             trait_item_span
         };
-        let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
-        let impl_span = match tcx.hir.expect_impl_item(impl_m_node_id).node {
+        let impl_m_node_id = tcx.hir().as_local_node_id(impl_m.def_id).unwrap();
+        let impl_span = match tcx.hir().expect_impl_item(impl_m_node_id).node {
             ImplItemKind::Method(ref impl_m_sig, _) => {
-                if let Some(arg) = impl_m_sig.decl.inputs.get(if impl_number_args > 0 {
+                let pos = if impl_number_args > 0 {
                     impl_number_args - 1
                 } else {
                     0
-                }) {
-                    arg.span
+                };
+                if let Some(arg) = impl_m_sig.decl.inputs.get(pos) {
+                    if pos == 0 {
+                        arg.span
+                    } else {
+                        Span::new(impl_m_sig.decl.inputs[0].span.lo(),
+                                  arg.span.hi(),
+                                  arg.span.ctxt())
+                    }
                 } else {
                     impl_m_span
                 }
@@ -729,8 +743,8 @@
         in impl_m_type_params.zip(trait_m_type_params)
     {
         if impl_synthetic != trait_synthetic {
-            let impl_node_id = tcx.hir.as_local_node_id(impl_def_id).unwrap();
-            let impl_span = tcx.hir.span(impl_node_id);
+            let impl_node_id = tcx.hir().as_local_node_id(impl_def_id).unwrap();
+            let impl_span = tcx.hir().span(impl_node_id);
             let trait_span = tcx.def_span(trait_def_id);
             let mut err = struct_span_err!(tcx.sess,
                                            impl_span,
@@ -752,11 +766,11 @@
                             .source_map()
                             .span_to_snippet(trait_span)
                             .ok()?;
-                        let trait_m = tcx.hir.as_local_node_id(trait_m.def_id)?;
-                        let trait_m = tcx.hir.trait_item(hir::TraitItemId { node_id: trait_m });
+                        let trait_m = tcx.hir().as_local_node_id(trait_m.def_id)?;
+                        let trait_m = tcx.hir().trait_item(hir::TraitItemId { node_id: trait_m });
 
-                        let impl_m = tcx.hir.as_local_node_id(impl_m.def_id)?;
-                        let impl_m = tcx.hir.impl_item(hir::ImplItemId { node_id: impl_m });
+                        let impl_m = tcx.hir().as_local_node_id(impl_m.def_id)?;
+                        let impl_m = tcx.hir().impl_item(hir::ImplItemId { node_id: impl_m });
 
                         // in case there are no generics, take the spot between the function name
                         // and the opening paren of the argument list
@@ -797,8 +811,8 @@
                 (None, Some(hir::SyntheticTyParamKind::ImplTrait)) => {
                     err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
                     (|| {
-                        let impl_m = tcx.hir.as_local_node_id(impl_m.def_id)?;
-                        let impl_m = tcx.hir.impl_item(hir::ImplItemId { node_id: impl_m });
+                        let impl_m = tcx.hir().as_local_node_id(impl_m.def_id)?;
+                        let impl_m = tcx.hir().impl_item(hir::ImplItemId { node_id: impl_m });
                         let input_tys = match impl_m.node {
                             hir::ImplItemKind::Method(ref sig, _) => &sig.decl.inputs,
                             _ => unreachable!(),
@@ -895,7 +909,7 @@
 
         // Create a parameter environment that represents the implementation's
         // method.
-        let impl_c_node_id = tcx.hir.as_local_node_id(impl_c.def_id).unwrap();
+        let impl_c_node_id = tcx.hir().as_local_node_id(impl_c.def_id).unwrap();
 
         // Compute placeholder form of impl and trait const tys.
         let impl_ty = tcx.type_of(impl_c.def_id);
@@ -927,7 +941,7 @@
                    trait_ty);
 
             // Locate the Span containing just the type of the offending impl
-            match tcx.hir.expect_impl_item(impl_c_node_id).node {
+            match tcx.hir().expect_impl_item(impl_c_node_id).node {
                 ImplItemKind::Const(ref ty, _) => cause.span = ty.span,
                 _ => bug!("{:?} is not a impl const", impl_c),
             }
@@ -939,10 +953,10 @@
                                              trait",
                                             trait_c.ident);
 
-            let trait_c_node_id = tcx.hir.as_local_node_id(trait_c.def_id);
+            let trait_c_node_id = tcx.hir().as_local_node_id(trait_c.def_id);
             let trait_c_span = trait_c_node_id.map(|trait_c_node_id| {
                 // Add a label to the Span containing just the type of the const
-                match tcx.hir.expect_trait_item(trait_c_node_id).node {
+                match tcx.hir().expect_trait_item(trait_c_node_id).node {
                     TraitItemKind::Const(ref ty, _) => ty.span,
                     _ => bug!("{:?} is not a trait const", trait_c),
                 }
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 0a19683..db4b686 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -91,7 +91,7 @@
 
     // Checks that the type of `expr` can be coerced to `expected`.
     //
-    // NB: This code relies on `self.diverges` to be accurate. In
+    // N.B., this code relies on `self.diverges` to be accurate. In
     // particular, assignments to `!` will be permitted if the
     // diverges flag is currently "always".
     pub fn demand_coerce_diag(&self,
@@ -123,7 +123,7 @@
                         let sole_field_ty = sole_field.ty(self.tcx, substs);
                         if self.can_coerce(expr_ty, sole_field_ty) {
                             let variant_path = self.tcx.item_path_str(variant.did);
-                            Some(variant_path.trim_left_matches("std::prelude::v1::").to_string())
+                            Some(variant_path.trim_start_matches("std::prelude::v1::").to_string())
                         } else {
                             None
                         }
@@ -203,17 +203,17 @@
     fn can_use_as_ref(&self, expr: &hir::Expr) -> Option<(Span, &'static str, String)> {
         if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.node {
             if let hir::def::Def::Local(id) = path.def {
-                let parent = self.tcx.hir.get_parent_node(id);
+                let parent = self.tcx.hir().get_parent_node(id);
                 if let Some(Node::Expr(hir::Expr {
                     id,
                     node: hir::ExprKind::Closure(_, decl, ..),
                     ..
-                })) = self.tcx.hir.find(parent) {
-                    let parent = self.tcx.hir.get_parent_node(*id);
+                })) = self.tcx.hir().find(parent) {
+                    let parent = self.tcx.hir().get_parent_node(*id);
                     if let (Some(Node::Expr(hir::Expr {
                         node: hir::ExprKind::MethodCall(path, span, expr),
                         ..
-                    })), 1) = (self.tcx.hir.find(parent), decl.inputs.len()) {
+                    })), 1) = (self.tcx.hir().find(parent), decl.inputs.len()) {
                         let self_ty = self.tables.borrow().node_id_to_type(expr[0].hir_id);
                         let self_ty = format!("{:?}", self_ty);
                         let name = path.ident.as_str();
@@ -450,8 +450,8 @@
                       checked_ty: Ty<'tcx>,
                       expected_ty: Ty<'tcx>)
                       -> bool {
-        let parent_id = self.tcx.hir.get_parent_node(expr.id);
-        if let Some(parent) = self.tcx.hir.find(parent_id) {
+        let parent_id = self.tcx.hir().get_parent_node(expr.id);
+        if let Some(parent) = self.tcx.hir().find(parent_id) {
             // Shouldn't suggest `.into()` on `const`s.
             if let Node::Item(Item { node: ItemKind::Const(_, _), .. }) = parent {
                 // FIXME(estebank): modify once we decide to suggest `as` casts
@@ -519,7 +519,7 @@
                 let suffix_suggestion = format!(
                     "{}{}{}{}",
                     if needs_paren { "(" } else { "" },
-                    src.trim_right_matches(&checked_ty.to_string()),
+                    src.trim_end_matches(&checked_ty.to_string()),
                     expected_ty,
                     if needs_paren { ")" } else { "" },
                 );
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index b854417..f59bc2d 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -32,7 +32,7 @@
 ///    coherence),
 ///
 /// 2. The generic region/type parameters of the impl's self-type must
-///    all be parameters of the Drop impl itself (i.e. no
+///    all be parameters of the Drop impl itself (i.e., no
 ///    specialization like `impl Drop for Foo<i32>`), and,
 ///
 /// 3. Any bounds on the generic parameters must be reflected in the
@@ -80,7 +80,7 @@
     drop_impl_ty: Ty<'tcx>,
     self_type_did: DefId,
 ) -> Result<(), ErrorReported> {
-    let drop_impl_node_id = tcx.hir.as_local_node_id(drop_impl_did).unwrap();
+    let drop_impl_node_id = tcx.hir().as_local_node_id(drop_impl_did).unwrap();
 
     // check that the impl type can be made to match the trait type.
 
@@ -180,7 +180,7 @@
     //
     //     self_to_impl_substs = {'c => 'z, 'b => 'y, 'a => 'x}
     //
-    // Applying this to the predicates (i.e. assumptions) provided by the item
+    // Applying this to the predicates (i.e., assumptions) provided by the item
     // definition yields the instantiated assumptions:
     //
     //     ['y : 'z]
@@ -194,7 +194,7 @@
     // absent. So we report an error that the Drop impl injected a
     // predicate that is not present on the struct definition.
 
-    let self_type_node_id = tcx.hir.as_local_node_id(self_type_did).unwrap();
+    let self_type_node_id = tcx.hir().as_local_node_id(self_type_did).unwrap();
 
     let drop_impl_span = tcx.def_span(drop_impl_did);
 
@@ -226,7 +226,7 @@
         // repeated `contains` calls.
 
         if !assumptions_in_impl_context.contains(&predicate) {
-            let item_span = tcx.hir.span(self_type_node_id);
+            let item_span = tcx.hir().span(self_type_node_id);
             struct_span_err!(
                 tcx.sess,
                 drop_impl_span,
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index b4ad9cf..55fceda 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -86,7 +86,7 @@
                                         def_id: DefId,
                                         body_id: hir::BodyId,
                                         interior: Ty<'tcx>) {
-    let body = fcx.tcx.hir.body(body_id);
+    let body = fcx.tcx.hir().body(body_id);
     let mut visitor = InteriorVisitor {
         fcx,
         types: FxHashMap::default(),
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 2af21f5..a40e56d 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -36,7 +36,7 @@
     inputs: Vec<Ty<'tcx>>,
     output: Ty<'tcx>,
 ) {
-    let def_id = tcx.hir.local_def_id(it.id);
+    let def_id = tcx.hir().local_def_id(it.id);
 
     match it.node {
         hir::ForeignItemKind::Fn(..) => {}
@@ -401,7 +401,7 @@
         tcx.mk_ty_param(n, name)
     };
 
-    let def_id = tcx.hir.local_def_id(it.id);
+    let def_id = tcx.hir().local_def_id(it.id);
     let i_n_tps = tcx.generics_of(def_id).own_counts().types;
     let name = it.name.as_str();
 
@@ -435,7 +435,8 @@
         "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
         "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)),
         "simd_cast" => (2, vec![param(0)], param(1)),
-        "simd_select" => (2, vec![param(0), param(1), param(1)], param(1)),
+        "simd_select" |
+        "simd_select_bitmask" => (2, vec![param(0), param(1), param(1)], param(1)),
         "simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool),
         "simd_reduce_add_ordered" | "simd_reduce_mul_ordered"
             => (2, vec![param(0), param(1)], param(1)),
@@ -505,7 +506,7 @@
 }
 
 // walk the expected type and the actual type in lock step, checking they're
-// the same, in a kinda-structural way, i.e. `Vector`s have to be simd structs with
+// the same, in a kinda-structural way, i.e., `Vector`s have to be simd structs with
 // exactly the right element type
 fn match_intrinsic_type_to_type<'a, 'tcx>(
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 5144f3e..11fb388 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -395,7 +395,7 @@
         // Instantiate late-bound regions and substitute the trait
         // parameters into the method type to get the actual method type.
         //
-        // NB: Instantiate late-bound regions first so that
+        // N.B., instantiate late-bound regions first so that
         // `instantiate_type_scheme` can normalize associated types that
         // may reference those regions.
         let method_sig = self.replace_bound_vars_with_fresh_vars(&sig);
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 37f4ae5..858d8c7 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -12,31 +12,28 @@
 //!
 //! [rustc guide]: https://rust-lang.github.io/rustc-guide/method-lookup.html
 
-use check::FnCtxt;
-use hir::def::Def;
-use hir::def_id::DefId;
-use namespace::Namespace;
-use rustc::ty::subst::Substs;
-use rustc::traits;
-use rustc::ty::{self, Ty, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable};
-use rustc::ty::GenericParamDefKind;
-use rustc::ty::subst::Subst;
-use rustc::infer::{self, InferOk};
-
-use syntax::ast;
-use syntax_pos::Span;
-
-use rustc::hir;
-
-use rustc_data_structures::sync::Lrc;
+mod confirm;
+pub mod probe;
+mod suggest;
 
 pub use self::MethodError::*;
 pub use self::CandidateSource::*;
 pub use self::suggest::TraitInfo;
 
-mod confirm;
-pub mod probe;
-mod suggest;
+use check::FnCtxt;
+use namespace::Namespace;
+use rustc_data_structures::sync::Lrc;
+use rustc::hir;
+use rustc::hir::def::Def;
+use rustc::hir::def_id::DefId;
+use rustc::traits;
+use rustc::ty::subst::Substs;
+use rustc::ty::{self, Ty, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable};
+use rustc::ty::GenericParamDefKind;
+use rustc::ty::subst::Subst;
+use rustc::infer::{self, InferOk};
+use syntax::ast;
+use syntax_pos::Span;
 
 use self::probe::{IsSuggestion, ProbeScope};
 
@@ -50,7 +47,7 @@
     pub def_id: DefId,
     pub substs: &'tcx Substs<'tcx>,
 
-    /// Instantiated method signature, i.e. it has been
+    /// Instantiated method signature, i.e., it has been
     /// substituted, normalized, and has had late-bound
     /// lifetimes replaced with inference variables.
     pub sig: ty::FnSig<'tcx>,
@@ -107,8 +104,7 @@
 #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
 pub enum CandidateSource {
     ImplSource(DefId),
-    TraitSource(// trait id
-                DefId),
+    TraitSource(DefId /* trait id */),
 }
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
@@ -171,10 +167,10 @@
         )?;
 
         if let Some(import_id) = pick.import_id {
-            let import_def_id = self.tcx.hir.local_def_id(import_id);
+            let import_def_id = self.tcx.hir().local_def_id(import_id);
             debug!("used_trait_import: {:?}", import_def_id);
             Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports)
-                                        .unwrap().insert(import_def_id);
+                .unwrap().insert(import_def_id);
         }
 
         self.tcx.check_stability(pick.item.def_id, Some(call_expr.id), span);
@@ -239,7 +235,7 @@
     /// an obligation for a particular trait with the given self-type and checks
     /// whether that trait is implemented.
     ///
-    /// FIXME(#18741) -- It seems likely that we can consolidate some of this
+    /// FIXME(#18741): it seems likely that we can consolidate some of this
     /// code with the other method-lookup code. In particular, the second half
     /// of this method is basically the same as confirmation.
     pub fn lookup_method_in_trait(&self,
@@ -307,7 +303,7 @@
         // Instantiate late-bound regions and substitute the trait
         // parameters into the method type to get the actual method type.
         //
-        // NB: Instantiate late-bound regions first so that
+        // N.B., instantiate late-bound regions first so that
         // `instantiate_type_scheme` can normalize associated types that
         // may reference those regions.
         let fn_sig = tcx.fn_sig(def_id);
@@ -324,7 +320,7 @@
             }
         };
 
-        // Register obligations for the parameters.  This will include the
+        // Register obligations for the parameters. This will include the
         // `Self` parameter, which in turn has a bound of the main trait,
         // so this also effectively registers `obligation` as well.  (We
         // used to register `obligation` explicitly, but that resulted in
@@ -380,7 +376,7 @@
                                        self_ty, expr_id, ProbeScope::TraitsInScope)?;
 
         if let Some(import_id) = pick.import_id {
-            let import_def_id = self.tcx.hir.local_def_id(import_id);
+            let import_def_id = self.tcx.hir().local_def_id(import_id);
             debug!("used_trait_import: {:?}", import_def_id);
             Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports)
                                         .unwrap().insert(import_def_id);
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 5b67116..dd3c022 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -41,7 +41,7 @@
 pub use self::PickKind::*;
 
 /// Boolean flag used to indicate if this search is for a suggestion
-/// or not.  If true, we can allow ambiguity and so forth.
+/// or not. If true, we can allow ambiguity and so forth.
 #[derive(Clone, Copy)]
 pub struct IsSuggestion(pub bool);
 
@@ -720,7 +720,7 @@
             return Ok(())
         }
         let mut duplicates = FxHashSet::default();
-        let expr_hir_id = self.tcx.hir.node_to_hir_id(expr_id);
+        let expr_hir_id = self.tcx.hir().node_to_hir_id(expr_id);
         let opt_applicable_traits = self.tcx.in_scope_traits(expr_hir_id);
         if let Some(applicable_traits) = opt_applicable_traits {
             for trait_candidate in applicable_traits.iter() {
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index cd243d4..0906357 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -12,29 +12,23 @@
 //! found or is otherwise invalid.
 
 use check::FnCtxt;
-use rustc::hir::map as hir_map;
-use hir::Node;
-use rustc_data_structures::sync::Lrc;
-use rustc::ty::{self, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
-use rustc::ty::item_path::with_crate_prefix;
-use hir::def::Def;
-use hir::def_id::{CRATE_DEF_INDEX, DefId};
+use errors::{Applicability, DiagnosticBuilder};
 use middle::lang_items::FnOnceTraitLangItem;
 use namespace::Namespace;
-use rustc::traits::Obligation;
-use util::nodemap::FxHashSet;
-
-use syntax::ast;
-use syntax::util::lev_distance::find_best_match_for_name;
-use errors::{Applicability, DiagnosticBuilder};
-use syntax_pos::{Span, FileName};
-
-
-use rustc::hir::def_id::LOCAL_CRATE;
-use rustc::hir;
+use rustc_data_structures::sync::Lrc;
+use rustc::hir::{self, Node};
+use rustc::hir::def::Def;
+use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
+use rustc::hir::map as hir_map;
 use rustc::hir::print;
 use rustc::infer::type_variable::TypeVariableOrigin;
-use rustc::ty::Adt;
+use rustc::traits::Obligation;
+use rustc::ty::{self, Adt, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
+use rustc::ty::item_path::with_crate_prefix;
+use util::nodemap::FxHashSet;
+use syntax_pos::{Span, FileName};
+use syntax::ast;
+use syntax::util::lev_distance::find_best_match_for_name;
 
 use std::cmp::Ordering;
 
@@ -45,12 +39,12 @@
     fn is_fn_ty(&self, ty: &Ty<'tcx>, span: Span) -> bool {
         let tcx = self.tcx;
         match ty.sty {
-            // Not all of these (e.g. unsafe fns) implement FnOnce
-            // so we look for these beforehand
+            // Not all of these (e.g., unsafe fns) implement `FnOnce`,
+            // so we look for these beforehand.
             ty::Closure(..) |
             ty::FnDef(..) |
             ty::FnPtr(_) => true,
-            // If it's not a simple function, look for things which implement FnOnce
+            // If it's not a simple function, look for things which implement `FnOnce`.
             _ => {
                 let fn_once = match tcx.lang_items().require(FnOnceTraitLangItem) {
                     Ok(fn_once) => fn_once,
@@ -83,7 +77,7 @@
                                rcvr_expr: Option<&hir::Expr>,
                                error: MethodError<'tcx>,
                                args: Option<&'gcx [hir::Expr]>) {
-        // avoid suggestions when we don't know what's going on.
+        // Avoid suggestions when we don't know what's going on.
         if rcvr_ty.references_error() {
             return;
         }
@@ -107,8 +101,8 @@
                                     Namespace::Value,
                                 )
                             }).unwrap();
-                        let note_span = self.tcx.hir.span_if_local(item.def_id).or_else(|| {
-                            self.tcx.hir.span_if_local(impl_did)
+                        let note_span = self.tcx.hir().span_if_local(item.def_id).or_else(|| {
+                            self.tcx.hir().span_if_local(impl_did)
                         });
 
                         let impl_ty = self.impl_self_ty(span, impl_did).ty;
@@ -194,7 +188,7 @@
                 let tcx = self.tcx;
 
                 let actual = self.resolve_type_vars_if_possible(&rcvr_ty);
-                let ty_string = self.ty_to_string(actual);
+                let ty_str = self.ty_to_string(actual);
                 let is_method = mode == Mode::MethodCall;
                 let mut suggestion = None;
                 let item_kind = if is_method {
@@ -239,7 +233,7 @@
                             "can't call {} `{}` on ambiguous numeric type `{}`",
                             item_kind,
                             item_name,
-                            ty_string
+                            ty_str
                         );
                         let concrete_type = if actual.is_integral() {
                             "i32"
@@ -247,7 +241,8 @@
                             "f32"
                         };
                         match expr.node {
-                            hir::ExprKind::Lit(ref lit) => { // numeric literal
+                            hir::ExprKind::Lit(ref lit) => {
+                                // numeric literal
                                 let snippet = tcx.sess.source_map().span_to_snippet(lit.span)
                                     .unwrap_or_else(|_| "<numeric literal>".to_owned());
 
@@ -262,16 +257,17 @@
                                                     Applicability::MaybeIncorrect,
                                 );
                             }
-                            hir::ExprKind::Path(ref qpath) => {  // local binding
+                            hir::ExprKind::Path(ref qpath) => {
+                                // local binding
                                 if let &hir::QPath::Resolved(_, ref path) = &qpath {
                                     if let hir::def::Def::Local(node_id) = path.def {
-                                        let span = tcx.hir.span(node_id);
+                                        let span = tcx.hir().span(node_id);
                                         let snippet = tcx.sess.source_map().span_to_snippet(span)
                                             .unwrap();
                                         let filename = tcx.sess.source_map().span_to_filename(span);
 
-                                        let parent_node = self.tcx.hir.get(
-                                            self.tcx.hir.get_parent_node(node_id),
+                                        let parent_node = self.tcx.hir().get(
+                                            self.tcx.hir().get_parent_node(node_id),
                                         );
                                         let msg = format!(
                                             "you must specify a type for this binding, like `{}`",
@@ -313,10 +309,10 @@
                             "no {} named `{}` found for type `{}` in the current scope",
                             item_kind,
                             item_name,
-                            ty_string
+                            ty_str
                         );
                         if let Some(suggestion) = suggestion {
-                            err.note(&format!("did you mean `{}::{}`?", ty_string, suggestion));
+                            err.note(&format!("did you mean `{}::{}`?", ty_str, suggestion));
                         }
                         err
                     }
@@ -325,7 +321,7 @@
                 };
 
                 if let Some(def) = actual.ty_adt_def() {
-                    if let Some(full_sp) = tcx.hir.span_if_local(def.did) {
+                    if let Some(full_sp) = tcx.hir().span_if_local(def.did) {
                         let def_sp = tcx.sess.source_map().def_span(full_sp);
                         err.span_label(def_sp, format!("{} `{}` not found {}",
                                                        item_kind,
@@ -339,7 +335,7 @@
                 }
 
                 // If the method name is the name of a field with a function or closure type,
-                // give a helping note that it has to be called as (x.f)(...).
+                // give a helping note that it has to be called as `(x.f)(...)`.
                 if let Some(expr) = rcvr_expr {
                     for (ty, _) in self.autoderef(span, rcvr_ty) {
                         if let ty::Adt(def, substs) = ty.sty {
@@ -351,12 +347,12 @@
                                     let expr_string = match snippet {
                                         Ok(expr_string) => expr_string,
                                         _ => "s".into(), // Default to a generic placeholder for the
-                                        // expression when we can't generate a
-                                        // string snippet
+                                                         // expression when we can't generate a
+                                                         // string snippet.
                                     };
 
                                     let field_ty = field.ty(tcx, substs);
-                                    let scope = self.tcx.hir.get_module_parent(self.body_id);
+                                    let scope = self.tcx.hir().get_module_parent(self.body_id);
                                     if field.vis.is_accessible_from(scope, self.tcx) {
                                         if self.is_fn_ty(&field_ty, span) {
                                             err.help(&format!("use `({0}.{1})(...)` if you \
@@ -380,7 +376,7 @@
                         }
                     }
                 } else {
-                    err.span_label(span, format!("{} not found in `{}`", item_kind, ty_string));
+                    err.span_label(span, format!("{} not found in `{}`", item_kind, ty_str));
                 }
 
                 if self.is_fn_ty(&rcvr_ty, span) {
@@ -424,15 +420,16 @@
 
                     report_candidates(&mut err, static_sources);
                 } else if static_sources.len() > 1 {
-
                     report_candidates(&mut err, static_sources);
                 }
 
                 if !unsatisfied_predicates.is_empty() {
-                    let bound_list = unsatisfied_predicates.iter()
+                    let mut bound_list = unsatisfied_predicates.iter()
                         .map(|p| format!("`{} : {}`", p.self_ty(), p))
-                        .collect::<Vec<_>>()
-                        .join("\n");
+                        .collect::<Vec<_>>();
+                    bound_list.sort();
+                    bound_list.dedup();  // #35677
+                    let bound_list = bound_list.join("\n");
                     err.note(&format!("the method `{}` exists but the following trait bounds \
                                        were not satisfied:\n{}",
                                       item_name,
@@ -503,13 +500,13 @@
                               err: &mut DiagnosticBuilder,
                               mut msg: String,
                               candidates: Vec<DefId>) {
-        let module_did = self.tcx.hir.get_module_parent(self.body_id);
-        let module_id = self.tcx.hir.as_local_node_id(module_did).unwrap();
-        let krate = self.tcx.hir.krate();
+        let module_did = self.tcx.hir().get_module_parent(self.body_id);
+        let module_id = self.tcx.hir().as_local_node_id(module_did).unwrap();
+        let krate = self.tcx.hir().krate();
         let (span, found_use) = UsePlacementFinder::check(self.tcx, krate, module_id);
         if let Some(span) = span {
             let path_strings = candidates.iter().map(|did| {
-                // produce an additional newline to separate the new use statement
+                // Produce an additional newline to separate the new use statement
                 // from the directly following item.
                 let additional_newline = if found_use {
                     ""
@@ -597,15 +594,15 @@
 
         let type_is_local = self.type_derefs_to_local(span, rcvr_ty, rcvr_expr);
 
-        // there's no implemented traits, so lets suggest some traits to
+        // There are no traits implemented, so lets suggest some traits to
         // implement, by finding ones that have the item name, and are
         // legal to implement.
         let mut candidates = all_traits(self.tcx)
             .into_iter()
             .filter(|info| {
-                // we approximate the coherence rules to only suggest
+                // We approximate the coherence rules to only suggest
                 // traits that are legal to implement by requiring that
-                // either the type or trait is local. Multidispatch means
+                // either the type or trait is local. Multi-dispatch means
                 // this isn't perfect (that is, there are cases when
                 // implementing a trait would be legal but is rejected
                 // here).
@@ -620,11 +617,11 @@
             .collect::<Vec<_>>();
 
         if !candidates.is_empty() {
-            // sort from most relevant to least relevant
+            // Sort from most relevant to least relevant.
             candidates.sort_by(|a, b| a.cmp(b).reverse());
             candidates.dedup();
 
-            // FIXME #21673 this help message could be tuned to the case
+            // FIXME #21673: this help message could be tuned to the case
             // of a type parameter: suggest adding a trait bound rather
             // than implementing.
             err.help("items from traits can only be used if the trait is implemented and in scope");
@@ -656,8 +653,7 @@
     fn type_derefs_to_local(&self,
                             span: Span,
                             rcvr_ty: Ty<'tcx>,
-                            rcvr_expr: Option<&hir::Expr>)
-                            -> bool {
+                            rcvr_expr: Option<&hir::Expr>) -> bool {
         fn is_local(ty: Ty) -> bool {
             match ty.sty {
                 ty::Adt(def, _) => def.did.is_local(),
@@ -667,8 +663,8 @@
 
                 ty::Param(_) => true,
 
-                // everything else (primitive types etc.) is effectively
-                // non-local (there are "edge" cases, e.g. (LocalType,), but
+                // Everything else (primitive types, etc.) is effectively
+                // non-local (there are "edge" cases, e.g., `(LocalType,)`, but
                 // the noise from these sort of types is usually just really
                 // annoying, rather than any sort of help).
                 _ => false,
@@ -703,8 +699,8 @@
 }
 impl Ord for TraitInfo {
     fn cmp(&self, other: &TraitInfo) -> Ordering {
-        // local crates are more important than remote ones (local:
-        // cnum == 0), and otherwise we throw in the defid for totality
+        // Local crates are more important than remote ones (local:
+        // `cnum == 0`), and otherwise we throw in the defid for totality.
 
         let lhs = (other.def_id.krate, other.def_id);
         let rhs = (self.def_id.krate, self.def_id);
@@ -719,65 +715,65 @@
 
 /// Compute all traits in this crate and any dependent crates.
 fn compute_all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Vec<DefId> {
-        use rustc::hir::itemlikevisit;
+    use hir::itemlikevisit;
 
-        let mut traits = vec![];
+    let mut traits = vec![];
 
-        // Crate-local:
-        //
-        // meh.
-        struct Visitor<'a, 'tcx: 'a> {
-            map: &'a hir_map::Map<'tcx>,
-            traits: &'a mut Vec<DefId>,
+    // Crate-local:
+
+    struct Visitor<'a, 'tcx: 'a> {
+        map: &'a hir_map::Map<'tcx>,
+        traits: &'a mut Vec<DefId>,
+    }
+
+    impl<'v, 'a, 'tcx> itemlikevisit::ItemLikeVisitor<'v> for Visitor<'a, 'tcx> {
+        fn visit_item(&mut self, i: &'v hir::Item) {
+            if let hir::ItemKind::Trait(..) = i.node {
+                let def_id = self.map.local_def_id(i.id);
+                self.traits.push(def_id);
+            }
         }
-        impl<'v, 'a, 'tcx> itemlikevisit::ItemLikeVisitor<'v> for Visitor<'a, 'tcx> {
-            fn visit_item(&mut self, i: &'v hir::Item) {
-                if let hir::ItemKind::Trait(..) = i.node {
-                    let def_id = self.map.local_def_id(i.id);
-                    self.traits.push(def_id);
+
+        fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {}
+
+        fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {}
+    }
+
+    tcx.hir().krate().visit_all_item_likes(&mut Visitor {
+        map: &tcx.hir(),
+        traits: &mut traits,
+    });
+
+    // Cross-crate:
+
+    let mut external_mods = FxHashSet::default();
+    fn handle_external_def(tcx: TyCtxt,
+                           traits: &mut Vec<DefId>,
+                           external_mods: &mut FxHashSet<DefId>,
+                           def: Def) {
+        let def_id = def.def_id();
+        match def {
+            Def::Trait(..) => {
+                traits.push(def_id);
+            }
+            Def::Mod(..) => {
+                if !external_mods.insert(def_id) {
+                    return;
+                }
+                for child in tcx.item_children(def_id).iter() {
+                    handle_external_def(tcx, traits, external_mods, child.def)
                 }
             }
-
-            fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
-            }
-
-            fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
-            }
+            _ => {}
         }
-        tcx.hir.krate().visit_all_item_likes(&mut Visitor {
-            map: &tcx.hir,
-            traits: &mut traits,
-        });
-
-        // Cross-crate:
-        let mut external_mods = FxHashSet::default();
-        fn handle_external_def(tcx: TyCtxt,
-                               traits: &mut Vec<DefId>,
-                               external_mods: &mut FxHashSet<DefId>,
-                               def: Def) {
-            let def_id = def.def_id();
-            match def {
-                Def::Trait(..) => {
-                    traits.push(def_id);
-                }
-                Def::Mod(..) => {
-                    if !external_mods.insert(def_id) {
-                        return;
-                    }
-                    for child in tcx.item_children(def_id).iter() {
-                        handle_external_def(tcx, traits, external_mods, child.def)
-                    }
-                }
-                _ => {}
-            }
-        }
-        for &cnum in tcx.crates().iter() {
-            let def_id = DefId {
-                krate: cnum,
-                index: CRATE_DEF_INDEX,
-            };
-            handle_external_def(tcx, &mut traits, &mut external_mods, Def::Mod(def_id));
-        }
+    }
+    for &cnum in tcx.crates().iter() {
+        let def_id = DefId {
+            krate: cnum,
+            index: CRATE_DEF_INDEX,
+        };
+        handle_external_def(tcx, &mut traits, &mut external_mods, Def::Mod(def_id));
+    }
 
     traits
 }
@@ -827,29 +823,29 @@
             hir::intravisit::walk_mod(self, module, node_id);
             return;
         }
-        // find a use statement
+        // Find a `use` statement.
         for item_id in &module.item_ids {
-            let item = self.tcx.hir.expect_item(item_id.id);
+            let item = self.tcx.hir().expect_item(item_id.id);
             match item.node {
                 hir::ItemKind::Use(..) => {
-                    // don't suggest placing a use before the prelude
-                    // import or other generated ones
+                    // Don't suggest placing a `use` before the prelude
+                    // import or other generated ones.
                     if item.span.ctxt().outer().expn_info().is_none() {
                         self.span = Some(item.span.shrink_to_lo());
                         self.found_use = true;
                         return;
                     }
                 },
-                // don't place use before extern crate
+                // Don't place `use` before `extern crate`...
                 hir::ItemKind::ExternCrate(_) => {}
-                // but place them before the first other item
+                // ...but do place them before the first other item.
                 _ => if self.span.map_or(true, |span| item.span < span ) {
                     if item.span.ctxt().outer().expn_info().is_none() {
-                        // don't insert between attributes and an item
+                        // Don't insert between attributes and an item.
                         if item.attrs.is_empty() {
                             self.span = Some(item.span.shrink_to_lo());
                         } else {
-                            // find the first attribute on the item
+                            // Find the first attribute on the item.
                             for attr in &item.attrs {
                                 if self.span.map_or(true, |span| attr.span < span) {
                                     self.span = Some(attr.span.shrink_to_lo());
@@ -861,6 +857,7 @@
             }
         }
     }
+
     fn nested_visit_map<'this>(
         &'this mut self
     ) -> hir::intravisit::NestedVisitorMap<'this, 'tcx> {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index e30a79b..8901f4b 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -8,14 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*
+/*!
 
 # check.rs
 
 Within the check phase of type check, we check each item one at a time
 (bodies of function expressions are checked as part of the containing
-function).  Inference is used to supply types wherever they are
-unknown.
+function). Inference is used to supply types wherever they are unknown.
 
 By far the most complex case is checking the body of a function. This
 can be broken down into several distinct phases:
@@ -65,7 +64,7 @@
 The types of top-level items, which never contain unbound type
 variables, are stored directly into the `tcx` tables.
 
-N.B.: A type variable is not the same thing as a type parameter.  A
+N.B., a type variable is not the same thing as a type parameter.  A
 type variable is rather an "instance" of a type parameter: that is,
 given a generic function `fn foo<T>(t: T)`: while checking the
 function `foo`, the type `ty_param(0)` refers to the type `T`, which
@@ -76,69 +75,6 @@
 
 */
 
-pub use self::Expectation::*;
-use self::autoderef::Autoderef;
-use self::callee::DeferredCallResolution;
-use self::coercion::{CoerceMany, DynamicCoerceMany};
-pub use self::compare_method::{compare_impl_method, compare_const_impl};
-use self::method::MethodCallee;
-use self::TupleArgumentsFlag::*;
-
-use astconv::AstConv;
-use hir::GenericArg;
-use hir::def::Def;
-use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use std::slice;
-use namespace::Namespace;
-use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
-use rustc::infer::opaque_types::OpaqueTypeDecl;
-use rustc::infer::type_variable::{TypeVariableOrigin};
-use rustc::middle::region;
-use rustc::mir::interpret::{ConstValue, GlobalId};
-use rustc::ty::subst::{CanonicalUserSubsts, UnpackedKind, Subst, Substs,
-                       UserSelfTy, UserSubsts};
-use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
-use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind};
-use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
-use rustc::ty::fold::TypeFoldable;
-use rustc::ty::query::Providers;
-use rustc::ty::util::{Representability, IntTypeExt, Discr};
-use rustc::ty::layout::VariantIdx;
-use rustc_data_structures::indexed_vec::Idx;
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
-
-use require_c_abi_if_variadic;
-use session::{CompileIncomplete, config, Session};
-use TypeAndSubsts;
-use lint;
-use util::common::{ErrorReported, indenter};
-use util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, NodeMap};
-
-use std::cell::{Cell, RefCell, Ref, RefMut};
-use rustc_data_structures::sync::Lrc;
-use std::collections::hash_map::Entry;
-use std::cmp;
-use std::fmt::Display;
-use std::iter;
-use std::mem::replace;
-use std::ops::{self, Deref};
-use rustc_target::spec::abi::Abi;
-use syntax::ast;
-use syntax::attr;
-use syntax::source_map::DUMMY_SP;
-use syntax::source_map::original_sp;
-use syntax::feature_gate::{GateIssue, emit_feature_err};
-use syntax::ptr::P;
-use syntax::symbol::{Symbol, LocalInternedString, keywords};
-use syntax::util::lev_distance::find_best_match_for_name;
-use syntax_pos::{self, BytePos, Span, MultiSpan};
-
-use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
-use rustc::hir::itemlikevisit::ItemLikeVisitor;
-use rustc::hir::Node;
-use rustc::hir::{self, PatKind, ItemKind};
-use rustc::middle::lang_items;
-
 mod autoderef;
 pub mod dropck;
 pub mod _match;
@@ -157,6 +93,65 @@
 mod intrinsic;
 mod op;
 
+use astconv::AstConv;
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use rustc::hir::{self, GenericArg, Node, ItemKind, PatKind};
+use rustc::hir::def::Def;
+use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
+use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use middle::lang_items;
+use namespace::Namespace;
+use rustc_data_structures::indexed_vec::Idx;
+use rustc_data_structures::sync::Lrc;
+use rustc_target::spec::abi::Abi;
+use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
+use rustc::infer::opaque_types::OpaqueTypeDecl;
+use rustc::infer::type_variable::{TypeVariableOrigin};
+use rustc::middle::region;
+use rustc::mir::interpret::{ConstValue, GlobalId};
+use rustc::ty::subst::{CanonicalUserSubsts, UnpackedKind, Subst, Substs,
+                       UserSelfTy, UserSubsts};
+use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
+use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind};
+use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
+use rustc::ty::fold::TypeFoldable;
+use rustc::ty::query::Providers;
+use rustc::ty::util::{Representability, IntTypeExt, Discr};
+use rustc::ty::layout::VariantIdx;
+use syntax_pos::{self, BytePos, Span, MultiSpan};
+use syntax::ast;
+use syntax::attr;
+use syntax::feature_gate::{GateIssue, emit_feature_err};
+use syntax::ptr::P;
+use syntax::source_map::{DUMMY_SP, original_sp};
+use syntax::symbol::{Symbol, LocalInternedString, keywords};
+use syntax::util::lev_distance::find_best_match_for_name;
+
+use std::cell::{Cell, RefCell, Ref, RefMut};
+use std::collections::hash_map::Entry;
+use std::cmp;
+use std::fmt::Display;
+use std::iter;
+use std::mem::replace;
+use std::ops::{self, Deref};
+use std::slice;
+
+use require_c_abi_if_variadic;
+use session::{CompileIncomplete, config, Session};
+use TypeAndSubsts;
+use lint;
+use util::common::{ErrorReported, indenter};
+use util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, NodeMap};
+
+pub use self::Expectation::*;
+use self::autoderef::Autoderef;
+use self::callee::DeferredCallResolution;
+use self::coercion::{CoerceMany, DynamicCoerceMany};
+pub use self::compare_method::{compare_impl_method, compare_const_impl};
+use self::method::MethodCallee;
+use self::TupleArgumentsFlag::*;
+
 /// The type of a local binding, including the revealed type for anon types.
 #[derive(Copy, Clone)]
 pub struct LocalTy<'tcx> {
@@ -605,8 +600,8 @@
     pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
                  -> InheritedBuilder<'a, 'gcx, 'tcx> {
         let hir_id_root = if def_id.is_local() {
-            let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-            let hir_id = tcx.hir.definitions().node_to_hir_id(node_id);
+            let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+            let hir_id = tcx.hir().definitions().node_to_hir_id(node_id);
             DefId::local(hir_id.owner)
         } else {
             def_id
@@ -631,10 +626,10 @@
 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
     fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self {
         let tcx = infcx.tcx;
-        let item_id = tcx.hir.as_local_node_id(def_id);
-        let body_id = item_id.and_then(|id| tcx.hir.maybe_body_owned_by(id));
+        let item_id = tcx.hir().as_local_node_id(def_id);
+        let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by(id));
         let implicit_region_bound = body_id.map(|body_id| {
-            let body = tcx.hir.body(body_id);
+            let body = tcx.hir().body(body_id);
             tcx.mk_region(ty::ReScope(region::Scope {
                 id: body.value.hir_id.local_id,
                 data: region::ScopeData::CallSite
@@ -707,13 +702,13 @@
 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
     tcx.sess.track_errors(|| {
         let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
-        tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor());
+        tcx.hir().krate().visit_all_item_likes(&mut visit.as_deep_visitor());
     })
 }
 
 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
     tcx.sess.track_errors(|| {
-        tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
+        tcx.hir().krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
     })
 }
 
@@ -778,7 +773,7 @@
                              id: ast::NodeId)
                              -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
 {
-    match tcx.hir.get(id) {
+    match tcx.hir().get(id) {
         Node::Item(item) => {
             match item.node {
                 hir::ItemKind::Const(_, body) |
@@ -825,7 +820,7 @@
         return tcx.has_typeck_tables(outer_def_id);
     }
 
-    let id = tcx.hir.as_local_node_id(def_id).unwrap();
+    let id = tcx.hir().as_local_node_id(def_id).unwrap();
     primary_body_of(tcx, id).is_some()
 }
 
@@ -845,14 +840,14 @@
         return tcx.typeck_tables_of(outer_def_id);
     }
 
-    let id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let span = tcx.hir.span(id);
+    let id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let span = tcx.hir().span(id);
 
     // Figure out what primary body this item has.
     let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
         span_bug!(span, "can't type-check body of {:?}", def_id);
     });
-    let body = tcx.hir.body(body_id);
+    let body = tcx.hir().body(body_id);
 
     let tables = Inherited::build(tcx, def_id).enter(|inh| {
         let param_env = tcx.param_env(def_id);
@@ -914,6 +909,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();
@@ -930,7 +926,7 @@
     // Consistency check our TypeckTables instance can hold all ItemLocalIds
     // it will need to hold.
     assert_eq!(tables.local_id_root,
-               Some(DefId::local(tcx.hir.definitions().node_to_hir_id(id).owner)));
+               Some(DefId::local(tcx.hir().definitions().node_to_hir_id(id).owner)));
     tables
 }
 
@@ -1087,8 +1083,8 @@
         fcx.yield_ty = Some(yield_ty);
     }
 
-    let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir.local_def_id(fn_id));
-    let outer_node_id = fcx.tcx.hir.as_local_node_id(outer_def_id).unwrap();
+    let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id(fn_id));
+    let outer_node_id = fcx.tcx.hir().as_local_node_id(outer_def_id).unwrap();
     GatherLocalsVisitor { fcx: &fcx, parent_id: outer_node_id, }.visit_body(body);
 
     // Add formal parameters.
@@ -1108,7 +1104,7 @@
         fcx.write_ty(arg.hir_id, arg_ty);
     }
 
-    let fn_hir_id = fcx.tcx.hir.node_to_hir_id(fn_id);
+    let fn_hir_id = fcx.tcx.hir().node_to_hir_id(fn_id);
     inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_hir_id, fn_sig);
 
     fcx.check_return_expr(&body.value);
@@ -1180,7 +1176,7 @@
 
     // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
     if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
-        if panic_impl_did == fcx.tcx.hir.local_def_id(fn_id) {
+        if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) {
             if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
                 // at this point we don't care if there are duplicate handlers or if the handler has
                 // the wrong signature as this value we'll be used when writing metadata and that
@@ -1195,7 +1191,7 @@
                 }
 
                 let inputs = fn_sig.inputs();
-                let span = fcx.tcx.hir.span(fn_id);
+                let span = fcx.tcx.hir().span(fn_id);
                 if inputs.len() == 1 {
                     let arg_is_panic_info = match inputs[0].sty {
                         ty::Ref(region, ty, mutbl) => match ty.sty {
@@ -1216,7 +1212,7 @@
                         );
                     }
 
-                    if let Node::Item(item) = fcx.tcx.hir.get(fn_id) {
+                    if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
                         if let ItemKind::Fn(_, _, ref generics, _) = item.node {
                             if !generics.params.is_empty() {
                                 fcx.tcx.sess.span_err(
@@ -1238,7 +1234,7 @@
 
     // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
     if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
-        if alloc_error_handler_did == fcx.tcx.hir.local_def_id(fn_id) {
+        if alloc_error_handler_did == fcx.tcx.hir().local_def_id(fn_id) {
             if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
                 if declared_ret_ty.sty != ty::Never {
                     fcx.tcx.sess.span_err(
@@ -1248,7 +1244,7 @@
                 }
 
                 let inputs = fn_sig.inputs();
-                let span = fcx.tcx.hir.span(fn_id);
+                let span = fcx.tcx.hir().span(fn_id);
                 if inputs.len() == 1 {
                     let arg_is_alloc_layout = match inputs[0].sty {
                         ty::Adt(ref adt, _) => {
@@ -1264,7 +1260,7 @@
                         );
                     }
 
-                    if let Node::Item(item) = fcx.tcx.hir.get(fn_id) {
+                    if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
                         if let ItemKind::Fn(_, _, ref generics, _) = item.node {
                             if !generics.params.is_empty() {
                                 fcx.tcx.sess.span_err(
@@ -1291,7 +1287,7 @@
 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           id: ast::NodeId,
                           span: Span) {
-    let def_id = tcx.hir.local_def_id(id);
+    let def_id = tcx.hir().local_def_id(id);
     let def = tcx.adt_def(def_id);
     def.destructor(tcx); // force the destructor to be evaluated
     check_representable(tcx, span, def_id);
@@ -1307,7 +1303,7 @@
 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          id: ast::NodeId,
                          span: Span) {
-    let def_id = tcx.hir.local_def_id(id);
+    let def_id = tcx.hir().local_def_id(id);
     let def = tcx.adt_def(def_id);
     def.destructor(tcx); // force the destructor to be evaluated
     check_representable(tcx, span, def_id);
@@ -1319,18 +1315,18 @@
     debug!(
         "check_item_type(it.id={}, it.name={})",
         it.id,
-        tcx.item_path_str(tcx.hir.local_def_id(it.id))
+        tcx.item_path_str(tcx.hir().local_def_id(it.id))
     );
     let _indenter = indenter();
     match it.node {
         // Consts can play a role in type-checking, so they are included here.
         hir::ItemKind::Static(..) => {
-            let def_id = tcx.hir.local_def_id(it.id);
+            let def_id = tcx.hir().local_def_id(it.id);
             tcx.typeck_tables_of(def_id);
             maybe_check_static_with_link_section(tcx, def_id, it.span);
         }
         hir::ItemKind::Const(..) => {
-            tcx.typeck_tables_of(tcx.hir.local_def_id(it.id));
+            tcx.typeck_tables_of(tcx.hir().local_def_id(it.id));
         }
         hir::ItemKind::Enum(ref enum_definition, _) => {
             check_enum(tcx, it.span, &enum_definition.variants, it.id);
@@ -1338,7 +1334,7 @@
         hir::ItemKind::Fn(..) => {} // entirely within check_item_body
         hir::ItemKind::Impl(.., ref impl_item_refs) => {
             debug!("ItemKind::Impl {} with id {}", it.name, it.id);
-            let impl_def_id = tcx.hir.local_def_id(it.id);
+            let impl_def_id = tcx.hir().local_def_id(it.id);
             if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
                 check_impl_items_against_trait(
                     tcx,
@@ -1352,7 +1348,7 @@
             }
         }
         hir::ItemKind::Trait(..) => {
-            let def_id = tcx.hir.local_def_id(it.id);
+            let def_id = tcx.hir().local_def_id(it.id);
             check_on_unimplemented(tcx, def_id, it);
         }
         hir::ItemKind::Struct(..) => {
@@ -1362,7 +1358,7 @@
             check_union(tcx, it.id, it.span);
         }
         hir::ItemKind::Existential(..) | hir::ItemKind::Ty(..) => {
-            let def_id = tcx.hir.local_def_id(it.id);
+            let def_id = tcx.hir().local_def_id(it.id);
             let pty_ty = tcx.type_of(def_id);
             let generics = tcx.generics_of(def_id);
             check_bounds_are_used(tcx, &generics, pty_ty);
@@ -1380,7 +1376,7 @@
                 }
             } else {
                 for item in &m.items {
-                    let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
+                    let generics = tcx.generics_of(tcx.hir().local_def_id(item.id));
                     if generics.params.len() - generics.own_counts().lifetimes != 0 {
                         let mut err = struct_span_err!(
                             tcx.sess,
@@ -1449,7 +1445,7 @@
 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                     trait_def_id: DefId,
                                     item: &hir::Item) {
-    let item_def_id = tcx.hir.local_def_id(item.id);
+    let item_def_id = tcx.hir().local_def_id(item.id);
     // an error would be reported if this fails.
     let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
 }
@@ -1522,12 +1518,12 @@
     let trait_def = tcx.trait_def(impl_trait_ref.def_id);
     let mut overridden_associated_type = None;
 
-    let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id));
+    let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
 
     // Check existing impl methods to see if they are both present in trait
     // and compatible with trait signature
     for impl_item in impl_items() {
-        let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
+        let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.id));
         let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
             .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
                        tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
@@ -1557,14 +1553,14 @@
                          err.span_label(impl_item.span, "does not match trait");
                          // We can only get the spans from local trait definition
                          // Same for E0324 and E0325
-                         if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
+                         if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
                             err.span_label(trait_span, "item in trait");
                          }
                          err.emit()
                     }
                 }
                 hir::ImplItemKind::Method(..) => {
-                    let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
+                    let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
                     if ty_trait_item.kind == ty::AssociatedKind::Method {
                         compare_impl_method(tcx,
                                             &ty_impl_item,
@@ -1579,7 +1575,7 @@
                             ty_impl_item.ident,
                             impl_trait_ref);
                          err.span_label(impl_item.span, "does not match trait");
-                         if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
+                         if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
                             err.span_label(trait_span, "item in trait");
                          }
                          err.emit()
@@ -1598,7 +1594,7 @@
                             ty_impl_item.ident,
                             impl_trait_ref);
                          err.span_label(impl_item.span, "does not match trait");
-                         if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
+                         if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
                             err.span_label(trait_span, "item in trait");
                          }
                          err.emit()
@@ -1641,7 +1637,7 @@
                     .map(|trait_item| trait_item.ident.to_string())
                     .collect::<Vec<_>>().join("`, `")));
         for trait_item in missing_items {
-            if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
+            if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
                 err.span_label(span, format!("`{}` from trait", trait_item.ident));
             } else {
                 err.note_trait_signature(trait_item.ident.to_string(),
@@ -1786,7 +1782,7 @@
         let param_env = tcx.param_env(field.did);
         let layout = tcx.layout_of(param_env.and(ty));
         // We are currently checking the type this field came from, so it must be local
-        let span = tcx.hir.span_if_local(field.did).unwrap();
+        let span = tcx.hir().span_if_local(field.did).unwrap();
         let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
         let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
         (span, zst, align1)
@@ -1815,7 +1811,7 @@
                             sp: Span,
                             vs: &'tcx [hir::Variant],
                             id: ast::NodeId) {
-    let def_id = tcx.hir.local_def_id(id);
+    let def_id = tcx.hir().local_def_id(id);
     let def = tcx.adt_def(def_id);
     def.destructor(tcx); // force the destructor to be evaluated
 
@@ -1843,7 +1839,7 @@
 
     for v in vs {
         if let Some(ref e) = v.node.disr_expr {
-            tcx.typeck_tables_of(tcx.hir.local_def_id(e.id));
+            tcx.typeck_tables_of(tcx.hir().local_def_id(e.id));
         }
     }
 
@@ -1852,14 +1848,14 @@
         // Check for duplicate discriminant values
         if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
             let variant_did = def.variants[VariantIdx::new(i)].did;
-            let variant_i_node_id = tcx.hir.as_local_node_id(variant_did).unwrap();
-            let variant_i = tcx.hir.expect_variant(variant_i_node_id);
+            let variant_i_node_id = tcx.hir().as_local_node_id(variant_did).unwrap();
+            let variant_i = tcx.hir().expect_variant(variant_i_node_id);
             let i_span = match variant_i.node.disr_expr {
-                Some(ref expr) => tcx.hir.span(expr.id),
-                None => tcx.hir.span(variant_i_node_id)
+                Some(ref expr) => tcx.hir().span(expr.id),
+                None => tcx.hir().span(variant_i_node_id)
             };
             let span = match v.node.disr_expr {
-                Some(ref expr) => tcx.hir.span(expr.id),
+                Some(ref expr) => tcx.hir().span(expr.id),
                 None => v.span
             };
             struct_span_err!(tcx.sess, span, E0081,
@@ -1881,9 +1877,9 @@
                                  -> Lrc<ty::GenericPredicates<'tcx>>
     {
         let tcx = self.tcx;
-        let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-        let item_id = tcx.hir.ty_param_owner(node_id);
-        let item_def_id = tcx.hir.local_def_id(item_id);
+        let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+        let item_id = tcx.hir().ty_param_owner(node_id);
+        let item_def_id = tcx.hir().local_def_id(item_id);
         let generics = tcx.generics_of(item_def_id);
         let index = generics.param_def_id_to_index[&def_id];
         Lrc::new(ty::GenericPredicates {
@@ -2089,7 +2085,7 @@
     pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> LocalTy<'tcx> {
         self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
             span_bug!(span, "no type for local variable {}",
-                      self.tcx.hir.node_to_string(nid))
+                      self.tcx.hir().node_to_string(nid))
         )
     }
 
@@ -2106,7 +2102,7 @@
     }
 
     pub fn write_field_index(&self, node_id: ast::NodeId, index: usize) {
-        let hir_id = self.tcx.hir.node_to_hir_id(node_id);
+        let hir_id = self.tcx.hir().node_to_hir_id(node_id);
         self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
     }
 
@@ -2294,7 +2290,7 @@
         parent_id: ast::NodeId,
         value: &T,
     ) -> T {
-        let parent_def_id = self.tcx.hir.local_def_id(parent_id);
+        let parent_def_id = self.tcx.hir().local_def_id(parent_id);
         debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
                parent_def_id,
                value);
@@ -2400,9 +2396,9 @@
             Some(&t) => t,
             None if self.is_tainted_by_errors() => self.tcx.types.err,
             None => {
-                let node_id = self.tcx.hir.hir_to_node_id(id);
+                let node_id = self.tcx.hir().hir_to_node_id(id);
                 bug!("no type for node {}: {} in fcx {}",
-                     node_id, self.tcx.hir.node_to_string(node_id),
+                     node_id, self.tcx.hir().node_to_string(node_id),
                      self.tag());
             }
         }
@@ -2730,7 +2726,7 @@
         );
         self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
                                   args_no_rcvr, method.sig.variadic, tuple_arguments,
-                                  self.tcx.hir.span_if_local(method.def_id));
+                                  self.tcx.hir().span_if_local(method.def_id));
         method.sig.output()
     }
 
@@ -2857,10 +2853,10 @@
                formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
 
         // Check the arguments.
-        // We do this in a pretty awful way: first we typecheck any arguments
-        // that are not closures, then we typecheck the closures. This is so
+        // We do this in a pretty awful way: first we type-check any arguments
+        // that are not closures, then we type-check the closures. This is so
         // that we have more information about the types of arguments when we
-        // typecheck the functions. This isn't really the right way to do this.
+        // type-check the functions. This isn't really the right way to do this.
         for &check_closures in &[false, true] {
             debug!("check_closures={}", check_closures);
 
@@ -2884,7 +2880,7 @@
             for (i, arg) in args.iter().take(t).enumerate() {
                 // Warn only for the first loop (the "no closures" one).
                 // Closure arguments themselves can't be diverging, but
-                // a previous argument can, e.g. `foo(panic!(), || {})`.
+                // a previous argument can, e.g., `foo(panic!(), || {})`.
                 if !check_closures {
                     self.warn_if_unreachable(arg.id, arg.span, "expression");
                 }
@@ -3091,9 +3087,9 @@
         self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
     }
 
-    // determine the `self` type, using fresh variables for all variables
+    // Determine the `Self` type, using fresh variables for all variables
     // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
-    // would return ($0, $1) where $0 and $1 are freshly instantiated type
+    // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
     // variables.
     pub fn impl_self_ty(&self,
                         span: Span, // (potential) receiver for this impl
@@ -3375,7 +3371,7 @@
                             len.assert_usize(self.tcx),
                             field.as_str().parse::<u64>()
                         ) {
-                            let base = self.tcx.hir.node_to_pretty_string(base.id);
+                            let base = self.tcx.hir().node_to_pretty_string(base.id);
                             let help = "instead of using tuple indexing, use array indexing";
                             let suggestion = format!("{}[{}]", base, field);
                             let applicability = if len < user_index {
@@ -3389,7 +3385,7 @@
                         }
                     }
                     ty::RawPtr(..) => {
-                        let base = self.tcx.hir.node_to_pretty_string(base.id);
+                        let base = self.tcx.hir().node_to_pretty_string(base.id);
                         let msg = format!("`{}` is a native pointer; try dereferencing it", base);
                         let suggestion = format!("(*{}).{}", base, field);
                         err.span_suggestion_with_applicability(
@@ -3538,16 +3534,16 @@
 
         let mut error_happened = false;
 
-        // Typecheck each field.
+        // Type-check each field.
         for field in ast_fields {
             let ident = tcx.adjust_ident(field.ident, variant.did, self.body_id).0;
             let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
                 seen_fields.insert(ident, field.span);
                 self.write_field_index(field.id, i);
 
-                // we don't look at stability attributes on
+                // We don't look at stability attributes on
                 // struct-like enums (yet...), but it's definitely not
-                // a bug to have construct one.
+                // a bug to have constructed one.
                 if adt_kind != ty::AdtKind::Enum {
                     tcx.check_stability(v_field.did, Some(expr_id), field.span);
                 }
@@ -3574,7 +3570,7 @@
             };
 
             // Make sure to give a type to the field even if there's
-            // an error, so we can continue typechecking
+            // an error, so we can continue type-checking.
             self.check_expr_coercable_to_type(&field.expr, field_type);
         }
 
@@ -3665,7 +3661,7 @@
 
         if let Some((variant, did, substs)) = variant {
             debug!("check_struct_path: did={:?} substs={:?}", did, substs);
-            let hir_id = self.tcx.hir.node_to_hir_id(node_id);
+            let hir_id = self.tcx.hir().node_to_hir_id(node_id);
             self.write_user_substs_from_substs(hir_id, substs, None);
 
             // Check bounds on type arguments used in the path.
@@ -3706,7 +3702,7 @@
             hir::QPath::TypeRelative(ref qself, _) => qself.span
         };
 
-        // Prohibit struct expressions when non exhaustive flag is set.
+        // Prohibit struct expressions when non-exhaustive flag is set.
         let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
         if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
             span_err!(self.tcx.sess, expr.span, E0639,
@@ -3759,7 +3755,7 @@
                                              expr: &'gcx hir::Expr,
                                              expected: Expectation<'tcx>,
                                              needs: Needs) -> Ty<'tcx> {
-        debug!(">> typechecking: expr={:?} expected={:?}",
+        debug!(">> type-checking: expr={:?} expected={:?}",
                expr, expected);
 
         // Warn for expressions after diverging siblings.
@@ -3796,7 +3792,7 @@
         self.diverges.set(self.diverges.get() | old_diverges);
         self.has_errors.set(self.has_errors.get() | old_has_errors);
 
-        debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
+        debug!("type of {} is...", self.tcx.hir().node_to_string(expr.id));
         debug!("... {:?}, expected is {:?}", ty, expected);
 
         ty
@@ -3961,7 +3957,7 @@
                     if !tcx.features().unsized_locals {
                         // We want to remove some Sized bounds from std functions,
                         // but don't want to expose the removal to stable Rust.
-                        // i.e. we don't want to allow
+                        // i.e., we don't want to allow
                         //
                         // ```rust
                         // drop as fn(str);
@@ -3969,7 +3965,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 +3979,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);
                 }
 
@@ -4073,7 +4081,7 @@
                             }
                         }
                     }
-                    // There was an error, make typecheck fail
+                    // There was an error; make type-check fail.
                     tcx.types.err
                 }
 
@@ -4082,7 +4090,7 @@
                 if destination.target_id.is_ok() {
                     tcx.types.never
                 } else {
-                    // There was an error, make typecheck fail
+                    // There was an error; make type-check fail.
                     tcx.types.err
                 }
             }
@@ -4267,7 +4275,7 @@
                 tcx.mk_array(element_ty, args.len() as u64)
             }
             hir::ExprKind::Repeat(ref element, ref count) => {
-                let count_def_id = tcx.hir.local_def_id(count.id);
+                let count_def_id = tcx.hir().local_def_id(count.id);
                 let param_env = ty::ParamEnv::empty();
                 let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
                 let instance = ty::Instance::resolve(
@@ -4400,7 +4408,7 @@
                                 }
                                 if needs_note {
                                     err.help("to access tuple elements, use tuple indexing \
-                                              syntax (e.g. `tuple.0`)");
+                                              syntax (e.g., `tuple.0`)");
                                 }
                             }
                             err.emit();
@@ -4450,7 +4458,7 @@
                                                                    ty, def, segment);
 
                 // Write back the new resolution.
-                let hir_id = self.tcx.hir.node_to_hir_id(node_id);
+                let hir_id = self.tcx.hir().node_to_hir_id(node_id);
                 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
 
                 (def, ty)
@@ -4476,7 +4484,7 @@
                 (self.to_ty(qself), segment)
             }
         };
-        let hir_id = self.tcx.hir.node_to_hir_id(node_id);
+        let hir_id = self.tcx.hir().node_to_hir_id(node_id);
         if let Some(cached_def) = self.tables.borrow().type_dependent_defs().get(hir_id) {
             // Return directly on cache hit. This is useful to avoid doubly reporting
             // errors with default match binding modes. See #44614.
@@ -4717,8 +4725,8 @@
     pub fn get_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, bool)> {
         // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
         // `while` before reaching it, as block tail returns are not available in them.
-        if let Some(fn_id) = self.tcx.hir.get_return_block(blk_id) {
-            let parent = self.tcx.hir.get(fn_id);
+        if let Some(fn_id) = self.tcx.hir().get_return_block(blk_id) {
+            let parent = self.tcx.hir().get(fn_id);
 
             if let Node::Item(&hir::Item {
                 name, node: hir::ItemKind::Fn(ref decl, ..), ..
@@ -5109,7 +5117,7 @@
             Def::Local(nid) | Def::Upvar(nid, ..) => {
                 let ty = self.local_ty(span, nid).decl_ty;
                 let ty = self.normalize_associated_types_in(span, &ty);
-                self.write_ty(self.tcx.hir.node_to_hir_id(node_id), ty);
+                self.write_ty(self.tcx.hir().node_to_hir_id(node_id), ty);
                 return (ty, def);
             }
             _ => {}
@@ -5236,8 +5244,8 @@
         assert!(!substs.has_escaping_bound_vars());
         assert!(!ty.has_escaping_bound_vars());
 
-        // Write the "user substs" down first thing for later.
-        let hir_id = self.tcx.hir.node_to_hir_id(node_id);
+        // First, store the "user substs" for later.
+        let hir_id = self.tcx.hir().node_to_hir_id(node_id);
         self.write_user_substs_from_substs(hir_id, substs, user_self_ty);
 
         // Add all the obligations that are required, substituting and
@@ -5292,7 +5300,7 @@
 
         // If our calling expression is indeed the function itself, we're good!
         // If not, generate an error that this can only be called directly.
-        if let Node::Expr(expr) = self.tcx.hir.get(self.tcx.hir.get_parent_node(node_id)) {
+        if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(node_id)) {
             if let hir::ExprKind::Call(ref callee, ..) = expr.node {
                 if callee.id == node_id {
                     return
@@ -5373,8 +5381,8 @@
     });
     for (&used, param) in types_used.iter().zip(types) {
         if !used {
-            let id = tcx.hir.as_local_node_id(param.def_id).unwrap();
-            let span = tcx.hir.span(id);
+            let id = tcx.hir().as_local_node_id(param.def_id).unwrap();
+            let span = tcx.hir().span(id);
             struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
                 .span_label(span, "unused type parameter")
                 .emit();
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index 54f4406..c40789c 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -170,7 +170,7 @@
                 // Find a suitable supertype of the LHS expression's type, by coercing to
                 // a type variable, to pass as the `Self` to the trait, avoiding invariant
                 // trait matching creating lifetime constraints that are too strict.
-                // E.g. adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
+                // e.g., adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
                 // in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`.
                 let lhs_ty = self.check_expr_with_needs(lhs_expr, Needs::None);
                 let fresh_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(lhs_expr.span));
@@ -186,7 +186,7 @@
         };
         let lhs_ty = self.resolve_type_vars_with_obligations(lhs_ty);
 
-        // NB: As we have not yet type-checked the RHS, we don't have the
+        // N.B., as we have not yet type-checked the RHS, we don't have the
         // type at hand. Make a variable to represent it. The whole reason
         // for this indirection is so that, below, we can check the expr
         // using this variable as the expected type, which sometimes lets
@@ -318,7 +318,7 @@
                                     self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
                                                             rhs_ty, &mut err, true) {
                                     // This has nothing here because it means we did string
-                                    // concatenation (e.g. "Hello " += "World!"). This means
+                                    // concatenation (e.g., "Hello " += "World!"). This means
                                     // we don't want the note in the else clause to be emitted
                                 } else if let ty::Param(_) = lhs_ty.sty {
                                     // FIXME: point to span of param
@@ -392,7 +392,7 @@
                                     self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
                                                             rhs_ty, &mut err, false) {
                                     // This has nothing here because it means we did string
-                                    // concatenation (e.g. "Hello " + "World!"). This means
+                                    // concatenation (e.g., "Hello " + "World!"). This means
                                     // we don't want the note in the else clause to be emitted
                                 } else if let ty::Param(_) = lhs_ty.sty {
                                     // FIXME: point to span of param
@@ -682,7 +682,7 @@
     Unary(hir::UnOp, Span),
 }
 
-/// Returns true if this is a built-in arithmetic operation (e.g. u32
+/// Returns true if this is a built-in arithmetic operation (e.g., u32
 /// + u32, i16x4 == i16x4) and false if these types would have to be
 /// overloaded to be legal. There are two reasons that we distinguish
 /// builtin operations from overloaded ones (vs trying to drive
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 212ee26..7960d74 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -121,7 +121,7 @@
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     pub fn regionck_expr(&self, body: &'gcx hir::Body) {
-        let subject = self.tcx.hir.body_owner_def_id(body.id());
+        let subject = self.tcx.hir().body_owner_def_id(body.id());
         let id = body.value.id;
         let mut rcx = RegionCtxt::new(
             self,
@@ -150,7 +150,7 @@
     /// types from which we should derive implied bounds, if any.
     pub fn regionck_item(&self, item_id: ast::NodeId, span: Span, wf_tys: &[Ty<'tcx>]) {
         debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys);
-        let subject = self.tcx.hir.local_def_id(item_id);
+        let subject = self.tcx.hir().local_def_id(item_id);
         let mut rcx = RegionCtxt::new(
             self,
             RepeatingScope(item_id),
@@ -175,7 +175,7 @@
     /// constraints to add.
     pub fn regionck_fn(&self, fn_id: ast::NodeId, body: &'gcx hir::Body) {
         debug!("regionck_fn(id={})", fn_id);
-        let subject = self.tcx.hir.body_owner_def_id(body.id());
+        let subject = self.tcx.hir().body_owner_def_id(body.id());
         let node_id = body.value.id;
         let mut rcx = RegionCtxt::new(
             self,
@@ -187,7 +187,7 @@
 
         if self.err_count_since_creation() == 0 {
             // regionck assumes typeck succeeded
-            rcx.visit_fn_body(fn_id, body, self.tcx.hir.span(fn_id));
+            rcx.visit_fn_body(fn_id, body, self.tcx.hir().span(fn_id));
         }
 
         rcx.resolve_regions_and_report_errors(SuppressRegionErrors::when_nll_is_enabled(self.tcx));
@@ -328,7 +328,7 @@
         self.call_site_scope = Some(call_site);
 
         let fn_sig = {
-            let fn_hir_id = self.tcx.hir.node_to_hir_id(id);
+            let fn_hir_id = self.tcx.hir().node_to_hir_id(id);
             match self.tables.borrow().liberated_fn_sigs().get(fn_hir_id) {
                 Some(f) => f.clone(),
                 None => {
@@ -375,7 +375,7 @@
         );
         let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope));
 
-        let body_hir_id = self.tcx.hir.node_to_hir_id(body_id.node_id);
+        let body_hir_id = self.tcx.hir().node_to_hir_id(body_id.node_id);
         self.type_of_node_must_outlive(infer::CallReturn(span), body_hir_id, call_site_region);
 
         self.constrain_opaque_types(
@@ -483,7 +483,7 @@
         let old_call_site_scope = self.call_site_scope;
         let env_snapshot = self.outlives_environment.push_snapshot_pre_closure();
 
-        let body = self.tcx.hir.body(body_id);
+        let body = self.tcx.hir().body(body_id);
         self.visit_fn_body(id, body, span);
 
         // Restore state from previous function.
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index 312ce40..562022c 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -74,7 +74,7 @@
 
     fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
         if let hir::ExprKind::Closure(cc, _, body_id, _, _) = expr.node {
-            let body = self.fcx.tcx.hir.body(body_id);
+            let body = self.fcx.tcx.hir().body(body_id);
             self.visit_body(body);
             self.fcx
                 .analyze_closure(expr.id, expr.hir_id, expr.span, body, cc);
@@ -135,7 +135,7 @@
             for freevar in freevars {
                 let upvar_id = ty::UpvarId {
                     var_path: ty::UpvarPath {
-                        hir_id : self.tcx.hir.node_to_hir_id(freevar.var_id()),
+                        hir_id : self.tcx.hir().node_to_hir_id(freevar.var_id()),
                     },
                     closure_expr_id: LocalDefId::from_def_id(closure_def_id),
                 };
@@ -161,7 +161,7 @@
             }
         });
 
-        let body_owner_def_id = self.tcx.hir.body_owner_def_id(body.id());
+        let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id());
         let region_scope_tree = &self.tcx.region_scope_tree(body_owner_def_id);
         let mut delegate = InferBorrowKind {
             fcx: self,
@@ -240,14 +240,14 @@
         // This may change if abstract return types of some sort are
         // implemented.
         let tcx = self.tcx;
-        let closure_def_index = tcx.hir.local_def_id(closure_id);
+        let closure_def_index = tcx.hir().local_def_id(closure_id);
 
         tcx.with_freevars(closure_id, |freevars| {
             freevars
                 .iter()
                 .map(|freevar| {
                     let var_node_id = freevar.var_id();
-                    let var_hir_id = tcx.hir.node_to_hir_id(var_node_id);
+                    let var_hir_id = tcx.hir().node_to_hir_id(var_node_id);
                     let freevar_ty = self.node_ty(var_hir_id);
                     let upvar_id = ty::UpvarId {
                         var_path: ty::UpvarPath {
@@ -647,6 +647,6 @@
 }
 
 fn var_name(tcx: TyCtxt, var_hir_id: hir::HirId) -> ast::Name {
-    let var_node_id = tcx.hir.hir_to_node_id(var_hir_id);
-    tcx.hir.name(var_node_id)
+    let var_node_id = tcx.hir().hir_to_node_id(var_hir_id);
+    tcx.hir().name(var_node_id)
 }
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index e5fe74f..6471e74 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -73,8 +73,8 @@
 /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
 /// the types first.
 pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let item = tcx.hir.expect_item(node_id);
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let item = tcx.hir().expect_item(node_id);
 
     debug!("check_item_well_formed(it.id={}, it.name={})",
            item.id,
@@ -99,7 +99,7 @@
         // won't be allowed unless there's an *explicit* implementation of `Send`
         // for `T`
         hir::ItemKind::Impl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => {
-            let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id))
+            let is_auto = tcx.impl_trait_ref(tcx.hir().local_def_id(item.id))
                                 .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
             if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) {
                 tcx.sess.span_err(item.span, "impls of auto traits cannot be default");
@@ -161,8 +161,8 @@
 }
 
 pub fn check_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let trait_item = tcx.hir.expect_trait_item(node_id);
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let trait_item = tcx.hir().expect_trait_item(node_id);
 
     let method_sig = match trait_item.node {
         hir::TraitItemKind::Method(ref sig, _) => Some(sig),
@@ -172,8 +172,8 @@
 }
 
 pub fn check_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let impl_item = tcx.hir.expect_impl_item(node_id);
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let impl_item = tcx.hir().expect_impl_item(node_id);
 
     let method_sig = match impl_item.node {
         hir::ImplItemKind::Method(ref sig, _) => Some(sig),
@@ -190,7 +190,7 @@
 
     let code = ObligationCauseCode::MiscObligation;
     for_id(tcx, item_id, span).with_fcx(|fcx, tcx| {
-        let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id));
+        let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
 
         let (mut implied_bounds, self_ty) = match item.container {
             ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()),
@@ -236,7 +236,7 @@
 
 fn for_id<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId, span: Span)
                           -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
-    let def_id = tcx.hir.local_def_id(id);
+    let def_id = tcx.hir().local_def_id(id);
     CheckWfFcxBuilder {
         inherited: Inherited::build(tcx, def_id),
         id,
@@ -252,7 +252,7 @@
 {
     for_item(tcx, item).with_fcx(|fcx, fcx_tcx| {
         let variants = lookup_fields(fcx);
-        let def_id = fcx.tcx.hir.local_def_id(item.id);
+        let def_id = fcx.tcx.hir().local_def_id(item.id);
         let packed = fcx.tcx.adt_def(def_id).repr.packed();
 
         for variant in &variants {
@@ -315,7 +315,7 @@
 fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
     debug!("check_trait: {:?}", item.id);
 
-    let trait_def_id = tcx.hir.local_def_id(item.id);
+    let trait_def_id = tcx.hir().local_def_id(item.id);
 
     let trait_def = tcx.trait_def(trait_def_id);
     if trait_def.is_marker {
@@ -337,7 +337,7 @@
 
 fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
     for_item(tcx, item).with_fcx(|fcx, tcx| {
-        let def_id = fcx.tcx.hir.local_def_id(item.id);
+        let def_id = fcx.tcx.hir().local_def_id(item.id);
         let sig = fcx.tcx.fn_sig(def_id);
         let sig = fcx.normalize_associated_types_in(item.span, &sig);
         let mut implied_bounds = vec![];
@@ -356,7 +356,7 @@
     debug!("check_item_type: {:?}", 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 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;
@@ -387,7 +387,7 @@
     debug!("check_impl: {:?}", item);
 
     for_item(tcx, item).with_fcx(|fcx, tcx| {
-        let item_def_id = fcx.tcx.hir.local_def_id(item.id);
+        let item_def_id = fcx.tcx.hir().local_def_id(item.id);
 
         match *ast_trait_ref {
             Some(ref ast_trait_ref) => {
@@ -621,7 +621,7 @@
                 let generics = tcx.generics_of(def_id);
                 // only check named existential types
                 if generics.parent.is_none() {
-                    let opaque_node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+                    let opaque_node_id = tcx.hir().as_local_node_id(def_id).unwrap();
                     if may_define_existential_type(tcx, fn_def_id, opaque_node_id) {
                         trace!("check_existential_types may define. Generics: {:#?}", generics);
                         let mut seen: FxHashMap<_, Vec<_>> = FxHashMap::default();
@@ -821,7 +821,7 @@
                                            item: &hir::Item,
                                            hir_generics: &hir::Generics)
 {
-    let item_def_id = tcx.hir.local_def_id(item.id);
+    let item_def_id = tcx.hir().local_def_id(item.id);
     let ty = tcx.type_of(item_def_id);
     if tcx.has_error_field(ty) {
         return;
@@ -908,7 +908,7 @@
 
     let empty_env = ty::ParamEnv::empty();
 
-    let def_id = fcx.tcx.hir.local_def_id(id);
+    let def_id = fcx.tcx.hir().local_def_id(id);
     let predicates = fcx.tcx.predicates_of(def_id).predicates
         .iter()
         .map(|(p, _)| *p)
@@ -956,21 +956,21 @@
 
     fn visit_item(&mut self, i: &hir::Item) {
         debug!("visit_item: {:?}", i);
-        let def_id = self.tcx.hir.local_def_id(i.id);
+        let def_id = self.tcx.hir().local_def_id(i.id);
         ty::query::queries::check_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_item(self, i);
     }
 
     fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
         debug!("visit_trait_item: {:?}", trait_item);
-        let def_id = self.tcx.hir.local_def_id(trait_item.id);
+        let def_id = self.tcx.hir().local_def_id(trait_item.id);
         ty::query::queries::check_trait_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_trait_item(self, trait_item)
     }
 
     fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) {
         debug!("visit_impl_item: {:?}", impl_item);
-        let def_id = self.tcx.hir.local_def_id(impl_item.id);
+        let def_id = self.tcx.hir().local_def_id(impl_item.id);
         ty::query::queries::check_impl_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_impl_item(self, impl_item)
     }
@@ -991,7 +991,7 @@
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     fn non_enum_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
         let fields = struct_def.fields().iter().map(|field| {
-            let field_ty = self.tcx.type_of(self.tcx.hir.local_def_id(field.id));
+            let field_ty = self.tcx.type_of(self.tcx.hir().local_def_id(field.id));
             let field_ty = self.normalize_associated_types_in(field.span,
                                                               &field_ty);
             AdtField { ty: field_ty, span: field.span }
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 669f2bc..8d7fc00 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -32,8 +32,8 @@
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) -> &'gcx ty::TypeckTables<'gcx> {
-        let item_id = self.tcx.hir.body_owner(body.id());
-        let item_def_id = self.tcx.hir.local_def_id(item_id);
+        let item_id = self.tcx.hir().body_owner(body.id());
+        let item_def_id = self.tcx.hir().local_def_id(item_id);
 
         // This attribute causes us to dump some writeback information
         // in the form of errors, which is used for unit tests.
@@ -99,7 +99,7 @@
         body: &'gcx hir::Body,
         rustc_dump_user_substs: bool,
     ) -> WritebackCx<'cx, 'gcx, 'tcx> {
-        let owner = fcx.tcx.hir.definitions().node_to_hir_id(body.id().node_id);
+        let owner = fcx.tcx.hir().definitions().node_to_hir_id(body.id().node_id);
 
         WritebackCx {
             fcx,
@@ -233,7 +233,7 @@
 
         match e.node {
             hir::ExprKind::Closure(_, _, body, _, _) => {
-                let body = self.fcx.tcx.hir.body(body);
+                let body = self.fcx.tcx.hir().body(body);
                 for arg in &body.arguments {
                     self.visit_node_id(e.span, arg.hir_id);
                 }
@@ -398,7 +398,7 @@
                 c_sig
             } else {
                 span_bug!(
-                    self.fcx.tcx.hir.span_if_local(def_id).unwrap(),
+                    self.fcx.tcx.hir().span_if_local(def_id).unwrap(),
                     "writeback: `{:?}` missing from the global type context",
                     c_sig
                 );
@@ -412,7 +412,7 @@
 
     fn visit_opaque_types(&mut self, span: Span) {
         for (&def_id, opaque_defn) in self.fcx.opaque_types.borrow().iter() {
-            let node_id = self.tcx().hir.as_local_node_id(def_id).unwrap();
+            let node_id = self.tcx().hir().as_local_node_id(def_id).unwrap();
             let instantiated_ty = self.resolve(&opaque_defn.concrete_ty, &node_id);
 
             let generics = self.tcx().generics_of(def_id);
@@ -545,7 +545,7 @@
     }
 
     fn visit_field_id(&mut self, node_id: ast::NodeId) {
-        let hir_id = self.tcx().hir.node_to_hir_id(node_id);
+        let hir_id = self.tcx().hir().node_to_hir_id(node_id);
         if let Some(index) = self.fcx
             .tables
             .borrow_mut()
@@ -591,8 +591,8 @@
 
             // Unit-testing mechanism:
             if self.rustc_dump_user_substs {
-                let node_id = self.tcx().hir.hir_to_node_id(hir_id);
-                let span = self.tcx().hir.span(node_id);
+                let node_id = self.tcx().hir().hir_to_node_id(hir_id);
+                let span = self.tcx().hir().span(node_id);
                 self.tcx().sess.span_err(
                     span,
                     &format!("user substs: {:?}", user_substs),
@@ -710,21 +710,21 @@
 
 impl Locatable for ast::NodeId {
     fn to_span(&self, tcx: &TyCtxt) -> Span {
-        tcx.hir.span(*self)
+        tcx.hir().span(*self)
     }
 }
 
 impl Locatable for DefIndex {
     fn to_span(&self, tcx: &TyCtxt) -> Span {
-        let node_id = tcx.hir.def_index_to_node_id(*self);
-        tcx.hir.span(node_id)
+        let node_id = tcx.hir().def_index_to_node_id(*self);
+        tcx.hir().span(node_id)
     }
 }
 
 impl Locatable for hir::HirId {
     fn to_span(&self, tcx: &TyCtxt) -> Span {
-        let node_id = tcx.hir.hir_to_node_id(*self);
-        tcx.hir.span(node_id)
+        let node_id = tcx.hir().hir_to_node_id(*self);
+        tcx.hir().span(node_id)
     }
 }
 
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index 9c1860f..e6171e9 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -25,15 +25,15 @@
 
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut used_trait_imports = DefIdSet::default();
-    for &body_id in tcx.hir.krate().bodies.keys() {
-        let item_def_id = tcx.hir.body_owner_def_id(body_id);
+    for &body_id in tcx.hir().krate().bodies.keys() {
+        let item_def_id = tcx.hir().body_owner_def_id(body_id);
         let imports = tcx.used_trait_imports(item_def_id);
         debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
         used_trait_imports.extend(imports.iter());
     }
 
     let mut visitor = CheckVisitor { tcx, used_trait_imports };
-    tcx.hir.krate().visit_all_item_likes(&mut visitor);
+    tcx.hir().krate().visit_all_item_likes(&mut visitor);
 
     unused_crates_lint(tcx);
 }
@@ -62,12 +62,12 @@
 
 impl<'a, 'tcx> CheckVisitor<'a, 'tcx> {
     fn check_import(&self, id: ast::NodeId, span: Span) {
-        let def_id = self.tcx.hir.local_def_id(id);
+        let def_id = self.tcx.hir().local_def_id(id);
         if !self.tcx.maybe_unused_trait_import(def_id) {
             return;
         }
 
-        let import_def_id = self.tcx.hir.local_def_id(id);
+        let import_def_id = self.tcx.hir().local_def_id(id);
         if self.used_trait_imports.contains(&import_def_id) {
             return;
         }
@@ -105,8 +105,8 @@
             // Note that if we carry through to the `extern_mod_stmt_cnum` query
             // below it'll cause a panic because `def_id` is actually bogus at this
             // point in time otherwise.
-            if let Some(id) = tcx.hir.as_local_node_id(def_id) {
-                if tcx.hir.find(id).is_none() {
+            if let Some(id) = tcx.hir().as_local_node_id(def_id) {
+                if tcx.hir().find(id).is_none() {
                     return false;
                 }
             }
@@ -125,14 +125,14 @@
 
     // Collect all the extern crates (in a reliable order).
     let mut crates_to_lint = vec![];
-    tcx.hir.krate().visit_all_item_likes(&mut CollectExternCrateVisitor {
+    tcx.hir().krate().visit_all_item_likes(&mut CollectExternCrateVisitor {
         tcx,
         crates_to_lint: &mut crates_to_lint,
     });
 
     for extern_crate in &crates_to_lint {
-        let id = tcx.hir.as_local_node_id(extern_crate.def_id).unwrap();
-        let item = tcx.hir.expect_item(id);
+        let id = tcx.hir().as_local_node_id(extern_crate.def_id).unwrap();
+        let item = tcx.hir().expect_item(id);
 
         // If the crate is fully unused, we suggest removing it altogether.
         // We do this in any edition.
@@ -223,7 +223,7 @@
 impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CollectExternCrateVisitor<'a, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
         if let hir::ItemKind::ExternCrate(orig_name) = item.node {
-            let extern_crate_def_id = self.tcx.hir.local_def_id(item.id);
+            let extern_crate_def_id = self.tcx.hir().local_def_id(item.id);
             self.crates_to_lint.push(
                 ExternCrateToLint {
                     def_id: extern_crate_def_id,
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index a5ad31e..2d5dcf0 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -46,8 +46,8 @@
         where F: FnMut(TyCtxt<'a, 'tcx, 'tcx>, DefId)
     {
         if Some(self.trait_def_id) == trait_def_id {
-            for &impl_id in self.tcx.hir.trait_impls(self.trait_def_id) {
-                let impl_def_id = self.tcx.hir.local_def_id(impl_id);
+            for &impl_id in self.tcx.hir().trait_impls(self.trait_def_id) {
+                let impl_def_id = self.tcx.hir().local_def_id(impl_id);
                 f(self.tcx, impl_def_id);
             }
         }
@@ -60,8 +60,8 @@
         /* do nothing */
     } else {
         // Destructors only work on nominal types.
-        if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_did) {
-            if let Some(Node::Item(item)) = tcx.hir.find(impl_node_id) {
+        if let Some(impl_node_id) = tcx.hir().as_local_node_id(impl_did) {
+            if let Some(Node::Item(item)) = tcx.hir().find(impl_node_id) {
                 let span = match item.node {
                     ItemKind::Impl(.., ref ty, _) => ty.span,
                     _ => item.span,
@@ -86,7 +86,7 @@
 fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) {
     debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
 
-    let impl_node_id = if let Some(n) = tcx.hir.as_local_node_id(impl_did) {
+    let impl_node_id = if let Some(n) = tcx.hir().as_local_node_id(impl_did) {
         n
     } else {
         debug!("visit_implementation_of_copy(): impl not in this crate");
@@ -97,7 +97,7 @@
     debug!("visit_implementation_of_copy: self_type={:?} (bound)",
            self_type);
 
-    let span = tcx.hir.span(impl_node_id);
+    let span = tcx.hir().span(impl_node_id);
     let param_env = tcx.param_env(impl_did);
     assert!(!self_type.has_escaping_bound_vars());
 
@@ -107,7 +107,7 @@
     match param_env.can_type_implement_copy(tcx, self_type) {
         Ok(()) => {}
         Err(CopyImplementationError::InfrigingFields(fields)) => {
-            let item = tcx.hir.expect_item(impl_node_id);
+            let item = tcx.hir().expect_item(impl_node_id);
             let span = if let ItemKind::Impl(.., Some(ref tr), _, _) = item.node {
                 tr.path.span
             } else {
@@ -124,7 +124,7 @@
             err.emit()
         }
         Err(CopyImplementationError::NotAnAdt) => {
-            let item = tcx.hir.expect_item(impl_node_id);
+            let item = tcx.hir().expect_item(impl_node_id);
             let span = if let ItemKind::Impl(.., ref ty, _) = item.node {
                 ty.span
             } else {
@@ -172,8 +172,8 @@
     if impl_did.is_local() {
         let dispatch_from_dyn_trait = tcx.lang_items().dispatch_from_dyn_trait().unwrap();
 
-        let impl_node_id = tcx.hir.as_local_node_id(impl_did).unwrap();
-        let span = tcx.hir.span(impl_node_id);
+        let impl_node_id = tcx.hir().as_local_node_id(impl_did).unwrap();
+        let span = tcx.hir().span(impl_node_id);
 
         let source = tcx.type_of(impl_did);
         assert!(!source.has_escaping_bound_vars());
@@ -342,7 +342,7 @@
     });
 
     // this provider should only get invoked for local def-ids
-    let impl_node_id = gcx.hir.as_local_node_id(impl_did).unwrap_or_else(|| {
+    let impl_node_id = gcx.hir().as_local_node_id(impl_did).unwrap_or_else(|| {
         bug!("coerce_unsized_info: invoked for non-local def-id {:?}", impl_did)
     });
 
@@ -354,7 +354,7 @@
            source,
            target);
 
-    let span = gcx.hir.span(impl_node_id);
+    let span = gcx.hir().span(impl_node_id);
     let param_env = gcx.param_env(impl_did);
     assert!(!source.has_escaping_bound_vars());
 
@@ -469,7 +469,7 @@
                         // variance where possible. (This is because
                         // we may have to evaluate constraint
                         // expressions in the course of execution.)
-                        // See e.g. #41936.
+                        // See e.g., #41936.
                         if let Ok(ok) = infcx.at(&cause, param_env).eq(a, b) {
                             if ok.obligations.is_empty() {
                                 return None;
@@ -477,7 +477,7 @@
                         }
 
                         // Collect up all fields that were significantly changed
-                        // i.e. those that contain T in coerce_unsized T -> U
+                        // i.e., those that contain T in coerce_unsized T -> U
                         Some((i, a, b))
                     })
                     .collect::<Vec<_>>();
@@ -491,11 +491,11 @@
                                being coerced, none found");
                     return err_info;
                 } else if diff_fields.len() > 1 {
-                    let item = gcx.hir.expect_item(impl_node_id);
+                    let item = gcx.hir().expect_item(impl_node_id);
                     let span = if let ItemKind::Impl(.., Some(ref t), _, _) = item.node {
                         t.path.span
                     } else {
-                        gcx.hir.span(impl_node_id)
+                        gcx.hir().span(impl_node_id)
                     };
 
                     let mut err = struct_span_err!(gcx.sess,
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index d9dff14..59989a6 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -33,7 +33,7 @@
                                       -> Lrc<CrateInherentImpls> {
     assert_eq!(crate_num, LOCAL_CRATE);
 
-    let krate = tcx.hir.krate();
+    let krate = tcx.hir().krate();
     let mut collect = InherentCollect {
         tcx,
         impls_map: Default::default(),
@@ -95,7 +95,7 @@
             _ => return
         };
 
-        let def_id = self.tcx.hir.local_def_id(item.id);
+        let def_id = self.tcx.hir().local_def_id(item.id);
         let self_ty = self.tcx.type_of(def_id);
         let lang_items = self.tcx.lang_items();
         match self_ty.sty {
@@ -298,7 +298,7 @@
             // Add the implementation to the mapping from implementation to base
             // type def ID, if there is a base type for this implementation and
             // the implementation does not have any associated traits.
-            let impl_def_id = self.tcx.hir.local_def_id(item.id);
+            let impl_def_id = self.tcx.hir().local_def_id(item.id);
             let mut rc_vec = self.impls_map.inherent_impls
                                            .entry(def_id)
                                            .or_default();
diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
index c0260d6..ec1a439 100644
--- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs
+++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
@@ -20,7 +20,7 @@
 pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                     crate_num: CrateNum) {
     assert_eq!(crate_num, LOCAL_CRATE);
-    let krate = tcx.hir.krate();
+    let krate = tcx.hir().krate();
     krate.visit_all_item_likes(&mut InherentOverlapChecker { tcx });
 }
 
@@ -46,7 +46,7 @@
 
             for &item2 in &impl_items2[..] {
                 if (name, namespace) == name_and_namespace(item2) {
-                    let node_id = self.tcx.hir.as_local_node_id(impl1);
+                    let node_id = self.tcx.hir().as_local_node_id(impl1);
                     let mut err = if used_to_be_allowed && node_id.is_some() {
                         self.tcx.struct_span_lint_node(
                             lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
@@ -126,7 +126,7 @@
             hir::ItemKind::Struct(..) |
             hir::ItemKind::Trait(..) |
             hir::ItemKind::Union(..) => {
-                let type_def_id = self.tcx.hir.local_def_id(item.id);
+                let type_def_id = self.tcx.hir().local_def_id(item.id);
                 self.check_for_overlapping_inherent_impls(type_def_id);
             }
             _ => {}
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 9b17654..0360617 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -29,7 +29,7 @@
 mod unsafety;
 
 fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
-    let impl_def_id = tcx.hir.local_def_id(node_id);
+    let impl_def_id = tcx.hir().local_def_id(node_id);
 
     // If there are no traits, then this implementation must have a
     // base type.
@@ -40,7 +40,7 @@
                tcx.item_path_str(impl_def_id));
 
         // Skip impls where one of the self type is an error type.
-        // This occurs with e.g. resolve failures (#30589).
+        // This occurs with e.g., resolve failures (#30589).
         if trait_ref.references_error() {
             return;
         }
@@ -135,7 +135,7 @@
 }
 
 fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
-    let impls = tcx.hir.trait_impls(def_id);
+    let impls = tcx.hir().trait_impls(def_id);
     for &impl_id in impls {
         check_impl(tcx, impl_id);
     }
@@ -146,7 +146,7 @@
 }
 
 pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    for &trait_def_id in tcx.hir.krate().trait_impls.keys() {
+    for &trait_def_id in tcx.hir().krate().trait_impls.keys() {
         ty::query::queries::coherent_trait::ensure(tcx, trait_def_id);
     }
 
@@ -162,7 +162,7 @@
 /// same type. Likewise, no two inherent impls for a given type
 /// constructor provide a method with the same name.
 fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
-    let impl_def_id = tcx.hir.local_def_id(node_id);
+    let impl_def_id = tcx.hir().local_def_id(node_id);
     let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
     let trait_def_id = trait_ref.def_id;
 
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index 14c6864..131413e 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -18,7 +18,7 @@
 
 pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut orphan = OrphanChecker { tcx };
-    tcx.hir.krate().visit_all_item_likes(&mut orphan);
+    tcx.hir().krate().visit_all_item_likes(&mut orphan);
 }
 
 struct OrphanChecker<'cx, 'tcx: 'cx> {
@@ -32,11 +32,11 @@
     /// to prevent inundating the user with a bunch of similar error
     /// reports.
     fn visit_item(&mut self, item: &hir::Item) {
-        let def_id = self.tcx.hir.local_def_id(item.id);
+        let def_id = self.tcx.hir().local_def_id(item.id);
         // "Trait" impl
         if let hir::ItemKind::Impl(.., Some(_), _, _) = item.node {
             debug!("coherence2::orphan check: trait impl {}",
-                   self.tcx.hir.node_to_string(item.id));
+                   self.tcx.hir().node_to_string(item.id));
             let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
             let trait_def_id = trait_ref.def_id;
             let cm = self.tcx.sess.source_map();
@@ -60,7 +60,7 @@
                                      sp,
                                      E0210,
                                      "type parameter `{}` must be used as the type parameter \
-                                      for some local type (e.g. `MyStruct<{}>`)",
+                                      for some local type (e.g., `MyStruct<{}>`)",
                                      param_ty,
                                      param_ty)
                         .span_label(sp,
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index 0894c1d..b4196b5 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -17,7 +17,7 @@
 
 pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut unsafety = UnsafetyChecker { tcx };
-    tcx.hir.krate().visit_all_item_likes(&mut unsafety);
+    tcx.hir().krate().visit_all_item_likes(&mut unsafety);
 }
 
 struct UnsafetyChecker<'cx, 'tcx: 'cx> {
@@ -31,7 +31,7 @@
                                 unsafety: hir::Unsafety,
                                 polarity: hir::ImplPolarity)
     {
-        if let Some(trait_ref) = self.tcx.impl_trait_ref(self.tcx.hir.local_def_id(item.id)) {
+        if let Some(trait_ref) = self.tcx.impl_trait_ref(self.tcx.hir().local_def_id(item.id)) {
             let trait_def = self.tcx.trait_def(trait_ref.def_id);
             let unsafe_attr = impl_generics.and_then(|generics| {
                 generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle")
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index a1bb0b5..3b8b6d4 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -66,7 +66,7 @@
 
 pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut visitor = CollectItemTypesVisitor { tcx };
-    tcx.hir
+    tcx.hir()
        .krate()
        .visit_all_item_likes(&mut visitor.as_deep_visitor());
 }
@@ -97,7 +97,7 @@
 /// AstConv. It has information about the predicates that are defined
 /// on the trait. Unfortunately, this predicate information is
 /// available in various different forms at various points in the
-/// process. So we can't just store a pointer to e.g. the AST or the
+/// process. So we can't just store a pointer to e.g., the AST or the
 /// parsed ty form, we have to be more flexible. To this end, the
 /// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
 /// `get_type_parameter_bounds` requests, drawing the information from
@@ -115,7 +115,7 @@
 
 impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.tcx.hir)
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
@@ -130,7 +130,7 @@
                 hir::GenericParamKind::Type {
                     default: Some(_), ..
                 } => {
-                    let def_id = self.tcx.hir.local_def_id(param.id);
+                    let def_id = self.tcx.hir().local_def_id(param.id);
                     self.tcx.type_of(def_id);
                 }
                 hir::GenericParamKind::Type { .. } => {}
@@ -141,7 +141,7 @@
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         if let hir::ExprKind::Closure(..) = expr.node {
-            let def_id = self.tcx.hir.local_def_id(expr.id);
+            let def_id = self.tcx.hir().local_def_id(expr.id);
             self.tcx.generics_of(def_id);
             self.tcx.type_of(def_id);
         }
@@ -252,12 +252,12 @@
     // written inline like `<T : Foo>` or in a where clause like
     // `where T : Foo`.
 
-    let param_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let param_owner = tcx.hir.ty_param_owner(param_id);
-    let param_owner_def_id = tcx.hir.local_def_id(param_owner);
+    let param_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let param_owner = tcx.hir().ty_param_owner(param_id);
+    let param_owner_def_id = tcx.hir().local_def_id(param_owner);
     let generics = tcx.generics_of(param_owner_def_id);
     let index = generics.param_def_id_to_index[&def_id];
-    let ty = tcx.mk_ty_param(index, tcx.hir.ty_param_name(param_id).as_interned_str());
+    let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(param_id).as_interned_str());
 
     // Don't look for bounds where the type parameter isn't in scope.
     let parent = if item_def_id == param_owner_def_id {
@@ -277,8 +277,8 @@
         },
     );
 
-    let item_node_id = tcx.hir.as_local_node_id(item_def_id).unwrap();
-    let ast_generics = match tcx.hir.get(item_node_id) {
+    let item_node_id = tcx.hir().as_local_node_id(item_def_id).unwrap();
+    let ast_generics = match tcx.hir().get(item_node_id) {
         Node::TraitItem(item) => &item.generics,
 
         Node::ImplItem(item) => &item.generics,
@@ -384,7 +384,7 @@
     if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ast_ty.node {
         match path.def {
             Def::SelfTy(Some(def_id), None) | Def::TyParam(def_id) => {
-                def_id == tcx.hir.local_def_id(param_id)
+                def_id == tcx.hir().local_def_id(param_id)
             }
             _ => false,
         }
@@ -394,9 +394,9 @@
 }
 
 fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
-    let it = tcx.hir.expect_item(item_id);
+    let it = tcx.hir().expect_item(item_id);
     debug!("convert: item {} with id {}", it.name, it.id);
-    let def_id = tcx.hir.local_def_id(item_id);
+    let def_id = tcx.hir().local_def_id(item_id);
     match it.node {
         // These don't define types.
         hir::ItemKind::ExternCrate(_)
@@ -405,7 +405,7 @@
         | hir::ItemKind::GlobalAsm(_) => {}
         hir::ItemKind::ForeignMod(ref foreign_mod) => {
             for item in &foreign_mod.items {
-                let def_id = tcx.hir.local_def_id(item.id);
+                let def_id = tcx.hir().local_def_id(item.id);
                 tcx.generics_of(def_id);
                 tcx.type_of(def_id);
                 tcx.predicates_of(def_id);
@@ -443,7 +443,7 @@
             tcx.predicates_of(def_id);
 
             for f in struct_def.fields() {
-                let def_id = tcx.hir.local_def_id(f.id);
+                let def_id = tcx.hir().local_def_id(f.id);
                 tcx.generics_of(def_id);
                 tcx.type_of(def_id);
                 tcx.predicates_of(def_id);
@@ -476,8 +476,8 @@
 }
 
 fn convert_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item_id: ast::NodeId) {
-    let trait_item = tcx.hir.expect_trait_item(trait_item_id);
-    let def_id = tcx.hir.local_def_id(trait_item.id);
+    let trait_item = tcx.hir().expect_trait_item(trait_item_id);
+    let def_id = tcx.hir().local_def_id(trait_item.id);
     tcx.generics_of(def_id);
 
     match trait_item.node {
@@ -497,17 +497,17 @@
 }
 
 fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_id: ast::NodeId) {
-    let def_id = tcx.hir.local_def_id(impl_item_id);
+    let def_id = tcx.hir().local_def_id(impl_item_id);
     tcx.generics_of(def_id);
     tcx.type_of(def_id);
     tcx.predicates_of(def_id);
-    if let hir::ImplItemKind::Method(..) = tcx.hir.expect_impl_item(impl_item_id).node {
+    if let hir::ImplItemKind::Method(..) = tcx.hir().expect_impl_item(impl_item_id).node {
         tcx.fn_sig(def_id);
     }
 }
 
 fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ctor_id: ast::NodeId) {
-    let def_id = tcx.hir.local_def_id(ctor_id);
+    let def_id = tcx.hir().local_def_id(ctor_id);
     tcx.generics_of(def_id);
     tcx.type_of(def_id);
     tcx.predicates_of(def_id);
@@ -528,7 +528,7 @@
         let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
         prev_discr = Some(
             if let Some(ref e) = variant.node.disr_expr {
-                let expr_did = tcx.hir.local_def_id(e.id);
+                let expr_did = tcx.hir().local_def_id(e.id);
                 def.eval_explicit_discr(tcx, expr_did)
             } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
                 Some(discr)
@@ -551,7 +551,7 @@
         );
 
         for f in variant.node.data.fields() {
-            let def_id = tcx.hir.local_def_id(f.id);
+            let def_id = tcx.hir().local_def_id(f.id);
             tcx.generics_of(def_id);
             tcx.type_of(def_id);
             tcx.predicates_of(def_id);
@@ -573,12 +573,12 @@
     attribute_def_id: DefId
 ) -> ty::VariantDef {
     let mut seen_fields: FxHashMap<ast::Ident, Span> = Default::default();
-    let node_id = tcx.hir.as_local_node_id(did).unwrap();
+    let node_id = tcx.hir().as_local_node_id(did).unwrap();
     let fields = def
         .fields()
         .iter()
         .map(|f| {
-            let fid = tcx.hir.local_def_id(f.id);
+            let fid = tcx.hir().local_def_id(f.id);
             let dup_span = seen_fields.get(&f.ident.modern()).cloned();
             if let Some(prev_span) = dup_span {
                 struct_span_err!(
@@ -614,8 +614,8 @@
 fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::AdtDef {
     use rustc::hir::*;
 
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let item = match tcx.hir.get(node_id) {
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let item = match tcx.hir().get(node_id) {
         Node::Item(item) => item,
         _ => bug!(),
     };
@@ -629,10 +629,10 @@
                 def.variants
                     .iter()
                     .map(|v| {
-                        let did = tcx.hir.local_def_id(v.node.data.id());
+                        let did = tcx.hir().local_def_id(v.node.data.id());
                         let discr = if let Some(ref e) = v.node.disr_expr {
                             distance_from_explicit = 0;
-                            ty::VariantDiscr::Explicit(tcx.hir.local_def_id(e.id))
+                            ty::VariantDiscr::Explicit(tcx.hir().local_def_id(e.id))
                         } else {
                             ty::VariantDiscr::Relative(distance_from_explicit)
                         };
@@ -647,7 +647,7 @@
         ItemKind::Struct(ref def, _) => {
             // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
             let ctor_id = if !def.is_struct() {
-                Some(tcx.hir.local_def_id(def.id()))
+                Some(tcx.hir().local_def_id(def.id()))
             } else {
                 None
             };
@@ -689,9 +689,9 @@
     trait_def_id: DefId,
 ) -> Lrc<ty::GenericPredicates<'tcx>> {
     debug!("super_predicates(trait_def_id={:?})", trait_def_id);
-    let trait_node_id = tcx.hir.as_local_node_id(trait_def_id).unwrap();
+    let trait_node_id = tcx.hir().as_local_node_id(trait_def_id).unwrap();
 
-    let item = match tcx.hir.get(trait_node_id) {
+    let item = match tcx.hir().get(trait_node_id) {
         Node::Item(item) => item,
         _ => bug!("trait_node_id {} is not an item", trait_node_id),
     };
@@ -704,16 +704,16 @@
 
     let icx = ItemCtxt::new(tcx, trait_def_id);
 
-    // Convert the bounds that follow the colon, e.g. `Bar + Zed` in `trait Foo : Bar + Zed`.
+    // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo : Bar + Zed`.
     let self_param_ty = tcx.mk_self_type();
     let superbounds1 = compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span);
 
     let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
 
     // Convert any explicit superbounds in the where clause,
-    // e.g. `trait Foo where Self : Bar`.
+    // e.g., `trait Foo where Self : Bar`.
     // In the case of trait aliases, however, we include all bounds in the where clause,
-    // so e.g. `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
+    // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
     // as one of its "superpredicates".
     let is_trait_alias = ty::is_trait_alias(tcx, trait_def_id);
     let superbounds2 = icx.type_parameter_bounds_in_generics(
@@ -738,8 +738,8 @@
 }
 
 fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::TraitDef {
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let item = tcx.hir.expect_item(node_id);
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let item = tcx.hir().expect_item(node_id);
 
     let (is_auto, unsafety) = match item.node {
         hir::ItemKind::Trait(is_auto, unsafety, ..) => (is_auto == hir::IsAuto::Yes, unsafety),
@@ -815,7 +815,7 @@
                 return;
             }
 
-            let hir_id = self.tcx.hir.node_to_hir_id(lt.id);
+            let hir_id = self.tcx.hir().node_to_hir_id(lt.id);
             match self.tcx.named_region(hir_id) {
                 Some(rl::Region::Static) | Some(rl::Region::EarlyBound(..)) => {}
                 Some(rl::Region::LateBound(debruijn, _, _))
@@ -842,7 +842,7 @@
         };
         for param in &generics.params {
             if let GenericParamKind::Lifetime { .. } = param.kind {
-                let hir_id = tcx.hir.node_to_hir_id(param.id);
+                let hir_id = tcx.hir().node_to_hir_id(param.id);
                 if tcx.is_late_bound(hir_id) {
                     return Some(param.span);
                 }
@@ -884,14 +884,14 @@
 fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Generics {
     use rustc::hir::*;
 
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
 
-    let node = tcx.hir.get(node_id);
+    let node = tcx.hir().get(node_id);
     let parent_def_id = match node {
         Node::ImplItem(_) | Node::TraitItem(_) | Node::Variant(_)
         | Node::StructCtor(_) | Node::Field(_) => {
-            let parent_id = tcx.hir.get_parent(node_id);
-            Some(tcx.hir.local_def_id(parent_id))
+            let parent_id = tcx.hir().get_parent(node_id);
+            Some(tcx.hir().local_def_id(parent_id))
         }
         Node::Expr(&hir::Expr {
             node: hir::ExprKind::Closure(..),
@@ -938,8 +938,8 @@
 
                     opt_self = Some(ty::GenericParamDef {
                         index: 0,
-                        name: keywords::SelfType.name().as_interned_str(),
-                        def_id: tcx.hir.local_def_id(param_id),
+                        name: keywords::SelfUpper.name().as_interned_str(),
+                        def_id: tcx.hir().local_def_id(param_id),
                         pure_wrt_drop: false,
                         kind: ty::GenericParamDefKind::Type {
                             has_default: false,
@@ -985,13 +985,13 @@
             .map(|(i, param)| ty::GenericParamDef {
                 name: param.name.ident().as_interned_str(),
                 index: own_start + i as u32,
-                def_id: tcx.hir.local_def_id(param.id),
+                def_id: tcx.hir().local_def_id(param.id),
                 pure_wrt_drop: param.pure_wrt_drop,
                 kind: ty::GenericParamDefKind::Lifetime,
             }),
     );
 
-    let hir_id = tcx.hir.node_to_hir_id(node_id);
+    let hir_id = tcx.hir().node_to_hir_id(node_id);
     let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id);
 
     // Now create the real type parameters.
@@ -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"
@@ -1031,7 +1031,7 @@
                     let ty_param = ty::GenericParamDef {
                         index: type_start + i as u32,
                         name: param.name.ident().as_interned_str(),
-                        def_id: tcx.hir.local_def_id(param.id),
+                        def_id: tcx.hir().local_def_id(param.id),
                         pure_wrt_drop: param.pure_wrt_drop,
                         kind: ty::GenericParamDefKind::Type {
                             has_default: default.is_some(),
@@ -1123,11 +1123,11 @@
 fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
     use rustc::hir::*;
 
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
 
     let icx = ItemCtxt::new(tcx, def_id);
 
-    match tcx.hir.get(node_id) {
+    match tcx.hir().get(node_id) {
         Node::TraitItem(item) => match item.node {
             TraitItemKind::Method(..) => {
                 let substs = Substs::identity_for_item(tcx, def_id);
@@ -1147,7 +1147,7 @@
             ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
             ImplItemKind::Existential(_) => {
                 if tcx
-                    .impl_trait_ref(tcx.hir.get_parent_did(node_id))
+                    .impl_trait_ref(tcx.hir().get_parent_did(node_id))
                     .is_none()
                 {
                     report_assoc_ty_on_inherent_impl(tcx, item.span);
@@ -1157,7 +1157,7 @@
             }
             ImplItemKind::Type(ref ty) => {
                 if tcx
-                    .impl_trait_ref(tcx.hir.get_parent_did(node_id))
+                    .impl_trait_ref(tcx.hir().get_parent_did(node_id))
                     .is_none()
                 {
                     report_assoc_ty_on_inherent_impl(tcx, item.span);
@@ -1240,7 +1240,7 @@
             ..
         }) => match *def {
             VariantData::Unit(..) | VariantData::Struct(..) => {
-                tcx.type_of(tcx.hir.get_parent_did(node_id))
+                tcx.type_of(tcx.hir().get_parent_did(node_id))
             }
             VariantData::Tuple(..) => {
                 let substs = Substs::identity_for_item(tcx, def_id);
@@ -1255,7 +1255,7 @@
             ..
         }) => {
             if gen.is_some() {
-                let hir_id = tcx.hir.node_to_hir_id(node_id);
+                let hir_id = tcx.hir().node_to_hir_id(node_id);
                 return tcx.typeck_tables_of(def_id).node_id_to_type(hir_id);
             }
 
@@ -1266,7 +1266,7 @@
             tcx.mk_closure(def_id, substs)
         }
 
-        Node::AnonConst(_) => match tcx.hir.get(tcx.hir.get_parent_node(node_id)) {
+        Node::AnonConst(_) => match tcx.hir().get(tcx.hir().get_parent_node(node_id)) {
             Node::Ty(&hir::Ty {
                 node: hir::TyKind::Array(_, ref constant),
                 ..
@@ -1292,7 +1292,7 @@
                 ..
             }) if e.id == node_id =>
             {
-                tcx.adt_def(tcx.hir.get_parent_did(node_id))
+                tcx.adt_def(tcx.hir().get_parent_did(node_id))
                     .repr
                     .discr_type()
                     .to_ty(tcx)
@@ -1365,10 +1365,10 @@
 
     impl<'a, 'tcx> intravisit::Visitor<'tcx> for ConstraintLocator<'a, 'tcx> {
         fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
-            intravisit::NestedVisitorMap::All(&self.tcx.hir)
+            intravisit::NestedVisitorMap::All(&self.tcx.hir())
         }
         fn visit_item(&mut self, it: &'tcx Item) {
-            let def_id = self.tcx.hir.local_def_id(it.id);
+            let def_id = self.tcx.hir().local_def_id(it.id);
             // the existential type itself or its children are not within its reveal scope
             if def_id != self.def_id {
                 self.check(def_id);
@@ -1376,7 +1376,7 @@
             }
         }
         fn visit_impl_item(&mut self, it: &'tcx ImplItem) {
-            let def_id = self.tcx.hir.local_def_id(it.id);
+            let def_id = self.tcx.hir().local_def_id(it.id);
             // the existential type itself or its children are not within its reveal scope
             if def_id != self.def_id {
                 self.check(def_id);
@@ -1384,7 +1384,7 @@
             }
         }
         fn visit_trait_item(&mut self, it: &'tcx TraitItem) {
-            let def_id = self.tcx.hir.local_def_id(it.id);
+            let def_id = self.tcx.hir().local_def_id(it.id);
             self.check(def_id);
             intravisit::walk_trait_item(self, it);
         }
@@ -1395,16 +1395,16 @@
         tcx,
         found: None,
     };
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let parent = tcx.hir.get_parent(node_id);
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let parent = tcx.hir().get_parent(node_id);
 
     trace!("parent_id: {:?}", parent);
 
     if parent == ast::CRATE_NODE_ID {
-        intravisit::walk_crate(&mut locator, tcx.hir.krate());
+        intravisit::walk_crate(&mut locator, tcx.hir().krate());
     } else {
-        trace!("parent: {:?}", tcx.hir.get(parent));
-        match tcx.hir.get(parent) {
+        trace!("parent: {:?}", tcx.hir().get(parent));
+        match tcx.hir().get(parent) {
             Node::Item(ref it) => intravisit::walk_item(&mut locator, it),
             Node::ImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it),
             Node::TraitItem(ref it) => intravisit::walk_trait_item(&mut locator, it),
@@ -1429,11 +1429,11 @@
     use rustc::hir::*;
     use rustc::hir::Node::*;
 
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
 
     let icx = ItemCtxt::new(tcx, def_id);
 
-    match tcx.hir.get(node_id) {
+    match tcx.hir().get(node_id) {
         TraitItem(hir::TraitItem {
             node: TraitItemKind::Method(sig, _),
             ..
@@ -1452,7 +1452,7 @@
             node: ForeignItemKind::Fn(ref fn_decl, _, _),
             ..
         }) => {
-            let abi = tcx.hir.get_foreign_abi(node_id);
+            let abi = tcx.hir().get_foreign_abi(node_id);
             compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
         }
 
@@ -1465,10 +1465,10 @@
                 },
             ..
         }) => {
-            let ty = tcx.type_of(tcx.hir.get_parent_did(node_id));
+            let ty = tcx.type_of(tcx.hir().get_parent_did(node_id));
             let inputs = fields
                 .iter()
-                .map(|f| tcx.type_of(tcx.hir.local_def_id(f.id)));
+                .map(|f| tcx.type_of(tcx.hir().local_def_id(f.id)));
             ty::Binder::bind(tcx.mk_fn_sig(
                 inputs,
                 ty,
@@ -1512,8 +1512,8 @@
 ) -> Option<ty::TraitRef<'tcx>> {
     let icx = ItemCtxt::new(tcx, def_id);
 
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    match tcx.hir.expect_item(node_id).node {
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    match tcx.hir().expect_item(node_id).node {
         hir::ItemKind::Impl(.., ref opt_trait_ref, _, _) => {
             opt_trait_ref.as_ref().map(|ast_trait_ref| {
                 let selfty = tcx.type_of(def_id);
@@ -1525,8 +1525,8 @@
 }
 
 fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> hir::ImplPolarity {
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    match tcx.hir.expect_item(node_id).node {
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    match tcx.hir().expect_item(node_id).node {
         hir::ItemKind::Impl(_, polarity, ..) => polarity,
         ref item => bug!("impl_polarity: {:?} not an impl", item),
     }
@@ -1597,7 +1597,7 @@
         .iter()
         .filter(move |param| match param.kind {
             GenericParamKind::Lifetime { .. } => {
-                let hir_id = tcx.hir.node_to_hir_id(param.id);
+                let hir_id = tcx.hir().node_to_hir_id(param.id);
                 !tcx.is_late_bound(hir_id)
             }
             _ => false,
@@ -1695,8 +1695,8 @@
         }
     }
 
-    let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
-    let node = tcx.hir.get(node_id);
+    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+    let node = tcx.hir().get(node_id);
 
     let mut is_trait = None;
     let mut is_default_impl_trait = None;
@@ -1715,7 +1715,7 @@
                 let substs = Substs::identity_for_item(tcx, def_id);
                 let opaque_ty = tcx.mk_opaque(def_id, substs);
 
-                // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
+                // Collect the bounds, i.e., the `A+B+'c` in `impl A+B+'c`.
                 let bounds = compute_bounds(
                     &icx,
                     opaque_ty,
@@ -1760,7 +1760,7 @@
                     let substs = Substs::identity_for_item(tcx, def_id);
                     let opaque_ty = tcx.mk_opaque(def_id, substs);
 
-                    // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
+                    // Collect the bounds, i.e., the `A+B+'c` in `impl A+B+'c`.
                     let bounds = compute_bounds(
                         &icx,
                         opaque_ty,
@@ -1825,7 +1825,7 @@
     let mut index = parent_count + has_own_self as u32;
     for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
         let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
-            def_id: tcx.hir.local_def_id(param.id),
+            def_id: tcx.hir().local_def_id(param.id),
             index,
             name: param.name.ident().as_interned_str(),
         }));
@@ -1938,14 +1938,14 @@
     // Add predicates from associated type bounds.
     if let Some((self_trait_ref, trait_items)) = is_trait {
         predicates.extend(trait_items.iter().flat_map(|trait_item_ref| {
-            let trait_item = tcx.hir.trait_item(trait_item_ref.id);
+            let trait_item = tcx.hir().trait_item(trait_item_ref.id);
             let bounds = match trait_item.node {
                 hir::TraitItemKind::Type(ref bounds, _) => bounds,
                 _ => return vec![].into_iter()
             };
 
             let assoc_ty =
-                tcx.mk_projection(tcx.hir.local_def_id(trait_item.id), self_trait_ref.substs);
+                tcx.mk_projection(tcx.hir().local_def_id(trait_item.id), self_trait_ref.substs);
 
             let bounds = compute_bounds(
                 &ItemCtxt::new(tcx, def_id),
@@ -2108,7 +2108,7 @@
                        &format!(
                            "use of SIMD type `{}` in FFI is highly experimental and \
                             may result in invalid code",
-                           tcx.hir.node_to_pretty_string(ast_ty.id)
+                           tcx.hir().node_to_pretty_string(ast_ty.id)
                        ),
                    )
                    .help("add #![feature(simd_ffi)] to the crate attributes to enable")
@@ -2127,7 +2127,7 @@
 }
 
 fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
-    match tcx.hir.get_if_local(def_id) {
+    match tcx.hir().get_if_local(def_id) {
         Some(Node::ForeignItem(..)) => true,
         Some(_) => false,
         _ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id),
@@ -2249,7 +2249,7 @@
         "weak" => WeakAny,
         "weak_odr" => WeakODR,
         _ => {
-            let span = tcx.hir.span_if_local(def_id);
+            let span = tcx.hir().span_if_local(def_id);
             if let Some(span) = span {
                 tcx.sess.span_fatal(span, "invalid linkage specified")
             } else {
diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs
index 9299e9b..25fa33e 100644
--- a/src/librustc_typeck/constrained_type_params.rs
+++ b/src/librustc_typeck/constrained_type_params.rs
@@ -37,7 +37,7 @@
 }
 
 /// If `include_projections` is false, returns the list of parameters that are
-/// constrained by `t` - i.e. the value of each parameter in the list is
+/// constrained by `t` - i.e., the value of each parameter in the list is
 /// uniquely determined by `t` (see RFC 447). If it is true, return the list
 /// of parameters whose values are needed in order to constrain `ty` - these
 /// differ, with the latter being a superset, in the presence of projections.
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 084951f..a0dbaf5 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -655,7 +655,7 @@
 fn f(a: u16, b: &str) {}
 ```
 
-Must always be called with exactly two arguments, e.g. `f(2, "test")`.
+Must always be called with exactly two arguments, e.g., `f(2, "test")`.
 
 Note that Rust does not have a notion of optional function arguments or
 variadic functions (except for its C-FFI).
@@ -1610,7 +1610,7 @@
 
 E0185: r##"
 An associated function for a trait was defined to be static, but an
-implementation of the trait declared the same function to be a method (i.e. to
+implementation of the trait declared the same function to be a method (i.e., to
 take a `self` parameter).
 
 Here's an example of this error:
@@ -1631,7 +1631,7 @@
 "##,
 
 E0186: r##"
-An associated function for a trait was defined to be a method (i.e. to take a
+An associated function for a trait was defined to be a method (i.e., to take a
 `self` parameter), but an implementation of the trait declared the same function
 to be static.
 
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index 74a53f7..a2071fd 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -62,7 +62,7 @@
     // We will tag this as part of the WF check -- logically, it is,
     // but it's one that we must perform earlier than the rest of
     // WfCheck.
-    tcx.hir.krate().visit_all_item_likes(&mut ImplWfCheck { tcx });
+    tcx.hir().krate().visit_all_item_likes(&mut ImplWfCheck { tcx });
 }
 
 struct ImplWfCheck<'a, 'tcx: 'a> {
@@ -72,7 +72,7 @@
 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         if let hir::ItemKind::Impl(.., ref impl_item_refs) = item.node {
-            let impl_def_id = self.tcx.hir.local_def_id(item.id);
+            let impl_def_id = self.tcx.hir().local_def_id(item.id);
             enforce_impl_params_are_constrained(self.tcx,
                                                 impl_def_id,
                                                 impl_item_refs);
@@ -101,7 +101,7 @@
 
     // Disallow unconstrained lifetimes, but only if they appear in assoc types.
     let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter()
-        .map(|item_ref| tcx.hir.local_def_id(item_ref.id.node_id))
+        .map(|item_ref| tcx.hir().local_def_id(item_ref.id.node_id))
         .filter(|&def_id| {
             let item = tcx.associated_item(def_id);
             item.kind == ty::AssociatedKind::Type && item.defaultness.has_value()
@@ -176,7 +176,7 @@
     let mut seen_type_items = FxHashMap::default();
     let mut seen_value_items = FxHashMap::default();
     for impl_item_ref in impl_item_refs {
-        let impl_item = tcx.hir.impl_item(impl_item_ref.id);
+        let impl_item = tcx.hir().impl_item(impl_item_ref.id);
         let seen_items = match impl_item.node {
             hir::ImplItemKind::Type(_) => &mut seen_type_items,
             _                          => &mut seen_value_items,
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 0fba311..8d6fb8b 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -10,24 +10,24 @@
 
 /*!
 
-typeck.rs, an introduction
+# typeck.rs
 
 The type checker is responsible for:
 
-1. Determining the type of each expression
-2. Resolving methods and traits
-3. Guaranteeing that most type rules are met ("most?", you say, "why most?"
+1. Determining the type of each expression.
+2. Resolving methods and traits.
+3. Guaranteeing that most type rules are met. ("Most?", you say, "why most?"
    Well, dear reader, read on)
 
-The main entry point is `check_crate()`.  Type checking operates in
+The main entry point is `check_crate()`. Type checking operates in
 several major phases:
 
 1. The collect phase first passes over all items and determines their
    type, without examining their "innards".
 
-2. Variance inference then runs to compute the variance of each parameter
+2. Variance inference then runs to compute the variance of each parameter.
 
-3. Coherence checks for overlapping or orphaned impls
+3. Coherence checks for overlapping or orphaned impls.
 
 4. Finally, the check phase then checks function bodies and so forth.
    Within the check phase, we check each function body one at a time
@@ -41,12 +41,12 @@
 independently:
 
 - astconv: converts the AST representation of types
-  into the `ty` representation
+  into the `ty` representation.
 
 - collect: computes the types of each top-level item and enters them into
-  the `tcx.types` table for later use
+  the `tcx.types` table for later use.
 
-- coherence: enforces coherence rules, builds some tables
+- coherence: enforces coherence rules, builds some tables.
 
 - variance: variance inference
 
@@ -59,7 +59,7 @@
   all subtyping and assignment constraints are met.  In essence, the check
   module specifies the constraints, and the infer module solves them.
 
-# Note
+## Note
 
 This API is completely unstable and subject to change.
 
@@ -97,29 +97,7 @@
 extern crate rustc_target;
 extern crate smallvec;
 
-use rustc::hir;
-use rustc::lint;
-use rustc::middle;
-use rustc::session;
-use rustc::util;
-
-use hir::Node;
-use rustc::infer::InferOk;
-use rustc::ty::subst::Substs;
-use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::query::Providers;
-use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt};
-use rustc::util::profiling::ProfileCategory;
-use session::{CompileIncomplete, config};
-use util::common::time;
-
-use syntax::ast;
-use rustc_target::spec::abi::Abi;
-use syntax_pos::Span;
-
-use std::iter;
-
-// NB: This module needs to be declared first so diagnostics are
+// N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
 mod diagnostics;
 
@@ -135,6 +113,26 @@
 mod outlives;
 mod variance;
 
+use hir::Node;
+use rustc_target::spec::abi::Abi;
+use rustc::hir;
+use rustc::infer::InferOk;
+use rustc::lint;
+use rustc::middle;
+use rustc::session;
+use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt};
+use rustc::ty::subst::Substs;
+use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::query::Providers;
+use rustc::util;
+use rustc::util::profiling::ProfileCategory;
+use session::{CompileIncomplete, config};
+use syntax_pos::Span;
+use syntax::ast;
+use util::common::time;
+
+use std::iter;
+
 pub struct TypeAndSubsts<'tcx> {
     substs: &'tcx Substs<'tcx>,
     ty: Ty<'tcx>,
@@ -182,11 +180,11 @@
 fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               main_id: ast::NodeId,
                               main_span: Span) {
-    let main_def_id = tcx.hir.local_def_id(main_id);
+    let main_def_id = tcx.hir().local_def_id(main_id);
     let main_t = tcx.type_of(main_def_id);
     match main_t.sty {
         ty::FnDef(..) => {
-            if let Some(Node::Item(it)) = tcx.hir.find(main_id) {
+            if let Some(Node::Item(it)) = tcx.hir().find(main_id) {
                 if let hir::ItemKind::Fn(.., ref generics, _) = it.node {
                     let mut error = false;
                     if !generics.params.is_empty() {
@@ -248,11 +246,11 @@
 fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                start_id: ast::NodeId,
                                start_span: Span) {
-    let start_def_id = tcx.hir.local_def_id(start_id);
+    let start_def_id = tcx.hir().local_def_id(start_id);
     let start_t = tcx.type_of(start_def_id);
     match start_t.sty {
         ty::FnDef(..) => {
-            if let Some(Node::Item(it)) = tcx.hir.find(start_id) {
+            if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
                 if let hir::ItemKind::Fn(.., ref generics, _) = it.node {
                     let mut error = false;
                     if !generics.params.is_empty() {
@@ -373,8 +371,8 @@
     // In case there are any projections etc, find the "environment"
     // def-id that will be used to determine the traits/predicates in
     // scope.  This is derived from the enclosing item-like thing.
-    let env_node_id = tcx.hir.get_parent(hir_ty.id);
-    let env_def_id = tcx.hir.local_def_id(env_node_id);
+    let env_node_id = tcx.hir().get_parent(hir_ty.id);
+    let env_def_id = tcx.hir().local_def_id(env_node_id);
     let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id);
 
     astconv::AstConv::ast_ty_to_ty(&item_cx, hir_ty)
@@ -385,8 +383,8 @@
     // In case there are any projections etc, find the "environment"
     // def-id that will be used to determine the traits/predicates in
     // scope.  This is derived from the enclosing item-like thing.
-    let env_node_id = tcx.hir.get_parent(hir_trait.ref_id);
-    let env_def_id = tcx.hir.local_def_id(env_node_id);
+    let env_node_id = tcx.hir().get_parent(hir_trait.ref_id);
+    let env_def_id = tcx.hir().local_def_id(env_node_id);
     let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id);
     let mut projections = Vec::new();
     let (principal, _) = astconv::AstConv::instantiate_poly_trait_ref_inner(
diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs
index 30e3043..315e5fe 100644
--- a/src/librustc_typeck/outlives/implicit_infer.rs
+++ b/src/librustc_typeck/outlives/implicit_infer.rs
@@ -48,7 +48,7 @@
         };
 
         // Visit all the crates and infer predicates
-        tcx.hir.krate().visit_all_item_likes(&mut visitor);
+        tcx.hir().krate().visit_all_item_likes(&mut visitor);
     }
 
     global_inferred_outlives
@@ -63,16 +63,16 @@
 
 impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
-        let item_did = self.tcx.hir.local_def_id(item.id);
+        let item_did = self.tcx.hir().local_def_id(item.id);
 
         debug!("InferVisitor::visit_item(item={:?})", item_did);
 
         let node_id = self
             .tcx
-            .hir
+            .hir()
             .as_local_node_id(item_did)
             .expect("expected local def-id");
-        let item = match self.tcx.hir.get(node_id) {
+        let item = match self.tcx.hir().get(node_id) {
             Node::Item(item) => item,
             _ => bug!(),
         };
@@ -314,7 +314,7 @@
         // case that `substs` come from a `dyn Trait` type, our caller will have
         // included `Self = usize` as the value for `Self`. If we were
         // to apply the substs, and not filter this predicate, we might then falsely
-        // conclude that e.g. `X: 'x` was a reasonable inferred requirement.
+        // conclude that e.g., `X: 'x` was a reasonable inferred requirement.
         //
         // Another similar case is where we have a inferred
         // requirement like `<Self as Trait>::Foo: 'b`. We presently
diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs
index 1eb53ff..5796df2 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/src/librustc_typeck/outlives/mod.rs
@@ -35,11 +35,11 @@
     item_def_id: DefId,
 ) -> Lrc<Vec<ty::Predicate<'tcx>>> {
     let id = tcx
-        .hir
+        .hir()
         .as_local_node_id(item_def_id)
         .expect("expected local def-id");
 
-    match tcx.hir.get(id) {
+    match tcx.hir().get(id) {
         Node::Item(item) => match item.node {
             hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) => {
                 let crate_map = tcx.inferred_outlives_crate(LOCAL_CRATE);
diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs
index 48c495e..d855675 100644
--- a/src/librustc_typeck/outlives/test.rs
+++ b/src/librustc_typeck/outlives/test.rs
@@ -13,7 +13,7 @@
 use rustc::ty::TyCtxt;
 
 pub fn test_inferred_outlives<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    tcx.hir
+    tcx.hir()
        .krate()
        .visit_all_item_likes(&mut OutlivesTest { tcx });
 }
@@ -24,7 +24,7 @@
 
 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for OutlivesTest<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let item_def_id = self.tcx.hir.local_def_id(item.id);
+        let item_def_id = self.tcx.hir().local_def_id(item.id);
 
         // For unit testing: check for a special "rustc_outlives"
         // attribute and report an error with various results if found.
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index ed32e5a..6ea9194 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -44,7 +44,7 @@
 }
 
 /// To build constraints, we visit one item (type, trait) at a time
-/// and look at its contents. So e.g. if we have
+/// and look at its contents. So e.g., if we have
 ///
 ///     struct Foo<T> {
 ///         b: Bar<T>
@@ -72,7 +72,7 @@
         constraints: Vec::new(),
     };
 
-    tcx.hir.krate().visit_all_item_likes(&mut constraint_cx);
+    tcx.hir().krate().visit_all_item_likes(&mut constraint_cx);
 
     constraint_cx
 }
@@ -131,7 +131,7 @@
 impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
     fn visit_node_helper(&mut self, id: ast::NodeId) {
         let tcx = self.terms_cx.tcx;
-        let def_id = tcx.hir.local_def_id(id);
+        let def_id = tcx.hir().local_def_id(id);
         self.build_constraints_for_item(def_id);
     }
 
@@ -148,7 +148,7 @@
             return;
         }
 
-        let id = tcx.hir.as_local_node_id(def_id).unwrap();
+        let id = tcx.hir().as_local_node_id(def_id).unwrap();
         let inferred_start = self.terms_cx.inferred_starts[&id];
         let current_item = &CurrentItem { inferred_start };
         match tcx.type_of(def_id).sty {
@@ -365,7 +365,7 @@
             return;
         }
 
-        let (local, remote) = if let Some(id) = self.tcx().hir.as_local_node_id(def_id) {
+        let (local, remote) = if let Some(id) = self.tcx().hir().as_local_node_id(def_id) {
             (Some(self.terms_cx.inferred_starts[&id]), None)
         } else {
             (None, Some(self.tcx().variances_of(def_id)))
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index e3c82d5..4039281 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -56,12 +56,12 @@
 
 fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
                           -> Lrc<Vec<ty::Variance>> {
-    let id = tcx.hir.as_local_node_id(item_def_id).expect("expected local def-id");
+    let id = tcx.hir().as_local_node_id(item_def_id).expect("expected local def-id");
     let unsupported = || {
         // Variance not relevant.
-        span_bug!(tcx.hir.span(id), "asked to compute variance for wrong kind of item")
+        span_bug!(tcx.hir().span(id), "asked to compute variance for wrong kind of item")
     };
-    match tcx.hir.get(id) {
+    match tcx.hir().get(id) {
         Node::Item(item) => match item.node {
             hir::ItemKind::Enum(..) |
             hir::ItemKind::Struct(..) |
diff --git a/src/librustc_typeck/variance/solve.rs b/src/librustc_typeck/variance/solve.rs
index 7116a42..365c65b 100644
--- a/src/librustc_typeck/variance/solve.rs
+++ b/src/librustc_typeck/variance/solve.rs
@@ -93,7 +93,7 @@
 
         let solutions = &self.solutions;
         self.terms_cx.inferred_starts.iter().map(|(&id, &InferredIndex(start))| {
-            let def_id = tcx.hir.local_def_id(id);
+            let def_id = tcx.hir().local_def_id(id);
             let generics = tcx.generics_of(def_id);
 
             let mut variances = solutions[start..start+generics.count()].to_vec();
diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs
index 3692221..75ff5bb 100644
--- a/src/librustc_typeck/variance/terms.rs
+++ b/src/librustc_typeck/variance/terms.rs
@@ -91,7 +91,7 @@
     //
     // - 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);
+    tcx.hir().krate().visit_all_item_likes(&mut terms_cx);
 
     terms_cx
 }
@@ -106,14 +106,14 @@
     all.into_iter() // iterating over (Option<DefId>, Variance)
        .filter(|&(ref d,_)| d.is_some())
        .map(|(d, v)| (d.unwrap(), v)) // (DefId, Variance)
-       .filter_map(|(d, v)| tcx.hir.as_local_node_id(d).map(|n| (n, v))) // (NodeId, Variance)
+       .filter_map(|(d, v)| tcx.hir().as_local_node_id(d).map(|n| (n, v))) // (NodeId, Variance)
        .collect()
 }
 
 impl<'a, 'tcx> TermsContext<'a, 'tcx> {
     fn add_inferreds_for_item(&mut self, id: ast::NodeId) {
         let tcx = self.tcx;
-        let def_id = tcx.hir.local_def_id(id);
+        let def_id = tcx.hir().local_def_id(id);
         let count = tcx.generics_of(def_id).count();
 
         if count == 0 {
@@ -125,7 +125,7 @@
         let newly_added = self.inferred_starts.insert(id, InferredIndex(start)).is_none();
         assert!(newly_added);
 
-        // NB: In the code below for writing the results back into the
+        // N.B., in the code below for writing the results back into the
         // `CrateVariancesMap`, we rely on the fact that all inferreds
         // for a particular item are assigned continuous indices.
 
@@ -139,7 +139,7 @@
 impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for TermsContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
         debug!("add_inferreds for item {}",
-               self.tcx.hir.node_to_string(item.id));
+               self.tcx.hir().node_to_string(item.id));
 
         match item.node {
             hir::ItemKind::Struct(ref struct_def, _) |
diff --git a/src/librustc_typeck/variance/test.rs b/src/librustc_typeck/variance/test.rs
index 1acadb7..7ae90e9 100644
--- a/src/librustc_typeck/variance/test.rs
+++ b/src/librustc_typeck/variance/test.rs
@@ -13,7 +13,7 @@
 use rustc::ty::TyCtxt;
 
 pub fn test_variance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    tcx.hir.krate().visit_all_item_likes(&mut VarianceTest { tcx });
+    tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx });
 }
 
 struct VarianceTest<'a, 'tcx: 'a> {
@@ -22,7 +22,7 @@
 
 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let item_def_id = self.tcx.hir.local_def_id(item.id);
+        let item_def_id = self.tcx.hir().local_def_id(item.id);
 
         // For unit testing: check for a special "rustc_variance"
         // attribute and report an error with various results if found.
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index fde8648..ac9680b 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -37,7 +37,7 @@
 
     pub fn get_with_node_id(&self, id: ast::NodeId, name: String) -> Vec<Item> {
         get_def_from_node_id(&self.cx, id, name, &|def_ctor, name| {
-            let did = self.cx.tcx.hir.local_def_id(id);
+            let did = self.cx.tcx.hir().local_def_id(id);
             self.get_auto_trait_impls(did, &def_ctor, Some(name))
         })
     }
@@ -255,7 +255,7 @@
     // handle_lifetimes determines what *needs be* true in order for an impl to hold.
     // lexical_region_resolve, along with much of the rest of the compiler, is concerned
     // with determining if a given set up constraints/predicates *are* met, given some
-    // starting conditions (e.g. user-provided code). For this reason, it's easier
+    // starting conditions (e.g., user-provided code). For this reason, it's easier
     // to perform the calculations we need on our own, rather than trying to make
     // existing inference/solver code do what we want.
     fn handle_lifetimes<'cx>(
@@ -274,7 +274,7 @@
         // Flattening is done in two parts. First, we insert all of the constraints
         // into a map. Each RegionTarget (either a RegionVid or a Region) maps
         // to its smaller and larger regions. Note that 'larger' regions correspond
-        // to sub-regions in Rust code (e.g. in 'a: 'b, 'a is the larger region).
+        // to sub-regions in Rust code (e.g., in 'a: 'b, 'a is the larger region).
         for constraint in regions.constraints.keys() {
             match constraint {
                 &Constraint::VarSubVar(r1, r2) => {
@@ -524,7 +524,7 @@
     // display on the docs page. Cleaning the Predicates produces sub-optimal WherePredicate's,
     // so we fix them up:
     //
-    // * Multiple bounds for the same type are coalesced into one: e.g. 'T: Copy', 'T: Debug'
+    // * Multiple bounds for the same type are coalesced into one: e.g., 'T: Copy', 'T: Debug'
     // becomes 'T: Copy + Debug'
     // * Fn bounds are handled specially - instead of leaving it as 'T: Fn(), <T as Fn::Output> =
     // K', we use the dedicated syntax 'T: Fn() -> K'
@@ -545,7 +545,7 @@
         );
 
         // The `Sized` trait must be handled specially, since we only only display it when
-        // it is *not* required (i.e. '?Sized')
+        // it is *not* required (i.e., '?Sized')
         let sized_trait = self.cx
             .tcx
             .require_lang_item(lang_items::SizedTraitLangItem);
@@ -629,7 +629,7 @@
                         let is_fn = match &mut b {
                             &mut GenericBound::TraitBound(ref mut p, _) => {
                                 // Insert regions into the for_generics hash map first, to ensure
-                                // that we don't end up with duplicate bounds (e.g. for<'b, 'b>)
+                                // that we don't end up with duplicate bounds (e.g., for<'b, 'b>)
                                 for_generics.extend(p.generic_params.clone());
                                 p.generic_params = for_generics.into_iter().collect();
                                 self.is_fn_ty(&tcx, &p.trait_)
@@ -737,7 +737,7 @@
                                         hir::TraitBoundModifier::None,
                                     ));
 
-                                    // Remove any existing 'plain' bound (e.g. 'T: Iterator`) so
+                                    // Remove any existing 'plain' bound (e.g., 'T: Iterator`) so
                                     // that we don't see a
                                     // duplicate bound like `T: Iterator + Iterator<Item=u8>`
                                     // on the docs page.
@@ -837,7 +837,7 @@
     // auto-trait impls always render in exactly the same way.
     //
     // Using the Debug implementation for sorting prevents us from needing to
-    // write quite a bit of almost entirely useless code (e.g. how should two
+    // write quite a bit of almost entirely useless code (e.g., how should two
     // Types be sorted relative to each other). It also allows us to solve the
     // problem for both WherePredicates and GenericBounds at the same time. This
     // approach is probably somewhat slower, but the small number of items
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 8246c7b..ed0056e 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -38,7 +38,7 @@
 
     pub fn get_with_node_id(&self, id: ast::NodeId, name: String) -> Vec<Item> {
         get_def_from_node_id(&self.cx, id, name, &|def_ctor, name| {
-            let did = self.cx.tcx.hir.local_def_id(id);
+            let did = self.cx.tcx.hir().local_def_id(id);
             self.get_blanket_impls(did, &def_ctor, Some(name))
         })
     }
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index f90f1e5..847786d 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -31,13 +31,13 @@
     True,
     /// Denies all configurations.
     False,
-    /// A generic configuration option, e.g. `test` or `target_os = "linux"`.
+    /// A generic configuration option, e.g., `test` or `target_os = "linux"`.
     Cfg(Symbol, Option<Symbol>),
-    /// Negate a configuration requirement, i.e. `not(x)`.
+    /// Negate a configuration requirement, i.e., `not(x)`.
     Not(Box<Cfg>),
-    /// Union of a list of configuration requirements, i.e. `any(...)`.
+    /// Union of a list of configuration requirements, i.e., `any(...)`.
     Any(Vec<Cfg>),
-    /// Intersection of a list of configuration requirements, i.e. `all(...)`.
+    /// Intersection of a list of configuration requirements, i.e., `all(...)`.
     All(Vec<Cfg>),
 }
 
@@ -61,7 +61,7 @@
 
     /// Parses a `MetaItem` into a `Cfg`.
     ///
-    /// The `MetaItem` should be the content of the `#[cfg(...)]`, e.g. `unix` or
+    /// The `MetaItem` should be the content of the `#[cfg(...)]`, e.g., `unix` or
     /// `target_os = "redox"`.
     ///
     /// If the content is not properly formatted, it will return an error indicating what and where
diff --git a/src/librustdoc/clean/def_ctor.rs b/src/librustdoc/clean/def_ctor.rs
index cd9f4eb..b14c36a 100644
--- a/src/librustdoc/clean/def_ctor.rs
+++ b/src/librustdoc/clean/def_ctor.rs
@@ -54,7 +54,7 @@
                                callback: &F,
 ) -> Vec<Item>
 where F: Fn(& dyn Fn(DefId) -> Def, String) -> Vec<Item> {
-    let item = &cx.tcx.hir.expect_item(id).node;
+    let item = &cx.tcx.hir().expect_item(id).node;
 
     callback(&match *item {
         hir::ItemKind::Struct(_, _) => Def::Struct,
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 49cecd5..2173455 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -303,8 +303,8 @@
         }
     }
 
-    let for_ = if let Some(nodeid) = tcx.hir.as_local_node_id(did) {
-        match tcx.hir.expect_item(nodeid).node {
+    let for_ = if let Some(nodeid) = tcx.hir().as_local_node_id(did) {
+        match tcx.hir().expect_item(nodeid).node {
             hir::ItemKind::Impl(.., ref t, _) => {
                 t.clean(cx)
             }
@@ -325,12 +325,12 @@
     }
 
     let predicates = tcx.predicates_of(did);
-    let (trait_items, generics) = if let Some(nodeid) = tcx.hir.as_local_node_id(did) {
-        match tcx.hir.expect_item(nodeid).node {
+    let (trait_items, generics) = if let Some(nodeid) = tcx.hir().as_local_node_id(did) {
+        match tcx.hir().expect_item(nodeid).node {
             hir::ItemKind::Impl(.., ref gen, _, _, ref item_ids) => {
                 (
                     item_ids.iter()
-                            .map(|ii| tcx.hir.impl_item(ii.id).clean(cx))
+                            .map(|ii| tcx.hir().impl_item(ii.id).clean(cx))
                             .collect::<Vec<_>>(),
                     gen.clean(cx),
                 )
@@ -420,8 +420,8 @@
 }
 
 pub fn print_inlined_const(cx: &DocContext, did: DefId) -> String {
-    if let Some(node_id) = cx.tcx.hir.as_local_node_id(did) {
-        cx.tcx.hir.node_to_pretty_string(node_id)
+    if let Some(node_id) = cx.tcx.hir().as_local_node_id(did) {
+        cx.tcx.hir().node_to_pretty_string(node_id)
     } else {
         cx.tcx.rendered_const(did)
     }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 5276683..1e33ec8 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -11,14 +11,31 @@
 //! This module contains the "cleaned" pieces of the AST, and the functions
 //! that clean them.
 
-pub use self::Type::*;
-pub use self::Mutability::*;
-pub use self::ItemEnum::*;
-pub use self::SelfTy::*;
-pub use self::FunctionRetTy::*;
-pub use self::Visibility::{Public, Inherited};
+pub mod inline;
+pub mod cfg;
+mod simplify;
+mod auto_trait;
+mod blanket_impl;
+pub mod def_ctor;
 
+use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::sync::Lrc;
 use rustc_target::spec::abi::Abi;
+use rustc_typeck::hir_ty_to_ty;
+use rustc::infer::region_constraints::{RegionConstraintData, Constraint};
+use rustc::mir::interpret::ConstValue;
+use rustc::middle::resolve_lifetime as rl;
+use rustc::middle::lang_items;
+use rustc::middle::stability;
+use rustc::mir::interpret::GlobalId;
+use rustc::hir::{self, GenericArg, HirVec};
+use rustc::hir::def::{self, Def, CtorKind};
+use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc::ty::subst::Substs;
+use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
+use rustc::ty::fold::TypeFolder;
+use rustc::ty::layout::VariantIdx;
+use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use syntax::ast::{self, AttrStyle, Ident};
 use syntax::attr;
 use syntax::ext::base::MacroKind;
@@ -28,30 +45,12 @@
 use syntax::symbol::InternedString;
 use syntax_pos::{self, DUMMY_SP, Pos, FileName};
 
-use rustc::mir::interpret::ConstValue;
-use rustc::middle::resolve_lifetime as rl;
-use rustc::ty::fold::TypeFolder;
-use rustc::middle::lang_items;
-use rustc::mir::interpret::GlobalId;
-use rustc::hir::{self, GenericArg, HirVec};
-use rustc::hir::def::{self, Def, CtorKind};
-use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
-use rustc::ty::subst::Substs;
-use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
-use rustc::ty::layout::VariantIdx;
-use rustc::middle::stability;
-use rustc::util::nodemap::{FxHashMap, FxHashSet};
-use rustc_typeck::hir_ty_to_ty;
-use rustc::infer::region_constraints::{RegionConstraintData, Constraint};
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
-
 use std::collections::hash_map::Entry;
 use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::default::Default;
 use std::{mem, slice, vec};
 use std::iter::{FromIterator, once};
-use rustc_data_structures::sync::Lrc;
 use std::rc::Rc;
 use std::str::FromStr;
 use std::cell::RefCell;
@@ -66,17 +65,17 @@
 use html::render::{cache, ExternalLocation};
 use html::item_type::ItemType;
 
-pub mod inline;
-pub mod cfg;
-mod simplify;
-mod auto_trait;
-mod blanket_impl;
-pub mod def_ctor;
-
 use self::cfg::Cfg;
 use self::auto_trait::AutoTraitFinder;
 use self::blanket_impl::BlanketImplFinder;
 
+pub use self::Type::*;
+pub use self::Mutability::*;
+pub use self::ItemEnum::*;
+pub use self::SelfTy::*;
+pub use self::FunctionRetTy::*;
+pub use self::Visibility::{Public, Inherited};
+
 thread_local!(pub static MAX_DEF_ID: RefCell<FxHashMap<CrateNum, DefId>> = Default::default());
 
 const FN_OUTPUT_NAME: &'static str = "Output";
@@ -282,17 +281,17 @@
             None
         };
         let primitives = if root.is_local() {
-            cx.tcx.hir.krate().module.item_ids.iter().filter_map(|&id| {
-                let item = cx.tcx.hir.expect_item(id.id);
+            cx.tcx.hir().krate().module.item_ids.iter().filter_map(|&id| {
+                let item = cx.tcx.hir().expect_item(id.id);
                 match item.node {
                     hir::ItemKind::Mod(_) => {
-                        as_primitive(Def::Mod(cx.tcx.hir.local_def_id(id.id)))
+                        as_primitive(Def::Mod(cx.tcx.hir().local_def_id(id.id)))
                     }
                     hir::ItemKind::Use(ref path, hir::UseKind::Single)
                     if item.vis.node.is_pub() => {
                         as_primitive(path.def).map(|(_, prim, attrs)| {
                             // Pretend the primitive is local.
-                            (cx.tcx.hir.local_def_id(id.id), prim, attrs)
+                            (cx.tcx.hir().local_def_id(id.id), prim, attrs)
                         })
                     }
                     _ => None
@@ -324,16 +323,16 @@
             None
         };
         let keywords = if root.is_local() {
-            cx.tcx.hir.krate().module.item_ids.iter().filter_map(|&id| {
-                let item = cx.tcx.hir.expect_item(id.id);
+            cx.tcx.hir().krate().module.item_ids.iter().filter_map(|&id| {
+                let item = cx.tcx.hir().expect_item(id.id);
                 match item.node {
                     hir::ItemKind::Mod(_) => {
-                        as_keyword(Def::Mod(cx.tcx.hir.local_def_id(id.id)))
+                        as_keyword(Def::Mod(cx.tcx.hir().local_def_id(id.id)))
                     }
                     hir::ItemKind::Use(ref path, hir::UseKind::Single)
                     if item.vis.node.is_pub() => {
                         as_keyword(path.def).map(|(_, prim, attrs)| {
-                            (cx.tcx.hir.local_def_id(id.id), prim, attrs)
+                            (cx.tcx.hir().local_def_id(id.id), prim, attrs)
                         })
                     }
                     _ => None
@@ -629,7 +628,7 @@
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             inner: ModuleItem(Module {
                is_crate: self.is_crate,
                items,
@@ -708,8 +707,6 @@
 /// kept separate because of issue #42760.
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
 pub enum DocFragment {
-    // FIXME #44229 (misdreavus): sugared and raw doc comments can be brought back together once
-    // hoedown is completely removed from rustdoc.
     /// A doc fragment created from a `///` or `//!` doc comment.
     SugaredDoc(usize, syntax_pos::Span, String),
     /// A doc fragment created from a "raw" `#[doc=""]` attribute.
@@ -1215,7 +1212,7 @@
 impl Clean<Lifetime> for hir::Lifetime {
     fn clean(&self, cx: &DocContext) -> Lifetime {
         if self.id != ast::DUMMY_NODE_ID {
-            let hir_id = cx.tcx.hir.node_to_hir_id(self.id);
+            let hir_id = cx.tcx.hir().node_to_hir_id(self.id);
             let def = cx.tcx.named_region(hir_id);
             match def {
                 Some(rl::Region::EarlyBound(_, node_id, _)) |
@@ -1473,7 +1470,7 @@
             }
             hir::GenericParamKind::Type { ref default, synthetic, .. } => {
                 (self.name.ident().name.clean(cx), GenericParamDefKind::Type {
-                    did: cx.tcx.hir.local_def_id(self.id),
+                    did: cx.tcx.hir().local_def_id(self.id),
                     bounds: self.bounds.clean(cx),
                     default: default.clean(cx),
                     synthetic: synthetic,
@@ -1575,7 +1572,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;
                 }
@@ -1621,7 +1618,7 @@
         }
 
         // It would be nice to collect all of the bounds on a type and recombine
-        // them if possible, to avoid e.g. `where T: Foo, T: Bar, T: Sized, T: 'a`
+        // them if possible, to avoid e.g., `where T: Foo, T: Bar, T: Sized, T: 'a`
         // and instead see `where T: Foo + Bar + Sized + 'a`
 
         Generics {
@@ -1684,7 +1681,7 @@
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             inner: FunctionItem(Function {
                 decl,
                 generics,
@@ -1733,7 +1730,7 @@
 
 impl<'a> Clean<Arguments> for (&'a [hir::Ty], hir::BodyId) {
     fn clean(&self, cx: &DocContext) -> Arguments {
-        let body = cx.tcx.hir.body(self.1);
+        let body = cx.tcx.hir().body(self.1);
 
         Arguments {
             values: self.0.iter().enumerate().map(|(i, ty)| {
@@ -1762,7 +1759,7 @@
 impl<'a, 'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
     fn clean(&self, cx: &DocContext) -> FnDecl {
         let (did, sig) = *self;
-        let mut names = if cx.tcx.hir.as_local_node_id(did).is_some() {
+        let mut names = if cx.tcx.hir().as_local_node_id(did).is_some() {
             vec![].into_iter()
         } else {
             cx.tcx.fn_arg_names(did).into_iter()
@@ -1857,7 +1854,7 @@
             name: Some(self.name.clean(cx)),
             attrs: attrs,
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -1926,10 +1923,10 @@
             name: Some(self.ident.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.span.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: None,
-            stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
-            deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
+            stability: get_stability(cx, cx.tcx.hir().local_def_id(self.id)),
+            deprecation: get_deprecation(cx, cx.tcx.hir().local_def_id(self.id)),
             inner,
         }
     }
@@ -1958,10 +1955,10 @@
             name: Some(self.ident.name.clean(cx)),
             source: self.span.clean(cx),
             attrs: self.attrs.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
-            stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
-            deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
+            stability: get_stability(cx, cx.tcx.hir().local_def_id(self.id)),
+            deprecation: get_deprecation(cx, cx.tcx.hir().local_def_id(self.id)),
             inner,
         }
     }
@@ -2411,7 +2408,7 @@
             }
             TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),
             TyKind::Array(ref ty, ref length) => {
-                let def_id = cx.tcx.hir.local_def_id(length.id);
+                let def_id = cx.tcx.hir().local_def_id(length.id);
                 let param_env = cx.tcx.param_env(def_id);
                 let substs = Substs::identity_for_item(cx.tcx, def_id);
                 let cid = GlobalId {
@@ -2426,7 +2423,7 @@
             },
             TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
             TyKind::Def(item_id, _) => {
-                let item = cx.tcx.hir.expect_item(item_id.id);
+                let item = cx.tcx.hir().expect_item(item_id.id);
                 if let hir::ItemKind::Existential(ref ty) = item.node {
                     ImplTrait(ty.bounds.clean(cx))
                 } else {
@@ -2447,9 +2444,9 @@
                 let mut alias = None;
                 if let Def::TyAlias(def_id) = path.def {
                     // Substitute private type aliases
-                    if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) {
+                    if let Some(node_id) = cx.tcx.hir().as_local_node_id(def_id) {
                         if !cx.renderinfo.borrow().access_levels.is_exported(def_id) {
-                            alias = Some(&cx.tcx.hir.expect_item(node_id).node);
+                            alias = Some(&cx.tcx.hir().expect_item(node_id).node);
                         }
                     }
                 };
@@ -2479,7 +2476,7 @@
                                     if let Some(lt) = lifetime.cloned() {
                                         if !lt.is_elided() {
                                             let lt_def_id =
-                                                cx.tcx.hir.local_def_id(param.id);
+                                                cx.tcx.hir().local_def_id(param.id);
                                             lt_substs.insert(lt_def_id, lt.clean(cx));
                                         }
                                     }
@@ -2487,7 +2484,7 @@
                                 }
                                 hir::GenericParamKind::Type { ref default, .. } => {
                                     let ty_param_def =
-                                        Def::TyParam(cx.tcx.hir.local_def_id(param.id));
+                                        Def::TyParam(cx.tcx.hir().local_def_id(param.id));
                                     let mut j = 0;
                                     let type_ = generic_args.args.iter().find_map(|arg| {
                                         match arg {
@@ -2608,7 +2605,7 @@
                 BareFunction(box BareFunctionDecl {
                     unsafety: sig.unsafety(),
                     generic_params: Vec::new(),
-                    decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
+                    decl: (cx.tcx.hir().local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
                     abi: sig.abi(),
                 })
             }
@@ -2760,9 +2757,9 @@
             attrs: self.attrs.clean(cx),
             source: self.span.clean(cx),
             visibility: self.vis.clean(cx),
-            stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
-            deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            stability: get_stability(cx, cx.tcx.hir().local_def_id(self.id)),
+            deprecation: get_deprecation(cx, cx.tcx.hir().local_def_id(self.id)),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             inner: StructFieldItem(self.ty.clean(cx)),
         }
     }
@@ -2834,7 +2831,7 @@
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -2854,7 +2851,7 @@
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -2901,7 +2898,7 @@
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -2928,7 +2925,7 @@
             visibility: None,
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.def.id()),
+            def_id: cx.tcx.hir().local_def_id(self.def.id()),
             inner: VariantItem(Variant {
                 kind: self.def.clean(cx),
             }),
@@ -3174,7 +3171,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());
         }
     }
@@ -3205,7 +3202,7 @@
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id.clone()),
+            def_id: cx.tcx.hir().local_def_id(self.id.clone()),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3229,7 +3226,7 @@
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id.clone()),
+            def_id: cx.tcx.hir().local_def_id(self.id.clone()),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3280,7 +3277,7 @@
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3305,7 +3302,7 @@
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3405,7 +3402,7 @@
             name: None,
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3548,7 +3545,7 @@
             name: None,
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID),
+            def_id: cx.tcx.hir().local_def_id(ast::CRATE_NODE_ID),
             visibility: self.vis.clean(cx),
             stability: None,
             deprecation: None,
@@ -3617,10 +3614,10 @@
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.span.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
-            stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
-            deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
+            stability: get_stability(cx, cx.tcx.hir().local_def_id(self.id)),
+            deprecation: get_deprecation(cx, cx.tcx.hir().local_def_id(self.id)),
             inner,
         }
     }
@@ -3683,8 +3680,8 @@
 fn print_const(cx: &DocContext, n: &ty::Const) -> String {
     match n.val {
         ConstValue::Unevaluated(def_id, _) => {
-            if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) {
-                print_const_expr(cx, cx.tcx.hir.body_owned_by(node_id))
+            if let Some(node_id) = cx.tcx.hir().as_local_node_id(def_id) {
+                print_const_expr(cx, cx.tcx.hir().body_owned_by(node_id))
             } else {
                 inline::print_inlined_const(cx, def_id)
             }
@@ -3703,7 +3700,7 @@
 }
 
 fn print_const_expr(cx: &DocContext, body: hir::BodyId) -> String {
-    cx.tcx.hir.node_to_pretty_string(body.node_id)
+    cx.tcx.hir().node_to_pretty_string(body.node_id)
 }
 
 /// Given a type Path, resolve it to a Type using the TyCtxt
@@ -3726,7 +3723,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));
@@ -3829,7 +3826,7 @@
             visibility: Some(Public),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
-            def_id: cx.tcx.hir.local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             inner: ProcMacroItem(ProcMacro {
                 kind: self.kind,
                 helpers: self.helpers.clean(cx),
@@ -3899,7 +3896,7 @@
     }
 }
 
-/// An equality constraint on an associated type, e.g. `A=Bar` in `Foo<A=Bar>`
+/// An equality constraint on an associated type, e.g., `A=Bar` in `Foo<A=Bar>`
 #[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)]
 pub struct TypeBinding {
     pub name: String,
@@ -3943,7 +3940,7 @@
 // Start of code copied from rust-clippy
 
 pub fn path_to_def_local(tcx: &TyCtxt, path: &[&str]) -> Option<DefId> {
-    let krate = tcx.hir.krate();
+    let krate = tcx.hir().krate();
     let mut items = krate.module.item_ids.clone();
     let mut path_it = path.iter().peekable();
 
@@ -3951,10 +3948,10 @@
         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);
+            let item = tcx.hir().expect_item(item_id.id);
             if item.name == *segment {
                 if path_it.peek().is_none() {
-                    return Some(tcx.hir.local_def_id(item_id.id))
+                    return Some(tcx.hir().local_def_id(item_id.id))
                 }
 
                 items = match &item.node {
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 635608d..81608b3 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -12,7 +12,7 @@
 //! more canonical form.
 //!
 //! Currently all cross-crate-inlined function use `rustc::ty` to reconstruct
-//! the AST (e.g. see all of `clean::inline`), but this is not always a
+//! the AST (e.g., see all of `clean::inline`), but this is not always a
 //! non-lossy transformation. The current format of storage for where clauses
 //! for functions and such is simply a list of predicates. One example of this
 //! is that the AST predicate of: `where T: Trait<Foo=Bar>` is encoded as:
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index f4d05c6..b421f07 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -20,7 +20,7 @@
 use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
 use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options,
                              get_cmd_lint_options};
-use rustc::session::search_paths::SearchPaths;
+use rustc::session::search_paths::SearchPath;
 use rustc_driver;
 use rustc_target::spec::TargetTriple;
 use syntax::edition::Edition;
@@ -46,7 +46,7 @@
     /// How to format errors and warnings.
     pub error_format: ErrorOutputType,
     /// Library search paths to hand to the compiler.
-    pub libs: SearchPaths,
+    pub libs: Vec<SearchPath>,
     /// The list of external crates to link against.
     pub externs: Externs,
     /// List of `cfg` flags to hand to the compiler. Always includes `rustdoc`.
@@ -295,10 +295,9 @@
         }
         let input = PathBuf::from(&matches.free[0]);
 
-        let mut libs = SearchPaths::new();
-        for s in &matches.opt_strs("L") {
-            libs.add_path(s, error_format);
-        }
+        let libs = matches.opt_strs("L").iter()
+            .map(|s| SearchPath::from_cli_opt(s, error_format))
+            .collect();
         let externs = match parse_externs(&matches) {
             Ok(ex) => ex,
             Err(err) => {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index aac0f9f..b85342f 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -51,7 +51,7 @@
 use passes;
 
 pub use rustc::session::config::{Input, Options, CodegenOptions};
-pub use rustc::session::search_paths::SearchPaths;
+pub use rustc::session::search_paths::SearchPath;
 
 pub type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>;
 
@@ -121,7 +121,7 @@
         let start_def_id = {
             let next_id = if crate_num == LOCAL_CRATE {
                 self.tcx
-                    .hir
+                    .hir()
                     .definitions()
                     .def_path_table()
                     .next_id(DefIndexAddressSpace::Low)
@@ -168,7 +168,7 @@
         if self.all_fake_def_ids.borrow().contains(&def_id) {
             None
         } else {
-            self.tcx.hir.as_local_node_id(def_id)
+            self.tcx.hir().as_local_node_id(def_id)
         }
     }
 
@@ -515,7 +515,7 @@
             // to the map from defid -> nodeid
             let access_levels = AccessLevels {
                 map: access_levels.map.iter()
-                                    .map(|(&k, &v)| (tcx.hir.local_def_id(k), v))
+                                    .map(|(&k, &v)| (tcx.hir().local_def_id(k), v))
                                     .collect()
             };
 
@@ -545,11 +545,11 @@
                 generated_synthetics: Default::default(),
                 all_traits: tcx.all_traits(LOCAL_CRATE).to_vec(),
             };
-            debug!("crate: {:?}", tcx.hir.krate());
+            debug!("crate: {:?}", tcx.hir().krate());
 
             let mut krate = {
                 let mut v = RustdocVisitor::new(&ctxt);
-                v.visit(tcx.hir.krate());
+                v.visit(tcx.hir().krate());
                 v.clean(&ctxt)
             };
 
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 5263cfe..37ff693 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -54,9 +54,13 @@
     <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}light{suffix}.css\" \
           id=\"themeStyle\">\
     <script src=\"{root_path}storage{suffix}.js\"></script>\
+    <noscript><link rel=\"stylesheet\" href=\"{root_path}noscript{suffix}.css\"></noscript>\
     {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 +85,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>\
@@ -122,7 +131,7 @@
             <div class=\"infos\">\
                 <h2>Search Tricks</h2>\
                 <p>\
-                    Prefix searches with a type followed by a colon (e.g. \
+                    Prefix searches with a type followed by a colon (e.g., \
                     <code>fn:</code>) to restrict the search to a given type.\
                 </p>\
                 <p>\
@@ -132,11 +141,11 @@
                     and <code>const</code>.\
                 </p>\
                 <p>\
-                    Search functions by type signature (e.g. \
+                    Search functions by type signature (e.g., \
                     <code>vec -> usize</code> or <code>* -> vec</code>)\
                 </p>\
                 <p>\
-                    Search multiple things at once by splitting your query with comma (e.g. \
+                    Search multiple things at once by splitting your query with comma (e.g., \
                     <code>str,u8</code> or <code>String,struct:Vec,test</code>)\
                 </p>\
             </div>\
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 00ca4fe..536ea39 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -806,6 +806,10 @@
 }
 
 pub fn plain_summary_line(md: &str) -> String {
+    plain_summary_line_full(md, false)
+}
+
+pub fn plain_summary_line_full(md: &str, limit_length: bool) -> String {
     struct ParserWrapper<'a> {
         inner: Parser<'a>,
         is_in: isize,
@@ -852,7 +856,21 @@
             s.push_str(&t);
         }
     }
-    s
+    if limit_length && s.chars().count() > 60 {
+        let mut len = 0;
+        let mut ret = s.split_whitespace()
+                       .take_while(|p| {
+                           // + 1 for the added character after the word.
+                           len += p.chars().count() + 1;
+                           len < 60
+                       })
+                       .collect::<Vec<_>>()
+                       .join(" ");
+        ret.push('…');
+        ret
+    } else {
+        s
+    }
 }
 
 pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 1194df2..c9f3aa0 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -698,7 +698,7 @@
                 ty: item.type_(),
                 name: item.name.clone().unwrap(),
                 path: fqp[..fqp.len() - 1].join("::"),
-                desc: plain_summary_line(item.doc_value()),
+                desc: plain_summary_line_short(item.doc_value()),
                 parent: Some(did),
                 parent_idx: None,
                 search_type: get_index_search_type(&item),
@@ -736,7 +736,7 @@
     }
 
     let crate_doc = krate.module.as_ref().map(|module| {
-        plain_summary_line(module.doc_value())
+        plain_summary_line_short(module.doc_value())
     }).unwrap_or(String::new());
 
     let mut crate_data = BTreeMap::new();
@@ -772,16 +772,16 @@
     write_minify(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
                  static_files::SETTINGS_CSS,
                  options.enable_minification)?;
+    write_minify(cx.dst.join(&format!("noscript{}.css", cx.shared.resource_suffix)),
+                 static_files::NOSCRIPT_CSS,
+                 options.enable_minification)?;
 
     // To avoid "light.css" to be overwritten, we'll first run over the received themes and only
     // then we'll run over the "official" styles.
     let mut themes: FxHashSet<String> = FxHashSet::default();
 
     for entry in &cx.shared.themes {
-        let mut content = Vec::with_capacity(100000);
-
-        let mut f = try_err!(File::open(&entry), &entry);
-        try_err!(f.read_to_end(&mut content), &entry);
+        let content = try_err!(fs::read(&entry), &entry);
         let theme = try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry);
         let extension = try_none!(try_none!(entry.extension(), &entry).to_str(), &entry);
         write(cx.dst.join(format!("{}{}.{}", theme, cx.shared.resource_suffix, extension)),
@@ -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)?;
@@ -866,9 +868,8 @@
     }
 
     {
-        let mut data = format!("var resourcesSuffix = \"{}\";\n",
-                               cx.shared.resource_suffix);
-        data.push_str(static_files::STORAGE_JS);
+        let mut data = static_files::STORAGE_JS.to_owned();
+        data.push_str(&format!("var resourcesSuffix = \"{}\";", cx.shared.resource_suffix));
         write_minify(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)),
                      &data,
                      options.enable_minification)?;
@@ -879,10 +880,7 @@
         if !options.enable_minification {
             try_err!(fs::copy(css, out), css);
         } else {
-            let mut f = try_err!(File::open(css), css);
-            let mut buffer = String::with_capacity(1000);
-
-            try_err!(f.read_to_string(&mut buffer), css);
+            let buffer = try_err!(fs::read_to_string(css), css);
             write_minify(out, &buffer, options.enable_minification)?;
         }
     }
@@ -1066,7 +1064,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() {
@@ -1485,7 +1483,7 @@
                             ty: item.type_(),
                             name: s.to_string(),
                             path: path.join("::"),
-                            desc: plain_summary_line(item.doc_value()),
+                            desc: plain_summary_line_short(item.doc_value()),
                             parent,
                             parent_idx: None,
                             search_type: get_index_search_type(&item),
@@ -1516,7 +1514,8 @@
             clean::FunctionItem(..) | clean::ModuleItem(..) |
             clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
             clean::ConstantItem(..) | clean::StaticItem(..) |
-            clean::UnionItem(..) | clean::ForeignTypeItem | clean::MacroItem(..)
+            clean::UnionItem(..) | clean::ForeignTypeItem |
+            clean::MacroItem(..) | clean::ProcMacroItem(..)
             if !self.stripped_mod => {
                 // Re-exported items mean that the same id can show up twice
                 // in the rustdoc ast that we're looking at. We know,
@@ -1677,7 +1676,7 @@
                                 ty: item.type_(),
                                 name: item_name.to_string(),
                                 path: path.clone(),
-                                desc: plain_summary_line(item.doc_value()),
+                                desc: plain_summary_line_short(item.doc_value()),
                                 parent: None,
                                 parent_idx: None,
                                 search_type: get_index_search_type(&item),
@@ -2075,7 +2074,7 @@
     fn item<F>(&mut self, item: clean::Item, all: &mut AllTypes, mut f: F) -> Result<(), Error>
         where F: FnMut(&mut Context, clean::Item),
     {
-        // Stripped modules survive the rustdoc passes (i.e. `strip-private`)
+        // Stripped modules survive the rustdoc passes (i.e., `strip-private`)
         // if they contain impls for public types. These modules can also
         // contain items such as publicly re-exported structures.
         //
@@ -2100,8 +2099,7 @@
                 if !buf.is_empty() {
                     try_err!(this.shared.ensure_dir(&this.dst), &this.dst);
                     let joint_dst = this.dst.join("index.html");
-                    let mut dst = try_err!(File::create(&joint_dst), &joint_dst);
-                    try_err!(dst.write_all(&buf), &joint_dst);
+                    try_err!(fs::write(&joint_dst, buf), &joint_dst);
                 }
 
                 let m = match item.inner {
@@ -2135,8 +2133,7 @@
                 let file_name = &item_path(item_type, name);
                 try_err!(self.shared.ensure_dir(&self.dst), &self.dst);
                 let joint_dst = self.dst.join(file_name);
-                let mut dst = try_err!(File::create(&joint_dst), &joint_dst);
-                try_err!(dst.write_all(&buf), &joint_dst);
+                try_err!(fs::write(&joint_dst, buf), &joint_dst);
 
                 if !self.render_redirect_pages {
                     all.append(full_path(self, &item), &item_type);
@@ -2394,7 +2391,13 @@
 #[inline]
 fn plain_summary_line(s: Option<&str>) -> String {
     let line = shorter(s).replace("\n", " ");
-    markdown::plain_summary_line(&line[..])
+    markdown::plain_summary_line_full(&line[..], false)
+}
+
+#[inline]
+fn plain_summary_line_short(s: Option<&str>) -> String {
+    let line = shorter(s).replace("\n", " ");
+    markdown::plain_summary_line_full(&line[..], true)
 }
 
 fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Result {
@@ -3012,6 +3015,22 @@
     // Trait documentation
     document(w, cx, it)?;
 
+    fn write_small_section_header(
+        w: &mut fmt::Formatter,
+        id: &str,
+        title: &str,
+        extra_content: &str,
+    ) -> fmt::Result {
+        write!(w, "
+            <h2 id='{0}' class='small-section-header'>\
+              {1}<a href='#{0}' class='anchor'></a>\
+            </h2>{2}", id, title, extra_content)
+    }
+
+    fn write_loading_content(w: &mut fmt::Formatter, extra_content: &str) -> fmt::Result {
+        write!(w, "{}<span class='loading-content'>Loading content...</span>", extra_content)
+    }
+
     fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::Item)
                   -> fmt::Result {
         let name = m.name.as_ref().unwrap();
@@ -3032,74 +3051,45 @@
     }
 
     if !types.is_empty() {
-        write!(w, "
-            <h2 id='associated-types' class='small-section-header'>
-              Associated Types<a href='#associated-types' class='anchor'></a>
-            </h2>
-            <div class='methods'>
-        ")?;
+        write_small_section_header(w, "associated-types", "Associated Types",
+                                   "<div class='methods'>")?;
         for t in &types {
             trait_item(w, cx, *t, it)?;
         }
-        write!(w, "</div>")?;
+        write_loading_content(w, "</div>")?;
     }
 
     if !consts.is_empty() {
-        write!(w, "
-            <h2 id='associated-const' class='small-section-header'>
-              Associated Constants<a href='#associated-const' class='anchor'></a>
-            </h2>
-            <div class='methods'>
-        ")?;
+        write_small_section_header(w, "associated-const", "Associated Constants",
+                                   "<div class='methods'>")?;
         for t in &consts {
             trait_item(w, cx, *t, it)?;
         }
-        write!(w, "</div>")?;
+        write_loading_content(w, "</div>")?;
     }
 
     // Output the documentation for each function individually
     if !required.is_empty() {
-        write!(w, "
-            <h2 id='required-methods' class='small-section-header'>
-              Required Methods<a href='#required-methods' class='anchor'></a>
-            </h2>
-            <div class='methods'>
-        ")?;
+        write_small_section_header(w, "required-methods", "Required methods",
+                                   "<div class='methods'>")?;
         for m in &required {
             trait_item(w, cx, *m, it)?;
         }
-        write!(w, "</div>")?;
+        write_loading_content(w, "</div>")?;
     }
     if !provided.is_empty() {
-        write!(w, "
-            <h2 id='provided-methods' class='small-section-header'>
-              Provided Methods<a href='#provided-methods' class='anchor'></a>
-            </h2>
-            <div class='methods'>
-        ")?;
+        write_small_section_header(w, "provided-methods", "Provided methods",
+                                   "<div class='methods'>")?;
         for m in &provided {
             trait_item(w, cx, *m, it)?;
         }
-        write!(w, "</div>")?;
+        write_loading_content(w, "</div>")?;
     }
 
     // If there are methods directly on this trait object, render them here.
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)?;
 
     let cache = cache();
-    let impl_header = "\
-        <h2 id='implementors' class='small-section-header'>\
-          Implementors<a href='#implementors' class='anchor'></a>\
-        </h2>\
-        <div class='item-list' id='implementors-list'>\
-    ";
-
-    let synthetic_impl_header = "\
-        <h2 id='synthetic-implementors' class='small-section-header'>\
-          Auto implementors<a href='#synthetic-implementors' class='anchor'></a>\
-        </h2>\
-        <div class='item-list' id='synthetic-implementors-list'>\
-    ";
 
     let mut synthetic_types = Vec::new();
 
@@ -3136,11 +3126,7 @@
         concrete.sort_by(compare_impl);
 
         if !foreign.is_empty() {
-            write!(w, "
-                <h2 id='foreign-impls' class='small-section-header'>
-                  Implementations on Foreign Types<a href='#foreign-impls' class='anchor'></a>
-                </h2>
-            ")?;
+            write_small_section_header(w, "foreign-impls", "Implementations on Foreign Types", "")?;
 
             for implementor in foreign {
                 let assoc_link = AssocItemLink::GotoSource(
@@ -3151,33 +3137,38 @@
                             RenderMode::Normal, implementor.impl_item.stable_since(), false,
                             None)?;
             }
+            write_loading_content(w, "")?;
         }
 
-        write!(w, "{}", impl_header)?;
+        write_small_section_header(w, "implementors", "Implementors",
+                                   "<div class='item-list' id='implementors-list'>")?;
         for implementor in concrete {
             render_implementor(cx, implementor, w, &implementor_dups)?;
         }
-        write!(w, "</div>")?;
+        write_loading_content(w, "</div>")?;
 
         if t.auto {
-            write!(w, "{}", synthetic_impl_header)?;
+            write_small_section_header(w, "synthetic-implementors", "Auto implementors",
+                                       "<div class='item-list' id='synthetic-implementors-list'>")?;
             for implementor in synthetic {
                 synthetic_types.extend(
                     collect_paths_for_type(implementor.inner_impl().for_.clone())
                 );
                 render_implementor(cx, implementor, w, &implementor_dups)?;
             }
-            write!(w, "</div>")?;
+            write_loading_content(w, "</div>")?;
         }
     } else {
         // even without any implementations to write in, we still want the heading and list, so the
         // implementors javascript file pulled in below has somewhere to write the impls into
-        write!(w, "{}", impl_header)?;
-        write!(w, "</div>")?;
+        write_small_section_header(w, "implementors", "Implementors",
+                                   "<div class='item-list' id='implementors-list'>")?;
+        write_loading_content(w, "</div>")?;
 
         if t.auto {
-            write!(w, "{}", synthetic_impl_header)?;
-            write!(w, "</div>")?;
+            write_small_section_header(w, "synthetic-implementors", "Auto implementors",
+                                       "<div class='item-list' id='synthetic-implementors-list'>")?;
+            write_loading_content(w, "</div>")?;
         }
     }
     write!(w, r#"<script type="text/javascript">window.inlined_types=new Set({});</script>"#,
@@ -4796,7 +4787,7 @@
             tmp /= 10;
         }
         write!(fmt, "<pre class=\"line-numbers\">")?;
-        for i in 1..lines + 1 {
+        for i in 1..=lines {
             write!(fmt, "<span id=\"{0}\">{0:1$}</span>\n", i, cols)?;
         }
         write!(fmt, "</pre>")?;
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 125277f..51714c3 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -30,6 +30,27 @@
     };
 }
 
+if (!DOMTokenList.prototype.add) {
+    DOMTokenList.prototype.add = function(className) {
+        if (className && !hasClass(this, className)) {
+            if (this.className && this.className.length > 0) {
+                this.className += " " + className;
+            } else {
+                this.className = className;
+            }
+        }
+    };
+}
+
+if (!DOMTokenList.prototype.remove) {
+    DOMTokenList.prototype.remove = function(className) {
+        if (className && this.className) {
+            this.className = (" " + this.className + " ").replace(" " + className + " ", " ")
+                                                         .trim();
+        }
+    };
+}
+
 (function() {
     "use strict";
 
@@ -61,7 +82,7 @@
                      "attr",
                      "derive"];
 
-    var search_input = document.getElementsByClassName('search-input')[0];
+    var search_input = document.getElementsByClassName("search-input")[0];
 
     // On the search screen, so you remain on the last tab you opened.
     //
@@ -75,9 +96,9 @@
     var titleBeforeSearch = document.title;
 
     function getPageId() {
-        var id = document.location.href.split('#')[1];
+        var id = document.location.href.split("#")[1];
         if (id) {
-            return id.split('?')[0].split('&')[0];
+            return id.split("?")[0].split("&")[0];
         }
         return null;
     }
@@ -87,9 +108,9 @@
         if (elems) {
             addClass(elems, "show-it");
         }
-        var sidebar = document.getElementsByClassName('sidebar')[0];
+        var sidebar = document.getElementsByClassName("sidebar")[0];
         if (sidebar) {
-            addClass(sidebar, 'mobile');
+            addClass(sidebar, "mobile");
             var filler = document.getElementById("sidebar-filler");
             if (!filler) {
                 var div = document.createElement("div");
@@ -108,13 +129,13 @@
         if (elems) {
             removeClass(elems, "show-it");
         }
-        var sidebar = document.getElementsByClassName('sidebar')[0];
-        removeClass(sidebar, 'mobile');
+        var sidebar = document.getElementsByClassName("sidebar")[0];
+        removeClass(sidebar, "mobile");
         var filler = document.getElementById("sidebar-filler");
         if (filler) {
             filler.remove();
         }
-        document.getElementsByTagName("body")[0].style.marginTop = '';
+        document.getElementsByTagName("body")[0].style.marginTop = "";
         var themePicker = document.getElementsByClassName("theme-picker");
         if (themePicker && themePicker.length > 0) {
             themePicker[0].style.display = null;
@@ -125,8 +146,8 @@
     var TY_PRIMITIVE = itemTypes.indexOf("primitive");
     var TY_KEYWORD = itemTypes.indexOf("keyword");
 
-    onEach(document.getElementsByClassName('js-only'), function(e) {
-        removeClass(e, 'js-only');
+    onEachLazy(document.getElementsByClassName("js-only"), function(e) {
+        removeClass(e, "js-only");
     });
 
     function getQueryStringParams() {
@@ -145,16 +166,19 @@
           window.history && typeof window.history.pushState === "function";
     }
 
+    var main = document.getElementById("main");
+
     function highlightSourceLines(ev) {
         // If we're in mobile mode, we should add the sidebar in any case.
         hideSidebar();
+        var elem;
         var search = document.getElementById("search");
         var i, from, to, match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
         if (match) {
             from = parseInt(match[1], 10);
             to = Math.min(50000, parseInt(match[2] || match[1], 10));
             from = Math.min(from, to);
-            var elem = document.getElementById(from);
+            elem = document.getElementById(from);
             if (!elem) {
                 return;
             }
@@ -164,22 +188,22 @@
                     x.scrollIntoView();
                 }
             }
-            onEach(document.getElementsByClassName('line-numbers'), function(e) {
-                onEach(e.getElementsByTagName('span'), function(i_e) {
-                    removeClass(i_e, 'line-highlighted');
+            onEachLazy(document.getElementsByClassName("line-numbers"), function(e) {
+                onEachLazy(e.getElementsByTagName("span"), function(i_e) {
+                    removeClass(i_e, "line-highlighted");
                 });
             });
             for (i = from; i <= to; ++i) {
-                addClass(document.getElementById(i), 'line-highlighted');
+                addClass(document.getElementById(i), "line-highlighted");
             }
         } else if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
             addClass(search, "hidden");
-            removeClass(document.getElementById("main"), "hidden");
-            var hash = ev.newURL.slice(ev.newURL.indexOf('#') + 1);
+            removeClass(main, "hidden");
+            var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
             if (browserSupportsHistoryApi()) {
                 history.replaceState(hash, "", "?search=#" + hash);
             }
-            var elem = document.getElementById(hash);
+            elem = document.getElementById(hash);
             if (elem) {
                 elem.scrollIntoView();
             }
@@ -190,7 +214,7 @@
         var elem = document.getElementById(id);
         if (elem && isHidden(elem)) {
             var h3 = elem.parentNode.previousSibling;
-            if (h3 && h3.tagName !== 'H3') {
+            if (h3 && h3.tagName !== "H3") {
                 h3 = h3.previousSibling; // skip div.docblock
             }
 
@@ -218,12 +242,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);
     }
 
@@ -234,7 +260,7 @@
                 removeClass(help, "hidden");
                 addClass(document.body, "blur");
             }
-        } else if (!hasClass(help, "hidden")) {
+        } else if (hasClass(help, "hidden") === false) {
             ev.preventDefault();
             addClass(help, "hidden");
             removeClass(document.body, "blur");
@@ -244,12 +270,12 @@
     function handleEscape(ev, help) {
         hideModal();
         var search = document.getElementById("search");
-        if (!hasClass(help, "hidden")) {
+        if (hasClass(help, "hidden") === false) {
             displayHelp(false, ev);
-        } else if (!hasClass(search, "hidden")) {
+        } else if (hasClass(search, "hidden") === false) {
             ev.preventDefault();
             addClass(search, "hidden");
-            removeClass(document.getElementById("main"), "hidden");
+            removeClass(main, "hidden");
             document.title = titleBeforeSearch;
         }
         defocusSearchBar();
@@ -303,26 +329,27 @@
             if (elem && elem.tagName === tagName) {
                 return elem;
             }
-        } while (elem = elem.parentNode);
+            elem = elem.parentNode;
+        } while (elem);
         return null;
     }
 
     document.onkeypress = handleShortcut;
     document.onkeydown = handleShortcut;
     document.onclick = function(ev) {
-        if (hasClass(ev.target, 'collapse-toggle')) {
+        if (hasClass(ev.target, "collapse-toggle")) {
             collapseDocs(ev.target, "toggle");
-        } else if (hasClass(ev.target.parentNode, 'collapse-toggle')) {
+        } else if (hasClass(ev.target.parentNode, "collapse-toggle")) {
             collapseDocs(ev.target.parentNode, "toggle");
-        } else if (ev.target.tagName === 'SPAN' && hasClass(ev.target.parentNode, 'line-numbers')) {
+        } else if (ev.target.tagName === "SPAN" && hasClass(ev.target.parentNode, "line-numbers")) {
             var prev_id = 0;
 
             var set_fragment = function(name) {
                 if (browserSupportsHistoryApi()) {
-                    history.replaceState(null, null, '#' + name);
+                    history.replaceState(null, null, "#" + name);
                     window.hashchange();
                 } else {
-                    location.replace('#' + name);
+                    location.replace("#" + name);
                 }
             };
 
@@ -335,31 +362,31 @@
                     cur_id = tmp;
                 }
 
-                set_fragment(prev_id + '-' + cur_id);
+                set_fragment(prev_id + "-" + cur_id);
             } else {
                 prev_id = cur_id;
 
                 set_fragment(cur_id);
             }
-        } else if (!hasClass(document.getElementById("help"), "hidden")) {
+        } else if (hasClass(document.getElementById("help"), "hidden") === false) {
             addClass(document.getElementById("help"), "hidden");
             removeClass(document.body, "blur");
         } else {
             // Making a collapsed element visible on onhashchange seems
             // too late
-            var a = findParentElement(ev.target, 'A');
+            var a = findParentElement(ev.target, "A");
             if (a && a.hash) {
-                expandSection(a.hash.replace(/^#/, ''));
+                expandSection(a.hash.replace(/^#/, ""));
             }
         }
     };
 
-    var x = document.getElementsByClassName('version-selector');
+    var x = document.getElementsByClassName("version-selector");
     if (x.length > 0) {
         x[0].onchange = function() {
             var i, match,
                 url = document.location.href,
-                stripped = '',
+                stripped = "",
                 len = rootPath.match(/\.\.\//g).length + 1;
 
             for (i = 0; i < len; ++i) {
@@ -370,7 +397,7 @@
                 url = url.substring(0, url.length - match[0].length);
             }
 
-            url += '/' + document.getElementsByClassName('version-selector')[0].value + stripped;
+            url += "/" + document.getElementsByClassName("version-selector")[0].value + stripped;
 
             document.location.href = url;
         };
@@ -426,19 +453,21 @@
         // where you start trying to do a search, and the index loads, and
         // suddenly your search is gone!
         if (search_input.value === "") {
-            search_input.value = params.search || '';
+            search_input.value = params.search || "";
         }
 
         /**
          * 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) {
+                var length = itemTypes.length;
+                for (var i = 0; i < length; ++i) {
                     if (itemTypes[i] === typename) {
                         return i;
                     }
@@ -452,7 +481,8 @@
                 results = {}, results_in_args = {}, results_returned = {},
                 split = valLower.split("::");
 
-            for (var z = 0; z < split.length; ++z) {
+            var length = split.length;
+            for (var z = 0; z < length; ++z) {
                 if (split[z] === "") {
                     split.splice(z, 1);
                     z -= 1;
@@ -461,7 +491,8 @@
 
             function transformResults(results, isType) {
                 var out = [];
-                for (i = 0; i < results.length; ++i) {
+                var length = results.length;
+                for (var i = 0; i < length; ++i) {
                     if (results[i].id > -1) {
                         var obj = searchIndex[results[i].id];
                         obj.lev = results[i].lev;
@@ -470,7 +501,7 @@
                             obj.displayPath = pathSplitter(res[0]);
                             obj.fullPath = obj.displayPath + obj.name;
                             // To be sure than it some items aren't considered as duplicate.
-                            obj.fullPath += '|' + obj.ty;
+                            obj.fullPath += "|" + obj.ty;
                             obj.href = res[1];
                             out.push(obj);
                             if (out.length >= MAX_RESULTS) {
@@ -490,8 +521,9 @@
                     }
                 }
                 results = ar;
+                var i;
                 var nresults = results.length;
-                for (var i = 0; i < nresults; ++i) {
+                for (i = 0; i < nresults; ++i) {
                     results[i].word = searchWords[results[i].id];
                     results[i].item = searchIndex[results[i].id] || {};
                 }
@@ -549,8 +581,8 @@
                     }
 
                     // sort by description (no description goes later)
-                    a = (aaa.item.desc === '');
-                    b = (bbb.item.desc === '');
+                    a = (aaa.item.desc === "");
+                    b = (bbb.item.desc === "");
                     if (a !== b) { return a - b; }
 
                     // sort by type (later occurrence in `itemTypes` goes later)
@@ -567,7 +599,8 @@
                     return 0;
                 });
 
-                for (var i = 0; i < results.length; ++i) {
+                var length = results.length;
+                for (i = 0; i < length; ++i) {
                     var result = results[i];
 
                     // this validation does not make sense when searching by types
@@ -589,10 +622,10 @@
 
             function extractGenerics(val) {
                 val = val.toLowerCase();
-                if (val.indexOf('<') !== -1) {
-                    var values = val.substring(val.indexOf('<') + 1, val.lastIndexOf('>'));
+                if (val.indexOf("<") !== -1) {
+                    var values = val.substring(val.indexOf("<") + 1, val.lastIndexOf(">"));
                     return {
-                        name: val.substring(0, val.indexOf('<')),
+                        name: val.substring(0, val.indexOf("<")),
                         generics: values.split(/\s*,\s*/),
                     };
                 }
@@ -614,9 +647,11 @@
                         var done = 0;
                         // We need to find the type that matches the most to remove it in order
                         // to move forward.
-                        for (var y = 0; y < val.generics.length; ++y) {
+                        var vlength = val.generics.length;
+                        for (var y = 0; y < vlength; ++y) {
                             var lev = { pos: -1, lev: MAX_LEV_DISTANCE + 1};
-                            for (var x = 0; x < elems.length; ++x) {
+                            var elength = elems.length;
+                            for (var x = 0; x < elength; ++x) {
                                 var tmp_lev = levenshtein(elems[x], val.generics[y]);
                                 if (tmp_lev < lev.lev) {
                                     lev.lev = tmp_lev;
@@ -641,6 +676,7 @@
             // Check for type name and type generics (if any).
             function checkType(obj, val, literalSearch) {
                 var lev_distance = MAX_LEV_DISTANCE + 1;
+                var x;
                 if (obj[NAME] === val.name) {
                     if (literalSearch === true) {
                         if (val.generics && val.generics.length !== 0) {
@@ -648,7 +684,6 @@
                                   obj[GENERICS_DATA].length >= val.generics.length) {
                                 var elems = obj[GENERICS_DATA].slice(0);
                                 var allFound = true;
-                                var x;
 
                                 for (var y = 0; allFound === true && y < val.generics.length; ++y) {
                                     allFound = false;
@@ -682,7 +717,8 @@
                 // Names didn't match so let's check if one of the generic types could.
                 if (literalSearch === true) {
                      if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) {
-                        for (var x = 0; x < obj[GENERICS_DATA].length; ++x) {
+                        var length = obj[GENERICS_DATA].length;
+                        for (x = 0; x < length; ++x) {
                             if (obj[GENERICS_DATA][x] === val.name) {
                                 return true;
                             }
@@ -690,13 +726,13 @@
                     }
                     return false;
                 }
-                var lev_distance = Math.min(levenshtein(obj[NAME], val.name),
-                                            lev_distance);
+                lev_distance = Math.min(levenshtein(obj[NAME], val.name), lev_distance);
                 if (lev_distance <= MAX_LEV_DISTANCE) {
                     lev_distance = Math.min(checkGenerics(obj, val), lev_distance);
                 } else if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) {
                     // We can check if the type we're looking for is inside the generics!
-                    for (var x = 0; x < obj[GENERICS_DATA].length; ++x) {
+                    var olength = obj[GENERICS_DATA].length;
+                    for (x = 0; x < olength; ++x) {
                         lev_distance = Math.min(levenshtein(obj[GENERICS_DATA][x], val.name),
                                                 lev_distance);
                     }
@@ -711,7 +747,8 @@
 
                 if (obj && obj.type && obj.type[INPUTS_DATA] &&
                       obj.type[INPUTS_DATA].length > 0) {
-                    for (var i = 0; i < obj.type[INPUTS_DATA].length; i++) {
+                    var length = obj.type[INPUTS_DATA].length;
+                    for (var i = 0; i < length; i++) {
                         var tmp = checkType(obj.type[INPUTS_DATA][i], val, literalSearch);
                         if (literalSearch === true && tmp === true) {
                             return true;
@@ -752,16 +789,18 @@
                     path.push(ty.parent.name.toLowerCase());
                 }
 
-                if (contains.length > path.length) {
+                var length = path.length;
+                var clength = contains.length;
+                if (clength > length) {
                     return MAX_LEV_DISTANCE + 1;
                 }
-                for (var i = 0; i < path.length; ++i) {
-                    if (i + contains.length > path.length) {
+                for (var i = 0; i < length; ++i) {
+                    if (i + clength > length) {
                         break;
                     }
                     var lev_total = 0;
                     var aborted = false;
-                    for (var x = 0; x < contains.length; ++x) {
+                    for (var x = 0; x < clength; ++x) {
                         var lev = levenshtein(path[i + x], contains[x]);
                         if (lev > MAX_LEV_DISTANCE) {
                             aborted = true;
@@ -770,7 +809,7 @@
                         lev_total += lev;
                     }
                     if (aborted === false) {
-                        ret_lev = Math.min(ret_lev, Math.round(lev_total / contains.length));
+                        ret_lev = Math.min(ret_lev, Math.round(lev_total / clength));
                     }
                 }
                 return ret_lev;
@@ -807,15 +846,23 @@
 
             // quoted values mean literal search
             var nSearchWords = searchWords.length;
+            var i;
+            var ty;
+            var fullId;
+            var returned;
+            var in_args;
             if ((val.charAt(0) === "\"" || val.charAt(0) === "'") &&
                 val.charAt(val.length - 1) === val.charAt(0))
             {
                 val = extractGenerics(val.substr(1, val.length - 2));
-                for (var i = 0; i < nSearchWords; ++i) {
-                    var in_args = findArg(searchIndex[i], val, true);
-                    var returned = checkReturned(searchIndex[i], val, true);
-                    var ty = searchIndex[i];
-                    var fullId = generateId(ty);
+                for (i = 0; i < nSearchWords; ++i) {
+                    if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) {
+                        continue;
+                    }
+                    in_args = findArg(searchIndex[i], val, true);
+                    returned = checkReturned(searchIndex[i], val, true);
+                    ty = searchIndex[i];
+                    fullId = generateId(ty);
 
                     if (searchWords[i] === val.name) {
                         // filter type: ... queries
@@ -860,24 +907,27 @@
                 var input = parts[0];
                 // sort inputs so that order does not matter
                 var inputs = input.split(",").map(trimmer).sort();
-                for (var i = 0; i < inputs.length; ++i) {
+                for (i = 0; i < inputs.length; ++i) {
                     inputs[i] = extractGenerics(inputs[i]);
                 }
                 var output = extractGenerics(parts[1]);
 
-                for (var i = 0; i < nSearchWords; ++i) {
+                for (i = 0; i < nSearchWords; ++i) {
+                    if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) {
+                        continue;
+                    }
                     var type = searchIndex[i].type;
-                    var ty = searchIndex[i];
+                    ty = searchIndex[i];
                     if (!type) {
                         continue;
                     }
-                    var fullId = generateId(ty);
+                    fullId = generateId(ty);
 
                     // allow searching for void (no output) functions as well
                     var typeOutput = type.length > OUTPUT_DATA ? type[OUTPUT_DATA].name : "";
-                    var returned = checkReturned(ty, output, true);
+                    returned = checkReturned(ty, output, true);
                     if (output.name === "*" || returned === true) {
-                        var in_args = false;
+                        in_args = false;
                         var module = false;
 
                         if (input === "*") {
@@ -937,14 +987,16 @@
                 var contains = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1);
 
                 for (j = 0; j < nSearchWords; ++j) {
+                    var lev;
                     var lev_distance;
-                    var ty = searchIndex[j];
-                    if (!ty) {
+                    ty = searchIndex[j];
+                    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);
+                        lev = checkPath(contains, paths[paths.length - 1], ty);
                         if (lev > MAX_LEV_DISTANCE) {
                             continue;
                         } else if (lev > 0) {
@@ -952,12 +1004,12 @@
                         }
                     }
 
-                    var returned = MAX_LEV_DISTANCE + 1;
-                    var in_args = MAX_LEV_DISTANCE + 1;
+                    returned = MAX_LEV_DISTANCE + 1;
+                    in_args = MAX_LEV_DISTANCE + 1;
                     var index = -1;
                     // we want lev results to go lower than others
-                    var lev = MAX_LEV_DISTANCE + 1;
-                    var fullId = generateId(ty);
+                    lev = MAX_LEV_DISTANCE + 1;
+                    fullId = generateId(ty);
 
                     if (searchWords[j].indexOf(split[i]) > -1 ||
                         searchWords[j].indexOf(val) > -1 ||
@@ -1033,14 +1085,14 @@
             }
 
             var ret = {
-                'in_args': sortResults(results_in_args, true),
-                'returned': sortResults(results_returned, true),
-                'others': sortResults(results),
+                "in_args": sortResults(results_in_args, true),
+                "returned": sortResults(results_returned, true),
+                "others": sortResults(results),
             };
             if (ALIASES && ALIASES[window.currentCrate] &&
                     ALIASES[window.currentCrate][query.raw]) {
                 var aliases = ALIASES[window.currentCrate][query.raw];
-                for (var i = 0; i < aliases.length; ++i) {
+                for (i = 0; i < aliases.length; ++i) {
                     aliases[i].is_alias = true;
                     aliases[i].alias = query.raw;
                     aliases[i].path = aliases[i].p;
@@ -1048,9 +1100,9 @@
                     aliases[i].displayPath = pathSplitter(res[0]);
                     aliases[i].fullPath = aliases[i].displayPath + aliases[i].name;
                     aliases[i].href = res[1];
-                    ret['others'].unshift(aliases[i]);
-                    if (ret['others'].length > MAX_RESULTS) {
-                        ret['others'].pop();
+                    ret.others.unshift(aliases[i]);
+                    if (ret.others.length > MAX_RESULTS) {
+                        ret.others.pop();
                     }
                 }
             }
@@ -1097,7 +1149,7 @@
 
             matches = query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i);
             if (matches) {
-                type = matches[1].replace(/^const$/, 'constant');
+                type = matches[1].replace(/^const$/, "constant");
                 query = query.substring(matches[0].length);
             }
 
@@ -1115,38 +1167,38 @@
             var click_func = function(e) {
                 var el = e.target;
                 // to retrieve the real "owner" of the event.
-                while (el.tagName !== 'TR') {
+                while (el.tagName !== "TR") {
                     el = el.parentNode;
                 }
-                var dst = e.target.getElementsByTagName('a');
+                var dst = e.target.getElementsByTagName("a");
                 if (dst.length < 1) {
                     return;
                 }
                 dst = dst[0];
                 if (window.location.pathname === dst.pathname) {
-                    addClass(document.getElementById('search'), 'hidden');
-                    removeClass(document.getElementById('main'), 'hidden');
+                    addClass(document.getElementById("search"), "hidden");
+                    removeClass(main, "hidden");
                     document.location.href = dst.href;
                 }
             };
             var mouseover_func = function(e) {
                 var el = e.target;
                 // to retrieve the real "owner" of the event.
-                while (el.tagName !== 'TR') {
+                while (el.tagName !== "TR") {
                     el = el.parentNode;
                 }
                 clearTimeout(hoverTimeout);
                 hoverTimeout = setTimeout(function() {
-                    onEach(document.getElementsByClassName('search-results'), function(e) {
-                        onEach(e.getElementsByClassName('result'), function(i_e) {
-                            removeClass(i_e, 'highlighted');
+                    onEachLazy(document.getElementsByClassName("search-results"), function(e) {
+                        onEachLazy(e.getElementsByClassName("result"), function(i_e) {
+                            removeClass(i_e, "highlighted");
                         });
                     });
-                    addClass(el, 'highlighted');
+                    addClass(el, "highlighted");
                 }, 20);
             };
-            onEach(document.getElementsByClassName('search-results'), function(e) {
-                onEach(e.getElementsByClassName('result'), function(i_e) {
+            onEachLazy(document.getElementsByClassName("search-results"), function(e) {
+                onEachLazy(e.getElementsByClassName("result"), function(i_e) {
                     i_e.onclick = click_func;
                     i_e.onmouseover = mouseover_func;
                 });
@@ -1158,8 +1210,8 @@
                 var actives = [[], [], []];
                 // "current" is used to know which tab we're looking into.
                 var current = 0;
-                onEach(document.getElementsByClassName('search-results'), function(e) {
-                    onEach(e.getElementsByClassName('highlighted'), function(e) {
+                onEachLazy(document.getElementsByClassName("search-results"), function(e) {
+                    onEachLazy(e.getElementsByClassName("highlighted"), function(e) {
                         actives[current].push(e);
                     });
                     current += 1;
@@ -1171,25 +1223,25 @@
                         return;
                     }
 
-                    addClass(actives[currentTab][0].previousElementSibling, 'highlighted');
-                    removeClass(actives[currentTab][0], 'highlighted');
+                    addClass(actives[currentTab][0].previousElementSibling, "highlighted");
+                    removeClass(actives[currentTab][0], "highlighted");
                 } else if (e.which === 40) { // down
                     if (!actives[currentTab].length) {
-                        var results = document.getElementsByClassName('search-results');
+                        var results = document.getElementsByClassName("search-results");
                         if (results.length > 0) {
-                            var res = results[currentTab].getElementsByClassName('result');
+                            var res = results[currentTab].getElementsByClassName("result");
                             if (res.length > 0) {
-                                addClass(res[0], 'highlighted');
+                                addClass(res[0], "highlighted");
                             }
                         }
                     } else if (actives[currentTab][0].nextElementSibling) {
-                        addClass(actives[currentTab][0].nextElementSibling, 'highlighted');
-                        removeClass(actives[currentTab][0], 'highlighted');
+                        addClass(actives[currentTab][0].nextElementSibling, "highlighted");
+                        removeClass(actives[currentTab][0], "highlighted");
                     }
                 } else if (e.which === 13) { // return
                     if (actives[currentTab].length) {
                         document.location.href =
-                            actives[currentTab][0].getElementsByTagName('a')[0].href;
+                            actives[currentTab][0].getElementsByTagName("a")[0].href;
                     }
                 } else if (e.which === 9) { // tab
                     if (e.shiftKey) {
@@ -1201,11 +1253,11 @@
                 } else if (e.which === 16) { // shift
                     // Does nothing, it's just to avoid losing "focus" on the highlighted element.
                 } else if (e.which === 27) { // escape
-                    removeClass(actives[currentTab][0], 'highlighted');
-                    search_input.value = '';
+                    removeClass(actives[currentTab][0], "highlighted");
+                    search_input.value = "";
                     defocusSearchBar();
                 } else if (actives[currentTab].length > 0) {
-                    removeClass(actives[currentTab][0], 'highlighted');
+                    removeClass(actives[currentTab][0], "highlighted");
                 }
             };
         }
@@ -1216,46 +1268,46 @@
             var type = itemTypes[item.ty];
             var name = item.name;
 
-            if (type === 'mod') {
-                displayPath = item.path + '::';
-                href = rootPath + item.path.replace(/::/g, '/') + '/' +
-                       name + '/index.html';
+            if (type === "mod") {
+                displayPath = item.path + "::";
+                href = rootPath + item.path.replace(/::/g, "/") + "/" +
+                       name + "/index.html";
             } else if (type === "primitive" || type === "keyword") {
                 displayPath = "";
-                href = rootPath + item.path.replace(/::/g, '/') +
-                       '/' + type + '.' + name + '.html';
+                href = rootPath + item.path.replace(/::/g, "/") +
+                       "/" + type + "." + name + ".html";
             } else if (type === "externcrate") {
                 displayPath = "";
-                href = rootPath + name + '/index.html';
+                href = rootPath + name + "/index.html";
             } else if (item.parent !== undefined) {
                 var myparent = item.parent;
-                var anchor = '#' + type + '.' + name;
+                var anchor = "#" + type + "." + name;
                 var parentType = itemTypes[myparent.ty];
                 if (parentType === "primitive") {
-                    displayPath = myparent.name + '::';
+                    displayPath = myparent.name + "::";
                 } else {
-                    displayPath = item.path + '::' + myparent.name + '::';
+                    displayPath = item.path + "::" + myparent.name + "::";
                 }
-                href = rootPath + item.path.replace(/::/g, '/') +
-                       '/' + parentType +
-                       '.' + myparent.name +
-                       '.html' + anchor;
+                href = rootPath + item.path.replace(/::/g, "/") +
+                       "/" + parentType +
+                       "." + myparent.name +
+                       ".html" + anchor;
             } else {
-                displayPath = item.path + '::';
-                href = rootPath + item.path.replace(/::/g, '/') +
-                       '/' + type + '.' + name + '.html';
+                displayPath = item.path + "::";
+                href = rootPath + item.path.replace(/::/g, "/") +
+                       "/" + type + "." + name + ".html";
             }
             return [displayPath, href];
         }
 
         function escape(content) {
-            var h1 = document.createElement('h1');
+            var h1 = document.createElement("h1");
             h1.textContent = content;
             return h1.innerHTML;
         }
 
         function pathSplitter(path) {
-            var tmp = '<span>' + path.replace(/::/g, '::</span><span>');
+            var tmp = "<span>" + path.replace(/::/g, "::</span><span>");
             if (tmp.endsWith("<span>")) {
                 return tmp.slice(0, tmp.length - 6);
             }
@@ -1263,16 +1315,16 @@
         }
 
         function addTab(array, query, display) {
-            var extraStyle = '';
+            var extraStyle = "";
             if (display === false) {
-                extraStyle = ' style="display: none;"';
+                extraStyle = " style=\"display: none;\"";
             }
 
-            var output = '';
+            var output = "";
             var duplicates = {};
             var length = 0;
             if (array.length > 0) {
-                output = '<table class="search-results"' + extraStyle + '>';
+                output = "<table class=\"search-results\"" + extraStyle + ">";
 
                 array.forEach(function(item) {
                     var name, type;
@@ -1288,50 +1340,50 @@
                     }
                     length += 1;
 
-                    output += '<tr class="' + type + ' result"><td>' +
-                              '<a href="' + item.href + '">' +
+                    output += "<tr class=\"" + type + " result\"><td>" +
+                              "<a href=\"" + item.href + "\">" +
                               (item.is_alias === true ?
-                               ('<span class="alias"><b>' + item.alias + ' </b></span><span ' +
-                                  'class="grey"><i>&nbsp;- see&nbsp;</i></span>') : '') +
-                              item.displayPath + '<span class="' + type + '">' +
-                              name + '</span></a></td><td>' +
-                              '<a href="' + item.href + '">' +
-                              '<span class="desc">' + escape(item.desc) +
-                              '&nbsp;</span></a></td></tr>';
+                               ("<span class=\"alias\"><b>" + item.alias + " </b></span><span " +
+                                  "class=\"grey\"><i>&nbsp;- see&nbsp;</i></span>") : "") +
+                              item.displayPath + "<span class=\"" + type + "\">" +
+                              name + "</span></a></td><td>" +
+                              "<a href=\"" + item.href + "\">" +
+                              "<span class=\"desc\">" + escape(item.desc) +
+                              "&nbsp;</span></a></td></tr>";
                 });
-                output += '</table>';
+                output += "</table>";
             } else {
-                output = '<div class="search-failed"' + extraStyle + '>No results :(<br/>' +
-                    'Try on <a href="https://duckduckgo.com/?q=' +
-                    encodeURIComponent('rust ' + query.query) +
-                    '">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>';
+                output = "<div class=\"search-failed\"" + extraStyle + ">No results :(<br/>" +
+                    "Try on <a href=\"https://duckduckgo.com/?q=" +
+                    encodeURIComponent("rust " + query.query) +
+                    "\">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];
         }
 
         function makeTabHeader(tabNb, text, nbElems) {
             if (currentTab === tabNb) {
-                return '<div class="selected">' + text +
-                       ' <div class="count">(' + nbElems + ')</div></div>';
+                return "<div class=\"selected\">" + text +
+                       " <div class=\"count\">(" + nbElems + ")</div></div>";
             }
-            return '<div>' + text + ' <div class="count">(' + nbElems + ')</div></div>';
+            return "<div>" + text + " <div class=\"count\">(" + nbElems + ")</div></div>";
         }
 
         function showResults(results) {
-            if (results['others'].length === 1 &&
-                getCurrentValue('rustdoc-go-to-only-result') === "true") {
-                var elem = document.createElement('a');
-                elem.href = results['others'][0].href;
-                elem.style.display = 'none';
+            if (results.others.length === 1 &&
+                getCurrentValue("rustdoc-go-to-only-result") === "true") {
+                var elem = document.createElement("a");
+                elem.href = results.others[0].href;
+                elem.style.display = "none";
                 // For firefox, we need the element to be in the DOM so it can be clicked.
                 document.body.appendChild(elem);
                 elem.click();
@@ -1340,114 +1392,123 @@
 
             currentResults = query.id;
 
-            var ret_others = addTab(results['others'], query);
-            var ret_in_args = addTab(results['in_args'], query, false);
-            var ret_returned = addTab(results['returned'], query, false);
+            var ret_others = addTab(results.others, query);
+            var ret_in_args = addTab(results.in_args, query, false);
+            var ret_returned = addTab(results.returned, query, false);
 
-            var output = '<h1>Results for ' + escape(query.query) +
-                (query.type ? ' (type: ' + escape(query.type) + ')' : '') + '</h1>' +
-                '<div id="titles">' +
+            var output = "<h1>Results for " + escape(query.query) +
+                (query.type ? " (type: " + escape(query.type) + ")" : "") + "</h1>" +
+                "<div id=\"titles\">" +
                 makeTabHeader(0, "In Names", ret_others[1]) +
                 makeTabHeader(1, "In Parameters", ret_in_args[1]) +
                 makeTabHeader(2, "In Return Types", ret_returned[1]) +
-                '</div><div id="results">' +
-                ret_others[0] + ret_in_args[0] + ret_returned[0] + '</div>';
+                "</div><div id=\"results\">" +
+                ret_others[0] + ret_in_args[0] + ret_returned[0] + "</div>";
 
-            addClass(document.getElementById('main'), 'hidden');
-            var search = document.getElementById('search');
-            removeClass(search, 'hidden');
+            addClass(main, "hidden");
+            var search = document.getElementById("search");
+            removeClass(search, "hidden");
             search.innerHTML = output;
-            var tds = search.getElementsByTagName('td');
+            var tds = search.getElementsByTagName("td");
             var td_width = 0;
             if (tds.length > 0) {
                 td_width = tds[0].offsetWidth;
             }
             var width = search.offsetWidth - 40 - td_width;
-            onEach(search.getElementsByClassName('desc'), function(e) {
-                e.style.width = width + 'px';
+            onEachLazy(search.getElementsByClassName("desc"), function(e) {
+                e.style.width = width + "px";
             });
             initSearchNav();
-            var elems = document.getElementById('titles').childNodes;
+            var elems = document.getElementById("titles").childNodes;
             elems[0].onclick = function() { printTab(0); };
             elems[1].onclick = function() { printTab(1); };
             elems[2].onclick = function() { printTab(2); };
             printTab(currentTab);
         }
 
-        function execSearch(query, searchWords) {
+        function execSearch(query, searchWords, filterCrates) {
+            function getSmallest(arrays, positions, notDuplicates) {
+                var start = null;
+
+                for (var it = 0; it < positions.length; ++it) {
+                    if (arrays[it].length > positions[it] &&
+                        (start === null || start > arrays[it][positions[it]].lev) &&
+                        !notDuplicates[arrays[it][positions[it]].fullPath]) {
+                        start = arrays[it][positions[it]].lev;
+                    }
+                }
+                return start;
+            }
+
+            function mergeArrays(arrays) {
+                var ret = [];
+                var positions = [];
+                var notDuplicates = {};
+
+                for (var x = 0; x < arrays.length; ++x) {
+                    positions.push(0);
+                }
+                while (ret.length < MAX_RESULTS) {
+                    var smallest = getSmallest(arrays, positions, notDuplicates);
+
+                    if (smallest === null) {
+                        break;
+                    }
+                    for (x = 0; x < arrays.length && ret.length < MAX_RESULTS; ++x) {
+                        if (arrays[x].length > positions[x] &&
+                                arrays[x][positions[x]].lev === smallest &&
+                                !notDuplicates[arrays[x][positions[x]].fullPath]) {
+                            ret.push(arrays[x][positions[x]]);
+                            notDuplicates[arrays[x][positions[x]].fullPath] = true;
+                            positions[x] += 1;
+                        }
+                    }
+                }
+                return ret;
+            }
+
             var queries = query.raw.split(",");
             var results = {
-                'in_args': [],
-                'returned': [],
-                'others': [],
+                "in_args": [],
+                "returned": [],
+                "others": [],
             };
 
             for (var i = 0; i < queries.length; ++i) {
-                var query = queries[i].trim();
+                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']);
-                    results['others'].push(tmp['others']);
+                    results.in_args.push(tmp.in_args);
+                    results.returned.push(tmp.returned);
+                    results.others.push(tmp.others);
                 }
             }
             if (queries.length > 1) {
-                function getSmallest(arrays, positions, notDuplicates) {
-                    var start = null;
-
-                    for (var it = 0; it < positions.length; ++it) {
-                        if (arrays[it].length > positions[it] &&
-                            (start === null || start > arrays[it][positions[it]].lev) &&
-                            !notDuplicates[arrays[it][positions[it]].fullPath]) {
-                            start = arrays[it][positions[it]].lev;
-                        }
-                    }
-                    return start;
-                }
-
-                function mergeArrays(arrays) {
-                    var ret = [];
-                    var positions = [];
-                    var notDuplicates = {};
-
-                    for (var x = 0; x < arrays.length; ++x) {
-                        positions.push(0);
-                    }
-                    while (ret.length < MAX_RESULTS) {
-                        var smallest = getSmallest(arrays, positions, notDuplicates);
-
-                        if (smallest === null) {
-                            break;
-                        }
-                        for (x = 0; x < arrays.length && ret.length < MAX_RESULTS; ++x) {
-                            if (arrays[x].length > positions[x] &&
-                                    arrays[x][positions[x]].lev === smallest &&
-                                    !notDuplicates[arrays[x][positions[x]].fullPath]) {
-                                ret.push(arrays[x][positions[x]]);
-                                notDuplicates[arrays[x][positions[x]].fullPath] = true;
-                                positions[x] += 1;
-                            }
-                        }
-                    }
-                    return ret;
-                }
-
                 return {
-                    'in_args': mergeArrays(results['in_args']),
-                    'returned': mergeArrays(results['returned']),
-                    'others': mergeArrays(results['others']),
+                    "in_args": mergeArrays(results.in_args),
+                    "returned": mergeArrays(results.returned),
+                    "others": mergeArrays(results.others),
                 };
             } else {
                 return {
-                    'in_args': results['in_args'][0],
-                    'returned': results['returned'][0],
-                    'others': results['others'][0],
+                    "in_args": results.in_args[0],
+                    "returned": results.returned[0],
+                    "others": results.others[0],
                 };
             }
         }
 
-        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());
 
@@ -1455,7 +1516,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);
                 }
@@ -1475,12 +1539,15 @@
                 }
             }
 
-            showResults(execSearch(query, index));
+            var filterCrates = getFilterCrates();
+            showResults(execSearch(query, index, filterCrates), filterCrates);
         }
 
         function buildIndex(rawSearchIndex) {
             searchIndex = [];
             var searchWords = [];
+            var i;
+
             for (var crate in rawSearchIndex) {
                 if (!rawSearchIndex.hasOwnProperty(crate)) { continue; }
 
@@ -1507,7 +1574,7 @@
 
                 // convert `paths` into an object form
                 var len = paths.length;
-                for (var i = 0; i < len; ++i) {
+                for (i = 0; i < len; ++i) {
                     paths[i] = {ty: paths[i][0], name: paths[i][1]};
                 }
 
@@ -1518,9 +1585,9 @@
                 // operation that is cached for the life of the page state so that
                 // all other search operations have access to this cached data for
                 // faster analysis operations
-                var len = items.length;
+                len = items.length;
                 var lastPath = "";
-                for (var i = 0; i < len; ++i) {
+                for (i = 0; i < len; ++i) {
                     var rawRow = items[i];
                     var row = {crate: crate, ty: rawRow[0], name: rawRow[1],
                                path: rawRow[2] || lastPath, desc: rawRow[3],
@@ -1546,13 +1613,12 @@
                     if (browserSupportsHistoryApi()) {
                         history.replaceState("", "std - Rust", "?search=");
                     }
-                    var main = document.getElementById('main');
-                    if (hasClass(main, 'content')) {
-                        removeClass(main, 'hidden');
+                    if (hasClass(main, "content")) {
+                        removeClass(main, "hidden");
                     }
-                    var search_c = document.getElementById('search');
-                    if (hasClass(search_c, 'content')) {
-                        addClass(search_c, 'hidden');
+                    var search_c = document.getElementById("search");
+                    if (hasClass(search_c, "content")) {
+                        addClass(search_c, "hidden");
                     }
                 } else {
                     searchTimeout = setTimeout(search, 500);
@@ -1575,6 +1641,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()) {
@@ -1586,13 +1659,12 @@
                     // When browsing back from search results the main page
                     // visibility must be reset.
                     if (!params.search) {
-                        var main = document.getElementById('main');
-                        if (hasClass(main, 'content')) {
-                            removeClass(main, 'hidden');
+                        if (hasClass(main, "content")) {
+                            removeClass(main, "hidden");
                         }
-                        var search_c = document.getElementById('search');
-                        if (hasClass(search_c, 'content')) {
-                            addClass(search_c, 'hidden');
+                        var search_c = document.getElementById("search");
+                        if (hasClass(search_c, "content")) {
+                            addClass(search_c, "hidden");
                         }
                     }
                     // Revert to the previous title manually since the History
@@ -1609,9 +1681,9 @@
                     if (params.search) {
                         search_input.value = params.search;
                     } else {
-                        search_input.value = '';
+                        search_input.value = "";
                     }
-                    // Some browsers fire 'onpopstate' for every page load
+                    // Some browsers fire "onpopstate" for every page load
                     // (Chrome), while others fire the event only when actually
                     // popping a state (Firefox), which is why search() is
                     // called both here and at the end of the startSearch()
@@ -1626,13 +1698,13 @@
         startSearch();
 
         // Draw a convenient sidebar of known crates if we have a listing
-        if (rootPath === '../' || rootPath === "./") {
-            var sidebar = document.getElementsByClassName('sidebar-elems')[0];
+        if (rootPath === "../" || rootPath === "./") {
+            var sidebar = document.getElementsByClassName("sidebar-elems")[0];
             if (sidebar) {
-                var div = document.createElement('div');
-                div.className = 'block crate';
-                div.innerHTML = '<h3>Crates</h3>';
-                var ul = document.createElement('ul');
+                var div = document.createElement("div");
+                div.className = "block crate";
+                div.innerHTML = "<h3>Crates</h3>";
+                var ul = document.createElement("ul");
                 div.appendChild(ul);
 
                 var crates = [];
@@ -1644,17 +1716,17 @@
                 }
                 crates.sort();
                 for (var i = 0; i < crates.length; ++i) {
-                    var klass = 'crate';
+                    var klass = "crate";
                     if (rootPath !== "./" && crates[i] === window.currentCrate) {
-                        klass += ' current';
+                        klass += " current";
                     }
-                    var link = document.createElement('a');
-                    link.href = rootPath + crates[i] + '/index.html';
+                    var link = document.createElement("a");
+                    link.href = rootPath + crates[i] + "/index.html";
                     link.title = rawSearchIndex[crates[i]].doc;
                     link.className = klass;
                     link.textContent = crates[i];
 
-                    var li = document.createElement('li');
+                    var li = document.createElement("li");
                     li.appendChild(link);
                     ul.appendChild(li);
                 }
@@ -1667,41 +1739,44 @@
 
     // delayed sidebar rendering.
     function initSidebarItems(items) {
-        var sidebar = document.getElementsByClassName('sidebar-elems')[0];
+        var sidebar = document.getElementsByClassName("sidebar-elems")[0];
         var current = window.sidebarCurrent;
 
         function block(shortty, longty) {
             var filtered = items[shortty];
-            if (!filtered) { return; }
+            if (!filtered) {
+                return;
+            }
 
-            var div = document.createElement('div');
-            div.className = 'block ' + shortty;
-            var h3 = document.createElement('h3');
+            var div = document.createElement("div");
+            div.className = "block " + shortty;
+            var h3 = document.createElement("h3");
             h3.textContent = longty;
             div.appendChild(h3);
-            var ul = document.createElement('ul');
+            var ul = document.createElement("ul");
 
-            for (var i = 0; i < filtered.length; ++i) {
+            var length = filtered.length;
+            for (var i = 0; i < length; ++i) {
                 var item = filtered[i];
                 var name = item[0];
                 var desc = item[1]; // can be null
 
                 var klass = shortty;
                 if (name === current.name && shortty === current.ty) {
-                    klass += ' current';
+                    klass += " current";
                 }
                 var path;
-                if (shortty === 'mod') {
-                    path = name + '/index.html';
+                if (shortty === "mod") {
+                    path = name + "/index.html";
                 } else {
-                    path = shortty + '.' + name + '.html';
+                    path = shortty + "." + name + ".html";
                 }
-                var link = document.createElement('a');
+                var link = document.createElement("a");
                 link.href = current.relpath + path;
                 link.title = desc;
                 link.className = klass;
                 link.textContent = name;
-                var li = document.createElement('li');
+                var li = document.createElement("li");
                 li.appendChild(link);
                 ul.appendChild(li);
             }
@@ -1729,22 +1804,25 @@
     window.initSidebarItems = initSidebarItems;
 
     window.register_implementors = function(imp) {
-        var implementors = document.getElementById('implementors-list');
-        var synthetic_implementors = document.getElementById('synthetic-implementors-list');
+        var implementors = document.getElementById("implementors-list");
+        var synthetic_implementors = document.getElementById("synthetic-implementors-list");
 
         var libs = Object.getOwnPropertyNames(imp);
-        for (var i = 0; i < libs.length; ++i) {
+        var llength = libs.length;
+        for (var i = 0; i < llength; ++i) {
             if (libs[i] === currentCrate) { continue; }
             var structs = imp[libs[i]];
 
+            var slength = structs.length;
             struct_loop:
-            for (var j = 0; j < structs.length; ++j) {
+            for (var j = 0; j < slength; ++j) {
                 var struct = structs[j];
 
                 var list = struct.synthetic ? synthetic_implementors : implementors;
 
                 if (struct.synthetic) {
-                    for (var k = 0; k < struct.types.length; k++) {
+                    var stlength = struct.types.length;
+                    for (var k = 0; k < stlength; k++) {
                         if (window.inlined_types.has(struct.types[k])) {
                             continue struct_loop;
                         }
@@ -1752,21 +1830,22 @@
                     }
                 }
 
-                var code = document.createElement('code');
+                var code = document.createElement("code");
                 code.innerHTML = struct.text;
 
-                var x = code.getElementsByTagName('a');
-                for (var k = 0; k < x.length; k++) {
-                    var href = x[k].getAttribute('href');
-                    if (href && href.indexOf('http') !== 0) {
-                        x[k].setAttribute('href', rootPath + href);
+                var x = code.getElementsByTagName("a");
+                var xlength = x.length;
+                for (var it = 0; it < xlength; it++) {
+                    var href = x[it].getAttribute("href");
+                    if (href && href.indexOf("http") !== 0) {
+                        x[it].setAttribute("href", rootPath + href);
                     }
                 }
-                var display = document.createElement('h3');
+                var display = document.createElement("h3");
                 addClass(display, "impl");
-                display.innerHTML = '<span class="in-band"><table class="table-display"><tbody>\
-                    <tr><td><code>' + code.outerHTML + '</code></td><td></td></tr></tbody></table>\
-                    </span>';
+                display.innerHTML = "<span class=\"in-band\"><table class=\"table-display\">" +
+                    "<tbody><tr><td><code>" + code.outerHTML + "</code></td><td></td></tr>" +
+                    "</tbody></table></span>";
                 list.appendChild(display);
             }
         }
@@ -1782,47 +1861,49 @@
         }
         // button will collapse the section
         // note that this text is also set in the HTML template in render.rs
-        return "\u2212"; // "\u2212" is '−' minus sign
+        return "\u2212"; // "\u2212" is "−" minus sign
     }
 
     function onEveryMatchingChild(elem, className, func) {
         if (elem && className && func) {
-            for (var i = 0; i < elem.childNodes.length; i++) {
-                if (hasClass(elem.childNodes[i], className)) {
-                    func(elem.childNodes[i]);
+            var length = elem.childNodes.length;
+            var nodes = elem.childNodes;
+            for (var i = 0; i < length; ++i) {
+                if (hasClass(nodes[i], className)) {
+                    func(nodes[i]);
                 } else {
-                    onEveryMatchingChild(elem.childNodes[i], className, func);
+                    onEveryMatchingChild(nodes[i], className, func);
                 }
             }
         }
     }
 
     function toggleAllDocs(pageId, fromAutoCollapse) {
-        var toggle = document.getElementById("toggle-all-docs");
-        if (!toggle) {
+        var innerToggle = document.getElementById("toggle-all-docs");
+        if (!innerToggle) {
             return;
         }
-        if (hasClass(toggle, "will-expand")) {
+        if (hasClass(innerToggle, "will-expand")) {
             updateLocalStorage("rustdoc-collapse", "false");
-            removeClass(toggle, "will-expand");
-            onEveryMatchingChild(toggle, "inner", function(e) {
+            removeClass(innerToggle, "will-expand");
+            onEveryMatchingChild(innerToggle, "inner", function(e) {
                 e.innerHTML = labelForToggleButton(false);
             });
-            toggle.title = "collapse all docs";
+            innerToggle.title = "collapse all docs";
             if (fromAutoCollapse !== true) {
-                onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
+                onEachLazy(document.getElementsByClassName("collapse-toggle"), function(e) {
                     collapseDocs(e, "show");
                 });
             }
         } else {
             updateLocalStorage("rustdoc-collapse", "true");
-            addClass(toggle, "will-expand");
-            onEveryMatchingChild(toggle, "inner", function(e) {
+            addClass(innerToggle, "will-expand");
+            onEveryMatchingChild(innerToggle, "inner", function(e) {
                 e.innerHTML = labelForToggleButton(true);
             });
-            toggle.title = "expand all docs";
+            innerToggle.title = "expand all docs";
             if (fromAutoCollapse !== true) {
-                onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
+                onEachLazy(document.getElementsByClassName("collapse-toggle"), function(e) {
                     collapseDocs(e, "hide", pageId);
                 });
             }
@@ -1836,27 +1917,58 @@
 
         function adjustToggle(arg) {
             return function(e) {
-                if (hasClass(e, 'toggle-label')) {
+                if (hasClass(e, "toggle-label")) {
                     if (arg) {
-                        e.style.display = 'inline-block';
+                        e.style.display = "inline-block";
                     } else {
-                        e.style.display = 'none';
+                        e.style.display = "none";
                     }
                 }
-                if (hasClass(e, 'inner')) {
+                if (hasClass(e, "inner")) {
                     e.innerHTML = labelForToggleButton(arg);
                 }
             };
-        };
+        }
 
-        if (!hasClass(toggle.parentNode, "impl")) {
-            var relatedDoc = toggle.parentNode.nextElementSibling;
+        function implHider(addOrRemove) {
+            return function(n) {
+                var is_method = hasClass(n, "method");
+                if (is_method || hasClass(n, "type")) {
+                    if (is_method === true) {
+                        if (addOrRemove) {
+                            addClass(n, "hidden-by-impl-hider");
+                        } else {
+                            removeClass(n, "hidden-by-impl-hider");
+                        }
+                    }
+                    var ns = n.nextElementSibling;
+                    while (true) {
+                        if (ns && (
+                                hasClass(ns, "docblock") ||
+                                hasClass(ns, "stability"))) {
+                            if (addOrRemove) {
+                                addClass(ns, "hidden-by-impl-hider");
+                            } else {
+                                removeClass(ns, "hidden-by-impl-hider");
+                            }
+                            ns = ns.nextElementSibling;
+                            continue;
+                        }
+                        break;
+                    }
+                }
+            };
+        }
+
+        var relatedDoc;
+        var action = mode;
+        if (hasClass(toggle.parentNode, "impl") === false) {
+            relatedDoc = toggle.parentNode.nextElementSibling;
             if (hasClass(relatedDoc, "stability")) {
                 relatedDoc = relatedDoc.nextElementSibling;
             }
             if (hasClass(relatedDoc, "docblock") || hasClass(relatedDoc, "sub-variant")) {
-                var action = mode;
-                if (action === "toggle") {
+                if (mode === "toggle") {
                     if (hasClass(relatedDoc, "hidden-by-usual-hider")) {
                         action = "show";
                     } else {
@@ -1865,67 +1977,35 @@
                 }
                 if (action === "hide") {
                     addClass(relatedDoc, "hidden-by-usual-hider");
-                    onEach(toggle.childNodes, adjustToggle(true));
-                    addClass(toggle.parentNode, 'collapsed');
+                    onEachLazy(toggle.childNodes, adjustToggle(true));
+                    addClass(toggle.parentNode, "collapsed");
                 } else if (action === "show") {
                     removeClass(relatedDoc, "hidden-by-usual-hider");
-                    removeClass(toggle.parentNode, 'collapsed');
-                    onEach(toggle.childNodes, adjustToggle(false));
+                    removeClass(toggle.parentNode, "collapsed");
+                    onEachLazy(toggle.childNodes, adjustToggle(false));
                 }
             }
         } else {
             // we are collapsing the impl block
-            function implHider(addOrRemove) {
-                return function(n) {
-                    var is_method = hasClass(n, "method");
-                    if (is_method || hasClass(n, "type")) {
-                        if (is_method === true) {
-                            if (addOrRemove) {
-                                addClass(n, "hidden-by-impl-hider");
-                            } else {
-                                removeClass(n, "hidden-by-impl-hider");
-                            }
-                        }
-                        var ns = n.nextElementSibling;
-                        while (true) {
-                            if (ns && (
-                                    hasClass(ns, "docblock") ||
-                                    hasClass(ns, "stability"))) {
-                                if (addOrRemove) {
-                                    addClass(ns, "hidden-by-impl-hider");
-                                } else {
-                                    removeClass(ns, "hidden-by-impl-hider");
-                                }
-                                ns = ns.nextElementSibling;
-                                continue;
-                            }
-                            break;
-                        }
-                    }
-                }
-            }
 
             var parentElem = toggle.parentNode;
-            var relatedDoc = parentElem;
+            relatedDoc = parentElem;
             var docblock = relatedDoc.nextElementSibling;
 
-            while (!hasClass(relatedDoc, "impl-items")) {
+            while (hasClass(relatedDoc, "impl-items") === false) {
                 relatedDoc = relatedDoc.nextElementSibling;
             }
 
-            if ((!relatedDoc && !hasClass(docblock, "docblock")) ||
-                (pageId && onEach(relatedDoc.childNodes, function(e) {
-                    return e.id === pageId;
-                }) === true)) {
+            if ((!relatedDoc && hasClass(docblock, "docblock") === false) ||
+                (pageId && document.getElementById(pageId))) {
                 return;
             }
 
             // Hide all functions, but not associated types/consts
 
-            var action = mode;
-            if (action === "toggle") {
+            if (mode === "toggle") {
                 if (hasClass(relatedDoc, "fns-now-collapsed") ||
-                    hasClass(docblock,  "hidden-by-impl-hider")) {
+                    hasClass(docblock, "hidden-by-impl-hider")) {
                     action = "show";
                 } else {
                     action = "hide";
@@ -1935,13 +2015,25 @@
             if (action === "show") {
                 removeClass(relatedDoc, "fns-now-collapsed");
                 removeClass(docblock, "hidden-by-usual-hider");
-                onEach(toggle.childNodes, adjustToggle(false));
-                onEach(relatedDoc.childNodes, implHider(false));
+                onEachLazy(toggle.childNodes, adjustToggle(false));
+                onEachLazy(relatedDoc.childNodes, implHider(false));
             } else if (action === "hide") {
                 addClass(relatedDoc, "fns-now-collapsed");
                 addClass(docblock, "hidden-by-usual-hider");
-                onEach(toggle.childNodes, adjustToggle(true));
-                onEach(relatedDoc.childNodes, implHider(true));
+                onEachLazy(toggle.childNodes, adjustToggle(true));
+                onEachLazy(relatedDoc.childNodes, implHider(true));
+            }
+        }
+    }
+
+    function collapser(e, collapse) {
+        // inherent impl ids are like "impl" or impl-<number>'.
+        // they will never be hidden by default.
+        var n = e.parentElement;
+        if (n.id.match(/^impl(?:-\d+)?$/) === null) {
+            // Automatically minimize all non-inherent impls
+            if (collapse || hasClass(n, "impl")) {
+                collapseDocs(e, "hide", pageId);
             }
         }
     }
@@ -1949,88 +2041,112 @@
     function autoCollapse(pageId, collapse) {
         if (collapse) {
             toggleAllDocs(pageId, true);
-        }
-        var collapser = function(e) {
-                // inherent impl ids are like 'impl' or impl-<number>'.
-                // they will never be hidden by default.
-                var n = e.parentElement;
-                if (n.id.match(/^impl(?:-\d+)?$/) === null) {
-                    // Automatically minimize all non-inherent impls
-                    if (collapse || hasClass(n, 'impl')) {
-                        collapseDocs(e, "hide", pageId);
-                    }
-                }
-        };
-        if (getCurrentValue('rustdoc-trait-implementations') !== "false") {
-            var impl_list = document.getElementById('implementations-list');
+        } else if (getCurrentValue("rustdoc-trait-implementations") !== "false") {
+            var impl_list = document.getElementById("implementations-list");
 
             if (impl_list !== null) {
-                onEach(impl_list.getElementsByClassName("collapse-toggle"), collapser);
-            }
-        }
-        if (getCurrentValue('rustdoc-method-docs') !== "false") {
-            var implItems = document.getElementsByClassName('impl-items');
-
-            if (implItems && implItems.length > 0) {
-                onEach(implItems, function(elem) {
-                    onEach(elem.getElementsByClassName("collapse-toggle"), collapser);
+                onEachLazy(impl_list.getElementsByClassName("collapse-toggle"), function(e) {
+                    collapser(e, collapse);
                 });
             }
         }
     }
 
-    var x = document.getElementById('toggle-all-docs');
-    if (x) {
-        x.onclick = toggleAllDocs;
+    var toggles = document.getElementById("toggle-all-docs");
+    if (toggles) {
+        toggles.onclick = toggleAllDocs;
     }
 
     function insertAfter(newNode, referenceNode) {
         referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
     }
 
-    function checkIfThereAreMethods(elems) {
-        var areThereMethods = false;
-
-        onEach(elems, function(e) {
-            if (hasClass(e, "method")) {
-                areThereMethods = true;
-                return true;
-            }
-        });
-        return areThereMethods;
+    function createSimpleToggle(sectionIsCollapsed) {
+        var toggle = document.createElement("a");
+        toggle.href = "javascript:void(0)";
+        toggle.className = "collapse-toggle";
+        toggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(sectionIsCollapsed) +
+                           "</span>]";
+        return toggle;
     }
 
-    var toggle = document.createElement('a');
-    toggle.href = 'javascript:void(0)';
-    toggle.className = 'collapse-toggle';
-    toggle.innerHTML = "[<span class='inner'>" + labelForToggleButton(false) + "</span>]";
+    var toggle = createSimpleToggle(false);
 
     var func = function(e) {
         var next = e.nextElementSibling;
-        if (hasClass(e, 'impl') && next && hasClass(next, 'docblock')) {
+        if (!next) {
+            return;
+        }
+        if (hasClass(next, "docblock") ||
+            (hasClass(next, "stability") &&
+             hasClass(next.nextElementSibling, "docblock"))) {
+            insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
+        }
+    };
+
+    var funcImpl = function(e) {
+        var next = e.nextElementSibling;
+        if (next && hasClass(next, "docblock")) {
             next = next.nextElementSibling;
         }
         if (!next) {
             return;
         }
-        if ((hasClass(e, 'method') || hasClass(e, 'associatedconstant') ||
-             checkIfThereAreMethods(next.childNodes)) &&
-            (hasClass(next, 'docblock') ||
-             hasClass(e, 'impl') ||
-             (hasClass(next, 'stability') &&
-              hasClass(next.nextElementSibling, 'docblock')))) {
+        if (next.getElementsByClassName("method").length > 0 && hasClass(e, "impl")) {
             insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
         }
     };
-    onEach(document.getElementsByClassName('method'), func);
-    onEach(document.getElementsByClassName('associatedconstant'), func);
-    onEach(document.getElementsByClassName('impl'), func);
-    onEach(document.getElementsByClassName('impl-items'), function(e) {
-        onEach(e.getElementsByClassName('associatedconstant'), func);
-        var hiddenElems = e.getElementsByClassName('hidden');
+
+    onEachLazy(document.getElementsByClassName("method"), func);
+    onEachLazy(document.getElementsByClassName("associatedconstant"), func);
+    onEachLazy(document.getElementsByClassName("impl"), funcImpl);
+    var impl_call = function() {};
+    if (getCurrentValue("rustdoc-method-docs") !== "false") {
+        impl_call = function(e, newToggle, pageId) {
+            if (e.id.match(/^impl(?:-\d+)?$/) === null) {
+                // Automatically minimize all non-inherent impls
+                if (hasClass(e, "impl")) {
+                    collapseDocs(newToggle, "hide", pageId);
+                }
+            }
+        };
+    }
+    var pageId = getPageId();
+    var newToggle = document.createElement("a");
+    newToggle.href = "javascript:void(0)";
+    newToggle.className = "collapse-toggle hidden-default collapsed";
+    newToggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
+                          "</span>] Show hidden undocumented items";
+    function toggleClicked() {
+        if (hasClass(this, "collapsed")) {
+            removeClass(this, "collapsed");
+            onEachLazy(this.parentNode.getElementsByClassName("hidden"), function(x) {
+                if (hasClass(x, "content") === false) {
+                    removeClass(x, "hidden");
+                    addClass(x, "x");
+                }
+            }, true);
+            this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(false) +
+                             "</span>] Hide undocumented items";
+        } else {
+            addClass(this, "collapsed");
+            onEachLazy(this.parentNode.getElementsByClassName("x"), function(x) {
+                if (hasClass(x, "content") === false) {
+                    addClass(x, "hidden");
+                    removeClass(x, "x");
+                }
+            }, true);
+            this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
+                             "</span>] Show hidden undocumented items";
+        }
+    }
+    onEachLazy(document.getElementsByClassName("impl-items"), function(e) {
+        onEachLazy(e.getElementsByClassName("associatedconstant"), func);
+        var hiddenElems = e.getElementsByClassName("hidden");
         var needToggle = false;
 
-        for (var i = 0; i < hiddenElems.length; ++i) {
+        var hlength = hiddenElems.length;
+        for (var i = 0; i < hlength; ++i) {
             if (hasClass(hiddenElems[i], "content") === false &&
                 hasClass(hiddenElems[i], "docblock") === false) {
                 needToggle = true;
@@ -2038,46 +2154,21 @@
             }
         }
         if (needToggle === true) {
-            var newToggle = document.createElement('a');
-            newToggle.href = 'javascript:void(0)';
-            newToggle.className = 'collapse-toggle hidden-default collapsed';
-            newToggle.innerHTML = "[<span class='inner'>" + labelForToggleButton(true) + "</span>" +
-                                  "] Show hidden undocumented items";
-            newToggle.onclick = function() {
-                if (hasClass(this, "collapsed")) {
-                    removeClass(this, "collapsed");
-                    onEach(this.parentNode.getElementsByClassName("hidden"), function(x) {
-                        if (hasClass(x, "content") === false) {
-                            removeClass(x, "hidden");
-                            addClass(x, "x");
-                        }
-                    }, true);
-                    this.innerHTML = "[<span class='inner'>" + labelForToggleButton(false) +
-                                     "</span>] Hide undocumented items"
-                } else {
-                    addClass(this, "collapsed");
-                    onEach(this.parentNode.getElementsByClassName("x"), function(x) {
-                        if (hasClass(x, "content") === false) {
-                            addClass(x, "hidden");
-                            removeClass(x, "x");
-                        }
-                    }, true);
-                    this.innerHTML = "[<span class='inner'>" + labelForToggleButton(true) +
-                                     "</span>] Show hidden undocumented items";
-                }
-            };
-            e.insertBefore(newToggle, e.firstChild);
+            var inner_toggle = newToggle.cloneNode(true);
+            inner_toggle.onclick = toggleClicked;
+            e.insertBefore(inner_toggle, e.firstChild);
+            impl_call(e, inner_toggle, pageId);
         }
     });
 
     function createToggle(otherMessage, fontSize, extraClass, show) {
-        var span = document.createElement('span');
-        span.className = 'toggle-label';
+        var span = document.createElement("span");
+        span.className = "toggle-label";
         if (show) {
-            span.style.display = 'none';
+            span.style.display = "none";
         }
         if (!otherMessage) {
-            span.innerHTML = '&nbsp;Expand&nbsp;description';
+            span.innerHTML = "&nbsp;Expand&nbsp;description";
         } else {
             span.innerHTML = otherMessage;
         }
@@ -2089,13 +2180,13 @@
         var mainToggle = toggle.cloneNode(true);
         mainToggle.appendChild(span);
 
-        var wrapper = document.createElement('div');
-        wrapper.className = 'toggle-wrapper';
+        var wrapper = document.createElement("div");
+        wrapper.className = "toggle-wrapper";
         if (!show) {
-            addClass(wrapper, 'collapsed');
-            var inner = mainToggle.getElementsByClassName('inner');
+            addClass(wrapper, "collapsed");
+            var inner = mainToggle.getElementsByClassName("inner");
             if (inner && inner.length > 0) {
-                inner[0].innerHTML = '+';
+                inner[0].innerHTML = "+";
             }
         }
         if (extraClass) {
@@ -2105,21 +2196,21 @@
         return wrapper;
     }
 
-    var showItemDeclarations = getCurrentValue('rustdoc-item-declarations') === "false";
+    var showItemDeclarations = getCurrentValue("rustdoc-item-declarations") === "false";
     function buildToggleWrapper(e) {
-        if (hasClass(e, 'autohide')) {
+        if (hasClass(e, "autohide")) {
             var wrap = e.previousElementSibling;
-            if (wrap && hasClass(wrap, 'toggle-wrapper')) {
-                var toggle = wrap.childNodes[0];
-                var extra = e.childNodes[0].tagName === 'H3';
+            if (wrap && hasClass(wrap, "toggle-wrapper")) {
+                var inner_toggle = wrap.childNodes[0];
+                var extra = e.childNodes[0].tagName === "H3";
 
-                e.style.display = 'none';
-                addClass(wrap, 'collapsed');
-                onEach(toggle.getElementsByClassName('inner'), function(e) {
+                e.style.display = "none";
+                addClass(wrap, "collapsed");
+                onEachLazy(inner_toggle.getElementsByClassName("inner"), function(e) {
                     e.innerHTML = labelForToggleButton(true);
                 });
-                onEach(toggle.getElementsByClassName('toggle-label'), function(e) {
-                    e.style.display = 'inline-block';
+                onEachLazy(inner_toggle.getElementsByClassName("toggle-label"), function(e) {
+                    e.style.display = "inline-block";
                     if (extra === true) {
                         i_e.innerHTML = " Show " + e.childNodes[0].innerHTML;
                     }
@@ -2127,28 +2218,28 @@
             }
         }
         if (e.parentNode.id === "main") {
-            var otherMessage = '';
+            var otherMessage = "";
             var fontSize;
             var extraClass;
 
             if (hasClass(e, "type-decl")) {
                 fontSize = "20px";
-                otherMessage = '&nbsp;Show&nbsp;declaration';
+                otherMessage = "&nbsp;Show&nbsp;declaration";
                 if (showItemDeclarations === false) {
-                    extraClass = 'collapsed';
+                    extraClass = "collapsed";
                 }
             } else if (hasClass(e, "sub-variant")) {
-                otherMessage = '&nbsp;Show&nbsp;fields';
+                otherMessage = "&nbsp;Show&nbsp;fields";
             } else if (hasClass(e, "non-exhaustive")) {
-                otherMessage = '&nbsp;This&nbsp;';
+                otherMessage = "&nbsp;This&nbsp;";
                 if (hasClass(e, "non-exhaustive-struct")) {
-                    otherMessage += 'struct';
+                    otherMessage += "struct";
                 } else if (hasClass(e, "non-exhaustive-enum")) {
-                    otherMessage += 'enum';
+                    otherMessage += "enum";
                 } else if (hasClass(e, "non-exhaustive-type")) {
-                    otherMessage += 'type';
+                    otherMessage += "type";
                 }
-                otherMessage += '&nbsp;is&nbsp;marked&nbsp;as&nbsp;non-exhaustive';
+                otherMessage += "&nbsp;is&nbsp;marked&nbsp;as&nbsp;non-exhaustive";
             } else if (hasClass(e.childNodes[0], "impl-items")) {
                 extraClass = "marg-left";
             }
@@ -2165,21 +2256,8 @@
         }
     }
 
-    onEach(document.getElementsByClassName('docblock'), buildToggleWrapper);
-    onEach(document.getElementsByClassName('sub-variant'), buildToggleWrapper);
-
-    function createToggleWrapper(tog) {
-        var span = document.createElement('span');
-        span.className = 'toggle-label';
-        span.style.display = 'none';
-        span.innerHTML = '&nbsp;Expand&nbsp;attributes';
-        tog.appendChild(span);
-
-        var wrapper = document.createElement('div');
-        wrapper.className = 'toggle-wrapper toggle-attributes';
-        wrapper.appendChild(tog);
-        return wrapper;
-    }
+    onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper);
+    onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
 
     // In the search display, allows to switch between tabs.
     function printTab(nb) {
@@ -2187,24 +2265,37 @@
             currentTab = nb;
         }
         var nb_copy = nb;
-        onEach(document.getElementById('titles').childNodes, function(elem) {
+        onEachLazy(document.getElementById("titles").childNodes, function(elem) {
             if (nb_copy === 0) {
-                addClass(elem, 'selected');
+                addClass(elem, "selected");
             } else {
-                removeClass(elem, 'selected');
+                removeClass(elem, "selected");
             }
             nb_copy -= 1;
         });
-        onEach(document.getElementById('results').childNodes, function(elem) {
+        onEachLazy(document.getElementById("results").childNodes, function(elem) {
             if (nb === 0) {
-                elem.style.display = '';
+                elem.style.display = "";
             } else {
-                elem.style.display = 'none';
+                elem.style.display = "none";
             }
             nb -= 1;
         });
     }
 
+    function createToggleWrapper(tog) {
+        var span = document.createElement("span");
+        span.className = "toggle-label";
+        span.style.display = "none";
+        span.innerHTML = "&nbsp;Expand&nbsp;attributes";
+        tog.appendChild(span);
+
+        var wrapper = document.createElement("div");
+        wrapper.className = "toggle-wrapper toggle-attributes";
+        wrapper.appendChild(tog);
+        return wrapper;
+    }
+
     // To avoid checking on "rustdoc-item-attributes" value on every loop...
     var itemAttributesFunc = function() {};
     if (getCurrentValue("rustdoc-item-attributes") !== "false") {
@@ -2212,8 +2303,9 @@
             collapseDocs(x.previousSibling.childNodes[0], "toggle");
         };
     }
-    onEach(document.getElementById('main').getElementsByClassName('attributes'), function(i_e) {
-        i_e.parentNode.insertBefore(createToggleWrapper(toggle.cloneNode(true)), i_e);
+    var attributesToggle = createToggleWrapper(createSimpleToggle(false));
+    onEachLazy(main.getElementsByClassName("attributes"), function(i_e) {
+        i_e.parentNode.insertBefore(attributesToggle.cloneNode(true), i_e);
         itemAttributesFunc(i_e);
     });
 
@@ -2221,45 +2313,45 @@
     var lineNumbersFunc = function() {};
     if (getCurrentValue("rustdoc-line-numbers") === "true") {
         lineNumbersFunc = function(x) {
-            var count = x.textContent.split('\n').length;
+            var count = x.textContent.split("\n").length;
             var elems = [];
             for (var i = 0; i < count; ++i) {
                 elems.push(i + 1);
             }
-            var node = document.createElement('pre');
-            addClass(node, 'line-number');
-            node.innerHTML = elems.join('\n');
+            var node = document.createElement("pre");
+            addClass(node, "line-number");
+            node.innerHTML = elems.join("\n");
             x.parentNode.insertBefore(node, x);
         };
     }
-    onEach(document.getElementsByClassName('rust-example-rendered'), function(e) {
-        if (hasClass(e, 'compile_fail')) {
+    onEachLazy(document.getElementsByClassName("rust-example-rendered"), function(e) {
+        if (hasClass(e, "compile_fail")) {
             e.addEventListener("mouseover", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = '#f00';
+                this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00";
             });
             e.addEventListener("mouseout", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = '';
+                this.parentElement.previousElementSibling.childNodes[0].style.color = "";
             });
-        } else if (hasClass(e, 'ignore')) {
+        } else if (hasClass(e, "ignore")) {
             e.addEventListener("mouseover", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = '#ff9200';
+                this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200";
             });
             e.addEventListener("mouseout", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = '';
+                this.parentElement.previousElementSibling.childNodes[0].style.color = "";
             });
         }
         lineNumbersFunc(e);
     });
 
     function showModal(content) {
-        var modal = document.createElement('div');
+        var modal = document.createElement("div");
         modal.id = "important";
-        addClass(modal, 'modal');
-        modal.innerHTML = '<div class="modal-content"><div class="close" id="modal-close">✕</div>' +
-                          '<div class="whiter"></div><span class="docblock">' + content +
-                          '</span></div>';
-        document.getElementsByTagName('body')[0].appendChild(modal);
-        document.getElementById('modal-close').onclick = hideModal;
+        addClass(modal, "modal");
+        modal.innerHTML = "<div class=\"modal-content\"><div class=\"close\" id=\"modal-close\">✕" +
+                          "</div><div class=\"whiter\"></div><span class=\"docblock\">" + content +
+                          "</span></div>";
+        document.getElementsByTagName("body")[0].appendChild(modal);
+        document.getElementById("modal-close").onclick = hideModal;
         modal.onclick = hideModal;
     }
 
@@ -2270,7 +2362,7 @@
         }
     }
 
-    onEach(document.getElementsByClassName('important-traits'), function(e) {
+    onEachLazy(document.getElementsByClassName("important-traits"), function(e) {
         e.onclick = function() {
             showModal(e.lastElementChild.innerHTML);
         };
@@ -2278,7 +2370,7 @@
 
     function putBackSearch(search_input) {
         if (search_input.value !== "") {
-            addClass(document.getElementById("main"), "hidden");
+            addClass(main, "hidden");
             removeClass(document.getElementById("search"), "hidden");
             if (browserSupportsHistoryApi()) {
                 history.replaceState(search_input.value,
@@ -2296,16 +2388,16 @@
 
     var params = getQueryStringParams();
     if (params && params.search) {
-        addClass(document.getElementById("main"), "hidden");
+        addClass(main, "hidden");
         var search = document.getElementById("search");
         removeClass(search, "hidden");
-        search.innerHTML = '<h3 style="text-align: center;">Loading search results...</h3>';
+        search.innerHTML = "<h3 style=\"text-align: center;\">Loading search results...</h3>";
     }
 
     var sidebar_menu = document.getElementsByClassName("sidebar-menu")[0];
     if (sidebar_menu) {
         sidebar_menu.onclick = function() {
-            var sidebar = document.getElementsByClassName('sidebar')[0];
+            var sidebar = document.getElementsByClassName("sidebar")[0];
             if (hasClass(sidebar, "mobile") === true) {
                 hideSidebar();
             } else {
@@ -2321,16 +2413,60 @@
     autoCollapse(getPageId(), getCurrentValue("rustdoc-collapse") === "true");
 
     if (window.location.hash && window.location.hash.length > 0) {
-        expandSection(window.location.hash.replace(/^#/, ''));
+        expandSection(window.location.hash.replace(/^#/, ""));
     }
+
+    if (main) {
+        onEachLazy(main.getElementsByClassName("loading-content"), function(e) {
+            e.remove();
+        });
+        onEachLazy(main.childNodes, function(e) {
+            if (e.tagName === "H2" || e.tagName === "H3") {
+                e.nextElementSibling.style.display = "block";
+            }
+        });
+    }
+
+    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
 function focusSearchBar() {
-    document.getElementsByClassName('search-input')[0].focus();
+    document.getElementsByClassName("search-input")[0].focus();
 }
 
 // Removes the focus from the search bar
 function defocusSearchBar() {
-    document.getElementsByClassName('search-input')[0].blur();
+    document.getElementsByClassName("search-input")[0].blur();
 }
diff --git a/src/librustdoc/html/static/noscript.css b/src/librustdoc/html/static/noscript.css
new file mode 100644
index 0000000..f4de75f
--- /dev/null
+++ b/src/librustdoc/html/static/noscript.css
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+ * file at the top-level directory of this distribution and at
+ * http://rust-lang.org/COPYRIGHT.
+ *
+ * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+ * http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+ * <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+ * option. This file may not be copied, modified, or distributed
+ * except according to those terms.
+ */
+
+#main > h2 + div, #main > h2 + h3, #main > h3 + div {
+	display: block;
+}
+
+.loading-content {
+	display: none;
+}
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 83129d9..d1336b1 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -368,6 +368,10 @@
 #main > .docblock h2 { font-size: 1.15em; }
 #main > .docblock h3, #main > .docblock h4, #main > .docblock h5 { font-size: 1em; }
 
+#main > h2 + div, #main > h2 + h3, #main > h3 + div {
+	display: none;
+}
+
 .docblock h1 { font-size: 1em; }
 .docblock h2 { font-size: 0.95em; }
 .docblock h3, .docblock h4, .docblock h5 { font-size: 0.9em; }
@@ -620,13 +624,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: 20px;
+	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 */
@@ -634,13 +661,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 {
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index e8f0c03..d1c377b 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -19,55 +19,38 @@
 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;
+    return elem && elem.classList && elem.classList.contains(className);
 }
 
 function addClass(elem, className) {
-    if (elem && className && !hasClass(elem, className)) {
-        if (elem.className && elem.className.length > 0) {
-            elem.className += ' ' + className;
-        } else {
-            elem.className = className;
-        }
+    if (!elem || !elem.classList) {
+        return;
     }
+    elem.classList.add(className);
 }
 
 function removeClass(elem, className) {
-    if (elem && className && elem.className) {
-        elem.className = (" " + elem.className + " ").replace(" " + className + " ", " ")
-                                                     .trim();
+    if (!elem || !elem.classList) {
+        return;
     }
+    elem.classList.remove(className);
 }
 
 function isHidden(elem) {
-    return (elem.offsetParent === null)
+    return elem.offsetParent === null;
 }
 
 function onEach(arr, func, reversed) {
     if (arr && arr.length > 0 && func) {
+        var length = arr.length;
         if (reversed !== true) {
-            for (var i = 0; i < arr.length; ++i) {
+            for (var i = 0; i < length; ++i) {
                 if (func(arr[i]) === true) {
                     return true;
                 }
             }
         } else {
-            for (var i = arr.length - 1; i >= 0; --i) {
+            for (var i = length - 1; i >= 0; --i) {
                 if (func(arr[i]) === true) {
                     return true;
                 }
@@ -77,6 +60,13 @@
     return false;
 }
 
+function onEachLazy(lazyArray, func, reversed) {
+    return onEach(
+        Array.prototype.slice.call(lazyArray),
+        func,
+        reversed);
+}
+
 function usableLocalStorage() {
     // Check if the browser supports localStorage at all:
     if (typeof(Storage) === "undefined") {
@@ -133,8 +123,8 @@
     });
     if (found === true) {
         styleElem.href = newHref;
-        updateLocalStorage('rustdoc-theme', newTheme);
+        updateLocalStorage("rustdoc-theme", newTheme);
     }
 }
 
-switchTheme(currentTheme, mainTheme, getCurrentValue('rustdoc-theme') || 'light');
+switchTheme(currentTheme, mainTheme, getCurrentValue("rustdoc-theme") || "light");
diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css
index 29388f0..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;
 }
 
diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css
index d37cfa4..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;
 }
 
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index ee29f15..f71b2a8 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -23,6 +23,9 @@
 /// The file contents of `settings.css`, responsible for the items on the settings page.
 pub static SETTINGS_CSS: &'static str = include_str!("static/settings.css");
 
+/// The file contents of the `noscript.css` file, used in case JS isn't supported or is disabled.
+pub static NOSCRIPT_CSS: &'static str = include_str!("static/noscript.css");
+
 /// The file contents of `normalize.css`, included to even out standard elements between browser
 /// implementations.
 pub static NORMALIZE_CSS: &'static str = include_str!("static/normalize.css");
@@ -45,6 +48,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");
diff --git a/src/librustdoc/html/toc.rs b/src/librustdoc/html/toc.rs
index 88ada5c..45bd699 100644
--- a/src/librustdoc/html/toc.rs
+++ b/src/librustdoc/html/toc.rs
@@ -52,7 +52,7 @@
 pub struct TocBuilder {
     top_level: Toc,
     /// The current hierarchy of parent headings, the levels are
-    /// strictly increasing (i.e. chain[0].level < chain[1].level <
+    /// strictly increasing (i.e., chain[0].level < chain[1].level <
     /// ...) with each entry being the most recent occurrence of a
     /// heading with that level (it doesn't include the most recent
     /// occurrences of every level, just, if it *is* in `chain` then
@@ -76,7 +76,7 @@
     }
 
     /// Collapse the chain until the first heading more important than
-    /// `level` (i.e. lower level)
+    /// `level` (i.e., lower level)
     ///
     /// Example:
     ///
@@ -91,7 +91,7 @@
     /// ### H
     /// ```
     ///
-    /// If we are considering H (i.e. level 3), then A and B are in
+    /// If we are considering H (i.e., level 3), then A and B are in
     /// self.top_level, D is in C.children, and C, E, F, G are in
     /// self.chain.
     ///
@@ -102,7 +102,7 @@
     ///
     /// This leaves us looking at E, which does have a smaller level,
     /// and, by construction, it's the most recent thing with smaller
-    /// level, i.e. it's the immediate parent of H.
+    /// level, i.e., it's the immediate parent of H.
     fn fold_until(&mut self, level: u32) {
         let mut this = None;
         loop {
@@ -133,7 +133,7 @@
         assert!(level >= 1);
 
         // collapse all previous sections into their parents until we
-        // get to relevant heading (i.e. the first one with a smaller
+        // get to relevant heading (i.e., the first one with a smaller
         // level than us)
         self.fold_until(level);
 
@@ -150,7 +150,7 @@
                     (entry.level, &entry.children)
                 }
             };
-            // fill in any missing zeros, e.g. for
+            // fill in any missing zeros, e.g., for
             // # Foo (1)
             // ### Bar (1.0.1)
             for _ in toc_level..level - 1 {
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index b21f005..b0045e4 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -276,7 +276,7 @@
         unstable("resource-suffix", |o| {
             o.optopt("",
                      "resource-suffix",
-                     "suffix to add to CSS and JavaScript files, e.g. \"light.css\" will become \
+                     "suffix to add to CSS and JavaScript files, e.g., \"light.css\" will become \
                       \"light-suffix.css\"",
                      "PATH")
         }),
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 8008f88..504567e 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -35,7 +35,7 @@
     for line in s.lines() {
         if line.starts_with("# ") || line.starts_with("%") {
             // trim the whitespace after the symbol
-            metadata.push(line[1..].trim_left());
+            metadata.push(line[1..].trim_start());
             count += line.len() + 1;
         } else {
             return (metadata, &s[count..]);
@@ -46,8 +46,8 @@
     (metadata, "")
 }
 
-/// Render `input` (e.g. "foo.md") into an HTML file in `output`
-/// (e.g. output = "bar" => "bar/foo.html").
+/// Render `input` (e.g., "foo.md") into an HTML file in `output`
+/// (e.g., output = "bar" => "bar/foo.html").
 pub fn render(input: PathBuf, options: RenderOptions, diag: &errors::Handler) -> isize {
     let mut output = options.output;
     output.push(input.file_stem().unwrap());
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 7183cfe..2e8bfd8 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use clean::*;
-
 use rustc::lint as lint;
 use rustc::hir;
 use rustc::hir::def::Def;
@@ -26,6 +24,7 @@
 use fold::DocFolder;
 use html::markdown::markdown_links;
 
+use clean::*;
 use passes::{look_for_tests, Pass};
 
 pub const COLLECT_INTRA_DOC_LINKS: Pass =
@@ -44,13 +43,13 @@
 
 #[derive(Debug)]
 enum PathKind {
-    /// can be either value or type, not a macro
+    /// Either a value or type, but not a macro
     Unknown,
-    /// macro
+    /// Macro
     Macro,
-    /// values, functions, consts, statics, everything in the value namespace
+    /// Values, functions, consts, statics (everything in the value namespace)
     Value,
-    /// types, traits, everything in the type namespace
+    /// Types, traits (everything in the type namespace)
     Type,
 }
 
@@ -71,7 +70,7 @@
 
     /// Resolve a given string as a path, along with whether or not it is
     /// in the value namespace. Also returns an optional URL fragment in the case
-    /// of variants and methods
+    /// of variants and methods.
     fn resolve(&self,
                path_str: &str,
                is_val: bool,
@@ -82,9 +81,9 @@
         let cx = self.cx;
 
         // In case we're in a module, try to resolve the relative
-        // path
+        // path.
         if let Some(id) = parent_id.or(self.mod_ids.last().cloned()) {
-            // FIXME: `with_scope` requires the NodeId of a module
+            // FIXME: `with_scope` requires the `NodeId` of a module.
             let result = cx.resolver.borrow_mut()
                                     .with_scope(id,
                 |resolver| {
@@ -94,12 +93,12 @@
 
             if let Ok(result) = result {
                 // In case this is a trait item, skip the
-                // early return and try looking for the trait
+                // early return and try looking for the trait.
                 let value = match result.def {
                     Def::Method(_) | Def::AssociatedConst(_) => true,
                     Def::AssociatedTy(_) => false,
                     Def::Variant(_) => return handle_variant(cx, result.def),
-                    // not a trait item, just return what we found
+                    // Not a trait item; just return what we found.
                     _ => return Ok((result.def, None))
                 };
 
@@ -111,13 +110,13 @@
             } else {
                 // If resolution failed, it may still be a method
                 // because methods are not handled by the resolver
-                // If so, bail when we're not looking for a value
+                // If so, bail when we're not looking for a value.
                 if !is_val {
                     return Err(())
                 }
             }
 
-            // Try looking for methods and associated items
+            // Try looking for methods and associated items.
             let mut split = path_str.rsplitn(2, "::");
             let item_name = if let Some(first) = split.next() {
                 first
@@ -137,7 +136,7 @@
                 }
             }
 
-            // FIXME: `with_scope` requires the NodeId of a module
+            // FIXME: `with_scope` requires the `NodeId` of a module.
             let ty = cx.resolver.borrow_mut()
                                 .with_scope(id,
                 |resolver| {
@@ -217,7 +216,7 @@
 impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstore> {
     fn fold_item(&mut self, mut item: Item) -> Option<Item> {
         let item_node_id = if item.is_mod() {
-            if let Some(id) = self.cx.tcx.hir.as_local_node_id(item.def_id) {
+            if let Some(id) = self.cx.tcx.hir().as_local_node_id(item.def_id) {
                 Some(id)
             } else {
                 debug!("attempting to fold on a non-local item: {:?}", item);
@@ -227,11 +226,11 @@
             None
         };
 
-        // FIXME: get the resolver to work with non-local resolve scopes
+        // FIXME: get the resolver to work with non-local resolve scopes.
         let parent_node = self.cx.as_local_node_id(item.def_id).and_then(|node_id| {
             // FIXME: this fails hard for impls in non-module scope, but is necessary for the
-            // current resolve() implementation
-            match self.cx.tcx.hir.get_module_parent_node(node_id) {
+            // current `resolve()` implementation.
+            match self.cx.tcx.hir().get_module_parent_node(node_id) {
                 id if id != node_id => Some(id),
                 _ => None,
             }
@@ -252,8 +251,8 @@
                 } else {
                     match parent_node.or(self.mod_ids.last().cloned()) {
                         Some(parent) if parent != NodeId::from_u32(0) => {
-                            //FIXME: can we pull the parent module's name from elsewhere?
-                            Some(self.cx.tcx.hir.name(parent).to_string())
+                            // FIXME: can we pull the parent module's name from elsewhere?
+                            Some(self.cx.tcx.hir().name(parent).to_string())
                         }
                         _ => None,
                     }
@@ -262,7 +261,7 @@
             ImplItem(Impl { ref for_, .. }) => {
                 for_.def_id().map(|did| self.cx.tcx.item_name(did).to_string())
             }
-            // we don't display docs on `extern crate` items anyway, so don't process them
+            // we don't display docs on `extern crate` items anyway, so don't process them.
             ExternCrateItem(..) => return self.fold_item_recur(item),
             ImportItem(Import::Simple(ref name, ..)) => Some(name.clone()),
             MacroItem(..) => None,
@@ -283,7 +282,7 @@
         }
 
         for (ori_link, link_range) in markdown_links(&dox) {
-            // bail early for real links
+            // Bail early for real links.
             if ori_link.contains('/') {
                 continue;
             }
@@ -295,23 +294,23 @@
                      "trait@", "union@"].iter()
                                       .find(|p| link.starts_with(**p)) {
                     kind = PathKind::Type;
-                    link.trim_left_matches(prefix)
+                    link.trim_start_matches(prefix)
                 } else if let Some(prefix) =
                     ["const@", "static@",
                      "value@", "function@", "mod@",
                      "fn@", "module@", "method@"]
                         .iter().find(|p| link.starts_with(**p)) {
                     kind = PathKind::Value;
-                    link.trim_left_matches(prefix)
+                    link.trim_start_matches(prefix)
                 } else if link.ends_with("()") {
                     kind = PathKind::Value;
-                    link.trim_right_matches("()")
+                    link.trim_end_matches("()")
                 } else if link.starts_with("macro@") {
                     kind = PathKind::Macro;
-                    link.trim_left_matches("macro@")
+                    link.trim_start_matches("macro@")
                 } else if link.ends_with('!') {
                     kind = PathKind::Macro;
-                    link.trim_right_matches('!')
+                    link.trim_end_matches('!')
                 } else {
                     &link[..]
                 }.trim();
@@ -327,9 +326,9 @@
                             def
                         } else {
                             resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
-                            // this could just be a normal link or a broken link
+                            // This could just be a normal link or a broken link
                             // we could potentially check if something is
-                            // "intra-doc-link-like" and warn in that case
+                            // "intra-doc-link-like" and warn in that case.
                             continue;
                         }
                     }
@@ -338,12 +337,12 @@
                             def
                         } else {
                             resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
-                            // this could just be a normal link
+                            // This could just be a normal link.
                             continue;
                         }
                     }
                     PathKind::Unknown => {
-                        // try everything!
+                        // Try everything!
                         if let Some(macro_def) = macro_resolve(cx, path_str) {
                             if let Ok(type_def) =
                                 self.resolve(path_str, false, &current_item, parent_node)
@@ -371,8 +370,8 @@
                         {
                             // It is imperative we search for not-a-value first
                             // Otherwise we will find struct ctors for when we are looking
-                            // for structs, and the link won't work.
-                            // if there is something in both namespaces
+                            // for structs, and the link won't work if there is something in
+                            // both namespaces.
                             if let Ok(value_def) =
                                 self.resolve(path_str, true, &current_item, parent_node)
                             {
@@ -432,7 +431,7 @@
     }
 }
 
-/// Resolve a string as a macro
+/// Resolve a string as a macro.
 fn macro_resolve(cx: &DocContext, path_str: &str) -> Option<Def> {
     use syntax::ext::base::{MacroKind, SyntaxExtension};
     let segment = ast::PathSegment::from_ident(Ident::from_str(path_str));
@@ -460,6 +459,19 @@
     start.to(end)
 }
 
+/// Reports a resolution failure diagnostic.
+///
+/// Ideally we can report the diagnostic with the actual span in the source where the link failure
+/// occurred. However, there's a mismatch between the span in the source code and the span in the
+/// markdown, so we have to do a bit of work to figure out the correspondence.
+///
+/// It's not too hard to find the span for sugared doc comments (`///` and `/**`), because the
+/// source will match the markdown exactly, excluding the comment markers. However, it's much more
+/// difficult to calculate the spans for unsugared docs, because we have to deal with escaping and
+/// other source features. So, we attempt to find the exact source span of the resolution failure
+/// in sugared docs, but use the span of the documentation attributes themselves for unsugared
+/// docs. Because this span might be overly large, we display the markdown line containing the
+/// failure as a note.
 fn resolution_failure(
     cx: &DocContext,
     attrs: &Attributes,
@@ -470,51 +482,79 @@
     let sp = span_of_attrs(attrs);
     let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str);
 
-    let code_dox = sp.to_src(cx);
-
-    let doc_comment_padding = 3;
     let mut diag = if let Some(link_range) = link_range {
-        // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
-        //                       ^    ~~~~~~
-        //                       |    link_range
-        //                       last_new_line_offset
+        let src = cx.sess().source_map().span_to_snippet(sp);
+        let is_all_sugared_doc = attrs.doc_strings.iter().all(|frag| match frag {
+            DocFragment::SugaredDoc(..) => true,
+            _ => false,
+        });
 
-        let mut diag;
-        if dox.lines().count() == code_dox.lines().count() {
-            let line_offset = dox[..link_range.start].lines().count();
-            // The span starts in the `///`, so we don't have to account for the leading whitespace
-            let code_dox_len = if line_offset <= 1 {
-                doc_comment_padding
-            } else {
-                // The first `///`
-                doc_comment_padding +
-                    // Each subsequent leading whitespace and `///`
-                    code_dox.lines().skip(1).take(line_offset - 1).fold(0, |sum, line| {
-                        sum + doc_comment_padding + line.len() - line.trim_start().len()
-                    })
-            };
+        if let (Ok(src), true) = (src, is_all_sugared_doc) {
+            // The number of markdown lines up to and including the resolution failure.
+            let num_lines = dox[..link_range.start].lines().count();
 
-            // Extract the specific span
+            // We use `split_terminator('\n')` instead of `lines()` when counting bytes to ensure
+            // that DOS-style line endings do not cause the spans to be calculated incorrectly.
+            let mut src_lines = src.split_terminator('\n');
+            let mut md_lines = dox.split_terminator('\n').take(num_lines).peekable();
+
+            // The number of bytes from the start of the source span to the resolution failure that
+            // are *not* part of the markdown, like comment markers.
+            let mut extra_src_bytes = 0;
+
+            while let Some(md_line) = md_lines.next() {
+                loop {
+                    let source_line = src_lines
+                        .next()
+                        .expect("could not find markdown line in source");
+
+                    match source_line.find(md_line) {
+                        Some(offset) => {
+                            extra_src_bytes += if md_lines.peek().is_some() {
+                                source_line.len() - md_line.len()
+                            } else {
+                                offset
+                            };
+                            break;
+                        }
+                        None => {
+                            // Since this is a source line that doesn't include a markdown line,
+                            // we have to count the newline that we split from earlier.
+                            extra_src_bytes += source_line.len() + 1;
+                        }
+                    }
+                }
+            }
+
             let sp = sp.from_inner_byte_pos(
-                link_range.start + code_dox_len,
-                link_range.end + code_dox_len,
+                link_range.start + extra_src_bytes,
+                link_range.end + extra_src_bytes,
             );
 
-            diag = cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
-                                                NodeId::from_u32(0),
-                                                sp,
-                                                &msg);
+            let mut diag = cx.tcx.struct_span_lint_node(
+                lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
+                NodeId::from_u32(0),
+                sp,
+                &msg,
+            );
             diag.span_label(sp, "cannot be resolved, ignoring");
+            diag
         } else {
-            diag = cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
-                                                NodeId::from_u32(0),
-                                                sp,
-                                                &msg);
+            let mut diag = cx.tcx.struct_span_lint_node(
+                lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
+                NodeId::from_u32(0),
+                sp,
+                &msg,
+            );
 
+            // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
+            //                       ^     ~~~~
+            //                       |     link_range
+            //                       last_new_line_offset
             let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
             let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
 
-            // Print the line containing the `link_range` and manually mark it with '^'s
+            // Print the line containing the `link_range` and manually mark it with '^'s.
             diag.note(&format!(
                 "the link appears in this line:\n\n{line}\n\
                  {indicator: <before$}{indicator:^<found$}",
@@ -523,8 +563,8 @@
                 before=link_range.start - last_new_line_offset,
                 found=link_range.len(),
             ));
+            diag
         }
-        diag
     } else {
         cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
                                      NodeId::from_u32(0),
@@ -555,13 +595,13 @@
 }
 
 /// Given a def, returns its name and disambiguator
-/// for a value namespace
+/// for a value namespace.
 ///
-/// Returns None for things which cannot be ambiguous since
-/// they exist in both namespaces (structs and modules)
+/// Returns `None` for things which cannot be ambiguous since
+/// they exist in both namespaces (structs and modules).
 fn value_ns_kind(def: Def, path_str: &str) -> Option<(&'static str, String)> {
     match def {
-        // structs, variants, and mods exist in both namespaces. skip them
+        // Structs, variants, and mods exist in both namespaces; skip them.
         Def::StructCtor(..) | Def::Mod(..) | Def::Variant(..) |
         Def::VariantCtor(..) | Def::SelfCtor(..)
             => None,
@@ -578,10 +618,10 @@
 }
 
 /// Given a def, returns its name, the article to be used, and a disambiguator
-/// for the type namespace
+/// for the type namespace.
 fn type_ns_kind(def: Def, path_str: &str) -> (&'static str, &'static str, String) {
     let (kind, article) = match def {
-        // we can still have non-tuple structs
+        // We can still have non-tuple structs.
         Def::Struct(..) => ("struct", "a"),
         Def::Enum(..) => ("enum", "an"),
         Def::Trait(..) => ("trait", "a"),
@@ -591,7 +631,7 @@
     (kind, article, format!("{}@{}", kind, path_str))
 }
 
-/// Given an enum variant's def, return the def of its enum and the associated fragment
+/// Given an enum variant's def, return the def of its enum and the associated fragment.
 fn handle_variant(cx: &DocContext, def: Def) -> Result<(Def, Option<String>), ()> {
     use rustc::ty::DefIdTree;
 
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 70e1a9b..8847fb8 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -127,8 +127,8 @@
     // `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations`
     // doesn't work with it anyway, so pull them from the HIR map instead
     for &trait_did in cx.all_traits.iter() {
-        for &impl_node in cx.tcx.hir.trait_impls(trait_did) {
-            let impl_did = cx.tcx.hir.local_def_id(impl_node);
+        for &impl_node in cx.tcx.hir().trait_impls(trait_did) {
+            let impl_did = cx.tcx.hir().local_def_id(impl_node);
             inline::build_impl(cx, impl_did, &mut new_items);
         }
     }
@@ -165,7 +165,7 @@
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         if i.is_struct() || i.is_enum() || i.is_union() {
             if let (Some(node_id), Some(name)) =
-                (self.cx.tcx.hir.as_local_node_id(i.def_id), i.name.clone())
+                (self.cx.tcx.hir().as_local_node_id(i.def_id), i.name.clone())
             {
                 self.impls.extend(get_auto_traits_with_node_id(self.cx, node_id, name.clone()));
                 self.impls.extend(get_blanket_impls_with_node_id(self.cx, node_id, name));
diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs
index 6d875c1..5c565bf 100644
--- a/src/librustdoc/passes/unindent_comments.rs
+++ b/src/librustdoc/passes/unindent_comments.rs
@@ -95,7 +95,7 @@
     });
 
     if !lines.is_empty() {
-        let mut unindented = vec![ lines[0].trim_left().to_string() ];
+        let mut unindented = vec![ lines[0].trim_start().to_string() ];
         unindented.extend_from_slice(&lines[1..].iter().map(|&line| {
             if line.chars().all(|c| c.is_whitespace()) {
                 line.to_string()
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 7458319..50acde6 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -8,6 +8,29 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use errors;
+use errors::emitter::ColorConfig;
+use rustc_data_structures::sync::Lrc;
+use rustc_lint;
+use rustc_driver::{self, driver, target_features, Compilation};
+use rustc_driver::driver::phase_2_configure_and_expand;
+use rustc_metadata::cstore::CStore;
+use rustc_metadata::dynamic_lib::DynamicLibrary;
+use rustc_resolve::MakeGlobMap;
+use rustc::hir;
+use rustc::hir::intravisit;
+use rustc::session::{self, CompileIncomplete, config};
+use rustc::session::config::{OutputType, OutputTypes, Externs, CodegenOptions};
+use rustc::session::search_paths::{SearchPath, PathKind};
+use syntax::ast;
+use syntax::source_map::SourceMap;
+use syntax::edition::Edition;
+use syntax::feature_gate::UnstableFeatures;
+use syntax::with_globals;
+use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
+use tempfile::Builder as TempFileBuilder;
+use testing;
+
 use std::env;
 use std::ffi::OsString;
 use std::io::prelude::*;
@@ -16,31 +39,8 @@
 use std::panic::{self, AssertUnwindSafe};
 use std::process::Command;
 use std::str;
-use rustc_data_structures::sync::Lrc;
 use std::sync::{Arc, Mutex};
 
-use testing;
-use rustc_lint;
-use rustc::hir;
-use rustc::hir::intravisit;
-use rustc::session::{self, CompileIncomplete, config};
-use rustc::session::config::{OutputType, OutputTypes, Externs, CodegenOptions};
-use rustc::session::search_paths::{SearchPaths, PathKind};
-use rustc_metadata::dynamic_lib::DynamicLibrary;
-use tempfile::Builder as TempFileBuilder;
-use rustc_driver::{self, driver, target_features, Compilation};
-use rustc_driver::driver::phase_2_configure_and_expand;
-use rustc_metadata::cstore::CStore;
-use rustc_resolve::MakeGlobMap;
-use syntax::ast;
-use syntax::source_map::SourceMap;
-use syntax::edition::Edition;
-use syntax::feature_gate::UnstableFeatures;
-use syntax::with_globals;
-use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
-use errors;
-use errors::emitter::ColorConfig;
-
 use clean::Attributes;
 use config::Options;
 use html::markdown::{self, ErrorCodes, LangString};
@@ -153,7 +153,7 @@
     })
 }
 
-// Look for #![doc(test(no_crate_inject))], used by crates in the std facade
+// Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade.
 fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
     use syntax::print::pprust;
 
@@ -187,17 +187,16 @@
 }
 
 fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
-            cfgs: Vec<String>, libs: SearchPaths,
+            cfgs: Vec<String>, libs: Vec<SearchPath>,
             cg: CodegenOptions, externs: Externs,
             should_panic: bool, no_run: bool, as_test_harness: bool,
             compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
             maybe_sysroot: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition) {
-    // the test harness wants its own `main` & top level functions, so
-    // never wrap the test in `fn main() { ... }`
+    // The test harness wants its own `main` and top-level functions, so
+    // never wrap the test in `fn main() { ... }`.
     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
-
+    // 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"),
@@ -408,8 +407,8 @@
         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
-        // send all the errors that libsyntax emits directly into a Sink instead of stderr
+        // Any errors in parsing should also appear when the doctest is compiled for real, so just
+        // send all the errors that libsyntax emits directly into a `Sink` instead of stderr.
         let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let emitter = EmitterWriter::new(box io::sink(), None, false, false);
         let handler = Handler::with_emitter(false, false, box emitter);
@@ -537,10 +536,10 @@
     // The name of the test displayed to the user, separated by `::`.
     //
     // In tests from Rust source, this is the path to the item
-    // e.g. `["std", "vec", "Vec", "push"]`.
+    // e.g., `["std", "vec", "Vec", "push"]`.
     //
     // In tests from a markdown file, this is the titles of all headers (h1~h6)
-    // of the sections that contain the code block, e.g. if the markdown file is
+    // of the sections that contain the code block, e.g., if the markdown file is
     // written as:
     //
     // ``````markdown
@@ -557,7 +556,7 @@
     names: Vec<String>,
 
     cfgs: Vec<String>,
-    libs: SearchPaths,
+    libs: Vec<SearchPath>,
     cg: CodegenOptions,
     externs: Externs,
     use_headers: bool,
@@ -572,7 +571,7 @@
 }
 
 impl Collector {
-    pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, cg: CodegenOptions,
+    pub fn new(cratename: String, cfgs: Vec<String>, libs: Vec<SearchPath>, cg: CodegenOptions,
                externs: Externs, use_headers: bool, opts: TestOptions,
                maybe_sysroot: Option<PathBuf>, source_map: Option<Lrc<SourceMap>>,
                filename: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition) -> Collector {
@@ -689,7 +688,7 @@
 
     fn register_header(&mut self, name: &str, level: u32) {
         if self.use_headers {
-            // we use these headings as test names, so it's good if
+            // We use these headings as test names, so it's good if
             // they're valid identifiers.
             let name = name.chars().enumerate().map(|(i, c)| {
                     if (i == 0 && c.is_xid_start()) ||
@@ -703,7 +702,7 @@
             // Here we try to efficiently assemble the header titles into the
             // test name in the form of `h1::h2::h3::h4::h5::h6`.
             //
-            // Suppose originally `self.names` contains `[h1, h2, h3]`...
+            // Suppose that originally `self.names` contains `[h1, h2, h3]`...
             let level = level as usize;
             if level <= self.names.len() {
                 // ... Consider `level == 2`. All headers in the lower levels
@@ -752,8 +751,8 @@
 
         attrs.collapse_doc_comments();
         attrs.unindent_doc_comments();
-        // the collapse-docs pass won't combine sugared/raw doc attributes, or included files with
-        // anything else, this will combine them for us
+        // The collapse-docs pass won't combine sugared/raw doc attributes, or included files with
+        // anything else, this will combine them for us.
         if let Some(doc) = attrs.collapsed_doc_value() {
             self.collector.set_position(attrs.span.unwrap_or(DUMMY_SP));
             let res = markdown::find_testable_code(&doc, self.collector, self.codes);
@@ -847,8 +846,8 @@
 
     #[test]
     fn make_test_crate_name_no_use() {
-        //if you give a crate name but *don't* use it within the test, it won't bother inserting
-        //the `extern crate` statement
+        // If you give a crate name but *don't* use it within the test, it won't bother inserting
+        // the `extern crate` statement.
         let opts = TestOptions::default();
         let input =
 "assert_eq!(2+2, 4);";
@@ -863,8 +862,8 @@
 
     #[test]
     fn make_test_crate_name() {
-        //if you give a crate name and use it within the test, it will insert an `extern crate`
-        //statement before `fn main`
+        // If you give a crate name and use it within the test, it will insert an `extern crate`
+        // statement before `fn main`.
         let opts = TestOptions::default();
         let input =
 "use asdf::qwop;
@@ -882,8 +881,8 @@
 
     #[test]
     fn make_test_no_crate_inject() {
-        //even if you do use the crate within the test, setting `opts.no_crate_inject` will skip
-        //adding it anyway
+        // Even if you do use the crate within the test, setting `opts.no_crate_inject` will skip
+        // adding it anyway.
         let opts = TestOptions {
             no_crate_inject: true,
             display_warnings: false,
@@ -904,8 +903,9 @@
 
     #[test]
     fn make_test_ignore_std() {
-        //even if you include a crate name, and use it in the doctest, we still won't include an
-        //`extern crate` statement if the crate is "std" - that's included already by the compiler!
+        // Even if you include a crate name, and use it in the doctest, we still won't include an
+        // `extern crate` statement if the crate is "std" -- that's included already by the
+        // compiler!
         let opts = TestOptions::default();
         let input =
 "use std::*;
@@ -922,8 +922,8 @@
 
     #[test]
     fn make_test_manual_extern_crate() {
-        //when you manually include an `extern crate` statement in your doctest, make_test assumes
-        //you've included one for your own crate too
+        // When you manually include an `extern crate` statement in your doctest, `make_test`
+        // assumes you've included one for your own crate too.
         let opts = TestOptions::default();
         let input =
 "extern crate asdf;
@@ -960,8 +960,8 @@
 
     #[test]
     fn make_test_opts_attrs() {
-        //if you supplied some doctest attributes with #![doc(test(attr(...)))], it will use those
-        //instead of the stock #![allow(unused)]
+        // If you supplied some doctest attributes with `#![doc(test(attr(...)))]`, it will use
+        // those instead of the stock `#![allow(unused)]`.
         let mut opts = TestOptions::default();
         opts.attrs.push("feature(sick_rad)".to_string());
         let input =
@@ -977,7 +977,7 @@
         let output = make_test(input, Some("asdf"), false, &opts);
         assert_eq!(output, (expected, 3));
 
-        //adding more will also bump the returned line offset
+        // Adding more will also bump the returned line offset.
         opts.attrs.push("feature(hella_dope)".to_string());
         let expected =
 "#![feature(sick_rad)]
@@ -993,8 +993,8 @@
 
     #[test]
     fn make_test_crate_attrs() {
-        //including inner attributes in your doctest will apply them to the whole "crate", pasting
-        //them outside the generated main function
+        // Including inner attributes in your doctest will apply them to the whole "crate", pasting
+        // them outside the generated main function.
         let opts = TestOptions::default();
         let input =
 "#![feature(sick_rad)]
@@ -1011,7 +1011,7 @@
 
     #[test]
     fn make_test_with_main() {
-        //including your own `fn main` wrapper lets the test use it verbatim
+        // Including your own `fn main` wrapper lets the test use it verbatim.
         let opts = TestOptions::default();
         let input =
 "fn main() {
@@ -1028,7 +1028,7 @@
 
     #[test]
     fn make_test_fake_main() {
-        //...but putting it in a comment will still provide a wrapper
+        // ... but putting it in a comment will still provide a wrapper.
         let opts = TestOptions::default();
         let input =
 "//Ceci n'est pas une `fn main`
@@ -1045,7 +1045,7 @@
 
     #[test]
     fn make_test_dont_insert_main() {
-        //even with that, if you set `dont_insert_main`, it won't create the `fn main` wrapper
+        // Even with that, if you set `dont_insert_main`, it won't create the `fn main` wrapper.
         let opts = TestOptions::default();
         let input =
 "//Ceci n'est pas une `fn main`
@@ -1060,7 +1060,7 @@
 
     #[test]
     fn make_test_display_warnings() {
-        //if the user is asking to display doctest warnings, suppress the default allow(unused)
+        // If the user is asking to display doctest warnings, suppress the default `allow(unused)`.
         let mut opts = TestOptions::default();
         opts.display_warnings = true;
         let input =
diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs
index 55a11d1..206a72c 100644
--- a/src/librustdoc/theme.rs
+++ b/src/librustdoc/theme.rs
@@ -9,9 +9,8 @@
 // except according to those terms.
 
 use rustc_data_structures::fx::FxHashSet;
-use std::fs::File;
+use std::fs;
 use std::hash::{Hash, Hasher};
-use std::io::Read;
 use std::path::Path;
 
 use errors::Handler;
@@ -278,12 +277,9 @@
 pub fn test_theme_against<P: AsRef<Path>>(f: &P, against: &CssPath, diag: &Handler)
     -> (bool, Vec<String>)
 {
-    let mut file = try_something!(File::open(f), diag, (false, Vec::new()));
-    let mut data = Vec::with_capacity(1000);
-
-    try_something!(file.read_to_end(&mut data), diag, (false, Vec::new()));
+    let data = try_something!(fs::read(f), diag, (false, vec![]));
     let paths = load_css_paths(&data);
-    let mut ret = Vec::new();
+    let mut ret = vec![];
     get_differences(against, &paths, &mut ret);
     (true, ret)
 }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 5d221d3..287984c 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -8,36 +8,33 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Rust AST Visitor. Extracts useful information and massages it into a form
-//! usable for clean
+//! The Rust AST Visitor. Extracts useful information and massages it into a form
+//! usable for `clean`.
 
-use std::mem;
-
+use rustc::hir::{self, Node};
+use rustc::hir::def::Def;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::middle::privacy::AccessLevel;
+use rustc::util::nodemap::{FxHashSet, FxHashMap};
 use syntax::ast;
 use syntax::attr;
 use syntax::ext::base::MacroKind;
 use syntax::source_map::Spanned;
 use syntax_pos::{self, Span};
 
-use rustc::hir::Node;
-use rustc::hir::def::Def;
-use rustc::hir::def_id::{DefId, LOCAL_CRATE};
-use rustc::middle::privacy::AccessLevel;
-use rustc::util::nodemap::{FxHashSet, FxHashMap};
-
-use rustc::hir;
+use std::mem;
 
 use core;
 use clean::{self, AttributesExt, NestedAttributesExt, def_id_to_path};
 use doctree::*;
 
-// looks to me like the first two of these are actually
+// Looks to me like the first two of these are actually
 // output parameters, maybe only mutated once; perhaps
 // better simply to have the visit method return a tuple
 // containing them?
 
-// also, is there some reason that this doesn't use the 'visit'
-// framework from syntax?
+// Also, is there some reason that this doesn't use the 'visit'
+// framework from syntax?.
 
 pub struct RustdocVisitor<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> {
     pub module: Module,
@@ -45,7 +42,7 @@
     pub cx: &'a core::DocContext<'a, 'tcx, 'rcx, 'cstore>,
     view_item_stack: FxHashSet<ast::NodeId>,
     inlining: bool,
-    /// Is the current module and all of its parents public?
+    /// Are the current module and all of its parents public?
     inside_public_path: bool,
     exact_paths: Option<FxHashMap<DefId, Vec<String>>>,
 }
@@ -69,8 +66,8 @@
     }
 
     fn store_path(&mut self, did: DefId) {
-        // We can't use the entry api, as that keeps the mutable borrow of self active
-        // when we try to use cx
+        // We can't use the entry API, as that keeps the mutable borrow of `self` active
+        // when we try to use `cx`.
         let exact_paths = self.exact_paths.as_mut().unwrap();
         if exact_paths.get(&did).is_none() {
             let path = def_id_to_path(self.cx, did, self.cx.crate_name.clone());
@@ -79,12 +76,12 @@
     }
 
     fn stability(&self, id: ast::NodeId) -> Option<attr::Stability> {
-        self.cx.tcx.hir.opt_local_def_id(id)
+        self.cx.tcx.hir().opt_local_def_id(id)
             .and_then(|def_id| self.cx.tcx.lookup_stability(def_id)).cloned()
     }
 
     fn deprecation(&self, id: ast::NodeId) -> Option<attr::Deprecation> {
-        self.cx.tcx.hir.opt_local_def_id(id)
+        self.cx.tcx.hir().opt_local_def_id(id)
             .and_then(|def_id| self.cx.tcx.lookup_deprecation(def_id))
     }
 
@@ -98,9 +95,9 @@
                                               ast::CRATE_NODE_ID,
                                               &krate.module,
                                               None);
-        // attach the crate's exported macros to the top-level module:
+        // 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;
 
@@ -257,7 +254,7 @@
         let orig_inside_public_path = self.inside_public_path;
         self.inside_public_path &= vis.node.is_pub();
         for i in &m.item_ids {
-            let item = self.cx.tcx.hir.expect_item(i.id);
+            let item = self.cx.tcx.hir().expect_item(i.id);
             self.visit_item(item, None, &mut om);
         }
         self.inside_public_path = orig_inside_public_path;
@@ -282,9 +279,9 @@
                           please_inline: bool) -> bool {
 
         fn inherits_doc_hidden(cx: &core::DocContext, mut node: ast::NodeId) -> bool {
-            while let Some(id) = cx.tcx.hir.get_enclosing_scope(node) {
+            while let Some(id) = cx.tcx.hir().get_enclosing_scope(node) {
                 node = id;
-                if cx.tcx.hir.attrs(node).lists("doc").has_word("hidden") {
+                if cx.tcx.hir().attrs(node).lists("doc").has_word("hidden") {
                     return true;
                 }
                 if node == ast::CRATE_NODE_ID {
@@ -302,15 +299,15 @@
         }
         let def_did = def.def_id();
 
-        let use_attrs = tcx.hir.attrs(id);
-        // Don't inline doc(hidden) imports so they can be stripped at a later stage.
+        let use_attrs = tcx.hir().attrs(id);
+        // Don't inline `doc(hidden)` imports so they can be stripped at a later stage.
         let is_no_inline = use_attrs.lists("doc").has_word("no_inline") ||
                            use_attrs.lists("doc").has_word("hidden");
 
         // For cross-crate impl inlining we need to know whether items are
-        // reachable in documentation - a previously nonreachable item can be
+        // reachable in documentation -- a previously nonreachable item can be
         // made reachable by cross-crate inlining which we're checking here.
-        // (this is done here because we need to know this upfront)
+        // (this is done here because we need to know this upfront).
         if !def_did.is_local() && !is_no_inline {
             let attrs = clean::inline::load_attrs(self.cx, def_did);
             let self_is_hidden = attrs.lists("doc").has_word("hidden");
@@ -335,25 +332,25 @@
             return false
         }
 
-        let def_node_id = match tcx.hir.as_local_node_id(def_did) {
+        let def_node_id = match tcx.hir().as_local_node_id(def_did) {
             Some(n) => n, None => return false
         };
 
         let is_private = !self.cx.renderinfo.borrow().access_levels.is_public(def_did);
         let is_hidden = inherits_doc_hidden(self.cx, def_node_id);
 
-        // Only inline if requested or if the item would otherwise be stripped
+        // Only inline if requested or if the item would otherwise be stripped.
         if (!please_inline && !is_private && !is_hidden) || is_no_inline {
             return false
         }
 
         if !self.view_item_stack.insert(def_node_id) { return false }
 
-        let ret = match tcx.hir.get(def_node_id) {
+        let ret = match tcx.hir().get(def_node_id) {
             Node::Item(&hir::Item { node: hir::ItemKind::Mod(ref m), .. }) if glob => {
                 let prev = mem::replace(&mut self.inlining, true);
                 for i in &m.item_ids {
-                    let i = self.cx.tcx.hir.expect_item(i.id);
+                    let i = self.cx.tcx.hir().expect_item(i.id);
                     self.visit_item(i, None, om);
                 }
                 self.inlining = prev;
@@ -366,9 +363,9 @@
                 true
             }
             Node::ForeignItem(it) if !glob => {
-                // generate a fresh `extern {}` block if we want to inline a foreign item.
+                // Generate a fresh `extern {}` block if we want to inline a foreign item.
                 om.foreigns.push(hir::ForeignMod {
-                    abi: tcx.hir.get_foreign_abi(it.id),
+                    abi: tcx.hir().get_foreign_abi(it.id),
                     items: vec![hir::ForeignItem {
                         name: renamed.unwrap_or(it.name),
                         .. it.clone()
@@ -376,6 +373,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);
@@ -388,7 +389,7 @@
         let name = renamed.unwrap_or(item.name);
 
         if item.vis.node.is_pub() {
-            let def_id = self.cx.tcx.hir.local_def_id(item.id);
+            let def_id = self.cx.tcx.hir().local_def_id(item.id);
             self.store_path(def_id);
         }
 
@@ -408,7 +409,7 @@
             _ if self.inlining && !item.vis.node.is_pub() => {}
             hir::ItemKind::GlobalAsm(..) => {}
             hir::ItemKind::ExternCrate(orig_name) => {
-                let def_id = self.cx.tcx.hir.local_def_id(item.id);
+                let def_id = self.cx.tcx.hir().local_def_id(item.id);
                 om.extern_crates.push(ExternCrate {
                     cnum: self.cx.tcx.extern_mod_stmt_cnum(def_id)
                                 .unwrap_or(LOCAL_CRATE),
@@ -423,10 +424,11 @@
             hir::ItemKind::Use(ref path, kind) => {
                 let is_glob = kind == hir::UseKind::Glob;
 
-                // struct and variant constructors always show up alongside their definitions, we've
-                // already processed them so just discard these.
+                // Struct and variant constructors and proc macro stubs always show up alongside
+                // their definitions, we've already processed them so just discard these.
                 match path.def {
-                    Def::StructCtor(..) | Def::VariantCtor(..) | Def::SelfCtor(..) => return,
+                    Def::StructCtor(..) | Def::VariantCtor(..) | Def::SelfCtor(..) |
+                    Def::Macro(_, MacroKind::ProcMacroStub) => return,
                     _ => {}
                 }
 
@@ -536,7 +538,7 @@
             },
             hir::ItemKind::Trait(is_auto, unsafety, ref gen, ref b, ref item_ids) => {
                 let items = item_ids.iter()
-                                    .map(|ti| self.cx.tcx.hir.trait_item(ti.id).clone())
+                                    .map(|ti| self.cx.tcx.hir().trait_item(ti.id).clone())
                                     .collect();
                 let t = Trait {
                     is_auto,
@@ -569,7 +571,7 @@
                 // them up regardless of where they're located.
                 if !self.inlining && tr.is_none() {
                     let items = item_ids.iter()
-                                        .map(|ii| self.cx.tcx.hir.impl_item(ii.id).clone())
+                                        .map(|ii| self.cx.tcx.hir().impl_item(ii.id).clone())
                                         .collect();
                     let i = Impl {
                         unsafety,
@@ -592,17 +594,21 @@
         }
     }
 
-    // convert each exported_macro into a doc item
-    fn visit_local_macro(&self, def: &hir::MacroDef) -> Macro {
+    // Convert each `exported_macro` into a doc item.
+    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.
         let matchers = tts.chunks(4).map(|arm| arm[0].span()).collect();
 
         Macro {
-            def_id: self.cx.tcx.hir.local_def_id(def.id),
+            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/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 5d1f42c..f64334a 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -21,7 +21,7 @@
 // FIXME: this may not be exhaustive, but is sufficient for rustdocs current uses
 
 /// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
-/// specific rustdoc annotations into account (i.e. `doc(hidden)`)
+/// specific rustdoc annotations into account (i.e., `doc(hidden)`)
 pub struct LibEmbargoVisitor<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> {
     cx: &'a ::core::DocContext<'a, 'tcx, 'rcx, 'cstore>,
     // Accessibility levels for reachable nodes
diff --git a/src/libserialize/Cargo.toml b/src/libserialize/Cargo.toml
index 66140d9..3e04081 100644
--- a/src/libserialize/Cargo.toml
+++ b/src/libserialize/Cargo.toml
@@ -9,4 +9,4 @@
 crate-type = ["dylib", "rlib"]
 
 [dependencies]
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 9439dc7..b0884e1 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -3493,7 +3493,7 @@
 
         // Helper function for counting indents
         fn indents(source: &str) -> usize {
-            let trimmed = source.trim_left_matches(' ');
+            let trimmed = source.trim_start_matches(' ');
             source.len() - trimmed.len()
         }
 
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index cae2f40..41e778b 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -17,13 +17,13 @@
 panic_unwind = { path = "../libpanic_unwind", optional = true }
 panic_abort = { path = "../libpanic_abort" }
 core = { path = "../libcore" }
-libc = { path = "../rustc/libc_shim" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
+libc = { version = "0.2.44", default-features = false, features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "0.1.1" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 
 [dev-dependencies]
-rand = "0.5"
+rand = "0.6.1"
 
 [target.x86_64-apple-darwin.dependencies]
 rustc_asan = { path = "../librustc_asan" }
@@ -35,8 +35,11 @@
 rustc_msan = { path = "../librustc_msan" }
 rustc_tsan = { path = "../librustc_tsan" }
 
-[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies]
-dlmalloc = { path = '../rustc/dlmalloc_shim' }
+[target.'cfg(any(all(target_arch = "wasm32", not(target_os = "emscripten")), target_env = "sgx"))'.dependencies]
+dlmalloc = { version = "0.1", features = ['rustc-dep-of-std'] }
+
+[target.x86_64-fortanix-unknown-sgx.dependencies]
+fortanix-sgx-abi = { version = "0.3.1", features = ['rustc-dep-of-std'] }
 
 [build-dependencies]
 cc = "1.0"
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index 9d6e8c4..7143de5 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -68,7 +68,6 @@
         println!("cargo:rustc-link-lib=advapi32");
         println!("cargo:rustc-link-lib=ws2_32");
         println!("cargo:rustc-link-lib=userenv");
-        println!("cargo:rustc-link-lib=shell32");
     } else if target.contains("fuchsia") {
         println!("cargo:rustc-link-lib=zircon");
         println!("cargo:rustc-link-lib=fdio");
@@ -82,7 +81,12 @@
 }
 
 fn build_libbacktrace(target: &str) -> Result<(), ()> {
-    let native = native_lib_boilerplate("libbacktrace", "libbacktrace", "backtrace", "")?;
+    let native = native_lib_boilerplate(
+        "../libbacktrace".as_ref(),
+        "libbacktrace",
+        "backtrace",
+        "",
+    )?;
 
     let mut build = cc::Build::new();
     build
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 536ce2e..55a1a75 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -11,6 +11,7 @@
 use self::Entry::*;
 use self::VacantEntryState::*;
 
+use intrinsics::unlikely;
 use collections::CollectionAllocErr;
 use cell::Cell;
 use borrow::Borrow;
@@ -1992,6 +1993,9 @@
     fn search<F>(self, hash: u64, is_match: F, compare_hashes: bool) -> Option<(&'a K, &'a V)>
         where F: FnMut(&K) -> bool
     {
+        if unsafe { unlikely(self.map.table.size() == 0) } {
+            return None;
+        }
         match search_hashed_nonempty(&self.map.table,
                                      SafeHash::new(hash),
                                      is_match,
@@ -3610,7 +3614,7 @@
             for i in 1..1001 {
                 assert!(m.insert(i, i).is_none());
 
-                for j in 1..i + 1 {
+                for j in 1..=i {
                     let r = m.get(&j);
                     assert_eq!(r, Some(&j));
                 }
@@ -3629,7 +3633,7 @@
             for i in 1..1001 {
                 assert!(m.remove(&i).is_some());
 
-                for j in 1..i + 1 {
+                for j in 1..=i {
                     assert!(!m.contains_key(&j));
                 }
 
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 4bb3ce0..d3267e4 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -342,7 +342,7 @@
     }
 
     /// Visits the values representing the difference,
-    /// i.e. the values that are in `self` but not in `other`.
+    /// i.e., the values that are in `self` but not in `other`.
     ///
     /// # Examples
     ///
@@ -373,7 +373,7 @@
     }
 
     /// Visits the values representing the symmetric difference,
-    /// i.e. the values that are in `self` or in `other` but not in both.
+    /// i.e., the values that are in `self` or in `other` but not in both.
     ///
     /// # Examples
     ///
@@ -401,7 +401,7 @@
     }
 
     /// Visits the values representing the intersection,
-    /// i.e. the values that are both in `self` and `other`.
+    /// i.e., the values that are both in `self` and `other`.
     ///
     /// # Examples
     ///
@@ -427,7 +427,7 @@
     }
 
     /// Visits the values representing the union,
-    /// i.e. all the values in `self` or `other`, without duplicates.
+    /// i.e., all the values in `self` or `other`, without duplicates.
     ///
     /// # Examples
     ///
@@ -598,7 +598,7 @@
     }
 
     /// Returns `true` if the set is a subset of another,
-    /// i.e. `other` contains at least all the values in `self`.
+    /// i.e., `other` contains at least all the values in `self`.
     ///
     /// # Examples
     ///
@@ -620,7 +620,7 @@
     }
 
     /// Returns `true` if the set is a superset of another,
-    /// i.e. `self` contains at least all the values in `other`.
+    /// i.e., `self` contains at least all the values in `other`.
     ///
     /// # Examples
     ///
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 7a5353b..e5c5ab8 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -36,12 +36,12 @@
 use string;
 
 /// `Error` is a trait representing the basic expectations for error values,
-/// i.e. values of type `E` in [`Result<T, E>`]. Errors must describe
+/// i.e., values of type `E` in [`Result<T, E>`]. Errors must describe
 /// themselves through the [`Display`] and [`Debug`] traits, and may provide
 /// cause chain information:
 ///
 /// The [`cause`] method is generally used when errors cross "abstraction
-/// boundaries", i.e.  when a one module must report an error that is "caused"
+/// boundaries", i.e.,  when a one module must report an error that is "caused"
 /// by an error from a lower-level module. This setup makes it possible for the
 /// high-level module to provide its own errors that do not commit to any
 /// particular implementation, but also reveal some of its implementation for
@@ -533,6 +533,7 @@
         Error::description(&**self)
     }
 
+    #[allow(deprecated)]
     fn cause(&self) -> Option<&dyn Error> {
         Error::cause(&**self)
     }
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index ecaaf83..c800763 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -888,7 +888,7 @@
     }
 
     // Solaris/Illumos requires a wrapper around log, log2, and log10 functions
-    // because of their non-standard behavior (e.g. log(-n) returns -Inf instead
+    // because of their non-standard behavior (e.g., log(-n) returns -Inf instead
     // of expected NaN).
     fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 {
         if !cfg!(target_os = "solaris") {
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 7c7f839..768998b 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -372,7 +372,7 @@
     /// # Safety
     ///
     /// This should only ever be called with a pointer that was earlier
-    /// obtained by calling [`into_raw`] on a `CString`. Other usage (e.g. trying to take
+    /// obtained by calling [`into_raw`] on a `CString`. Other usage (e.g., trying to take
     /// ownership of a string that was allocated by foreign code) is likely to lead
     /// to undefined behavior or allocator corruption.
     ///
@@ -1167,8 +1167,8 @@
     /// ```
     #[stable(feature = "cstr_to_str", since = "1.4.0")]
     pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
-        // NB: When CStr is changed to perform the length check in .to_bytes()
-        // instead of in from_ptr(), it may be worth considering if this should
+        // N.B., when `CStr` is changed to perform the length check in `.to_bytes()`
+        // instead of in `from_ptr()`, it may be worth considering if this should
         // be rewritten to do the UTF-8 check inline with the length calculation
         // instead of doing it afterwards.
         str::from_utf8(self.to_bytes())
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index bd5fc3f..7e15539 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -21,7 +21,7 @@
 //! Rust represents owned strings with the [`String`] type, and
 //! borrowed slices of strings with the [`str`] primitive. Both are
 //! always in UTF-8 encoding, and may contain nul bytes in the middle,
-//! i.e. if you look at the bytes that make up the string, there may
+//! i.e., if you look at the bytes that make up the string, there may
 //! be a `\0` among them. Both `String` and `str` store their length
 //! explicitly; there are no nul terminators at the end of strings
 //! like in C.
@@ -44,7 +44,7 @@
 //! code point]'.
 //!
 //! * **Nul terminators and implicit string lengths** - Often, C
-//! strings are nul-terminated, i.e. they have a `\0` character at the
+//! strings are nul-terminated, i.e., they have a `\0` character at the
 //! end. The length of a string buffer is not stored, but has to be
 //! calculated; to compute the length of a string, C code must
 //! manually call a function like `strlen()` for `char`-based strings,
@@ -72,32 +72,32 @@
 //!
 //! * **From Rust to C:** [`CString`] represents an owned, C-friendly
 //! string: it is nul-terminated, and has no internal nul characters.
-//! Rust code can create a `CString` out of a normal string (provided
+//! Rust code can create a [`CString`] out of a normal string (provided
 //! that the string doesn't have nul characters in the middle), and
-//! then use a variety of methods to obtain a raw `*mut u8` that can
+//! then use a variety of methods to obtain a raw `*mut `[`u8`] that can
 //! then be passed as an argument to functions which use the C
 //! conventions for strings.
 //!
 //! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
-//! is what you would use to wrap a raw `*const u8` that you got from
-//! a C function. A `CStr` is guaranteed to be a nul-terminated array
-//! of bytes. Once you have a `CStr`, you can convert it to a Rust
-//! `&str` if it's valid UTF-8, or lossily convert it by adding
+//! is what you would use to wrap a raw `*const `[`u8`] that you got from
+//! a C function. A [`CStr`] is guaranteed to be a nul-terminated array
+//! of bytes. Once you have a [`CStr`], you can convert it to a Rust
+//! [`&str`][`str`] if it's valid UTF-8, or lossily convert it by adding
 //! replacement characters.
 //!
 //! [`OsString`] and [`OsStr`] are useful when you need to transfer
 //! strings to and from the operating system itself, or when capturing
-//! the output of external commands. Conversions between `OsString`,
-//! `OsStr` and Rust strings work similarly to those for [`CString`]
+//! the output of external commands. Conversions between [`OsString`],
+//! [`OsStr`] and Rust strings work similarly to those for [`CString`]
 //! and [`CStr`].
 //!
 //! * [`OsString`] represents an owned string in whatever
 //! representation the operating system prefers. In the Rust standard
 //! library, various APIs that transfer strings to/from the operating
-//! system use `OsString` instead of plain strings. For example,
+//! system use [`OsString`] instead of plain strings. For example,
 //! [`env::var_os()`] is used to query environment variables; it
-//! returns an `Option<OsString>`. If the environment variable exists
-//! you will get a `Some(os_string)`, which you can *then* try to
+//! returns an [`Option`]`<`[`OsString`]`>`. If the environment variable
+//! exists you will get a [`Some`]`(os_string)`, which you can *then* try to
 //! convert to a Rust string. This yields a [`Result<>`], so that
 //! your code can detect errors in case the environment variable did
 //! not in fact contain valid Unicode data.
@@ -105,7 +105,7 @@
 //! * [`OsStr`] represents a borrowed reference to a string in a
 //! format that can be passed to the operating system. It can be
 //! converted into an UTF-8 Rust string slice in a similar way to
-//! `OsString`.
+//! [`OsString`].
 //!
 //! # Conversions
 //!
@@ -131,7 +131,7 @@
 //! Additionally, on Windows [`OsString`] implements the
 //! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
 //! trait, which provides a [`from_wide`] method. The result of this
-//! method is an `OsString` which can be round-tripped to a Windows
+//! method is an [`OsString`] which can be round-tripped to a Windows
 //! string losslessly.
 //!
 //! [`String`]: ../string/struct.String.html
@@ -160,6 +160,8 @@
 //! [`collect`]: ../iter/trait.Iterator.html#method.collect
 //! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
 //! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide
+//! [`Option`]: ../option/enum.Option.html
+//! [`Some`]: ../option/enum.Option.html#variant.Some
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -174,7 +176,6 @@
 #[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",
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 9c40a31..766142f 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -36,7 +36,7 @@
 /// and platform-native string values, and in particular allowing a Rust string
 /// to be converted into an "OS" string with no cost if possible.  A consequence
 /// of this is that `OsString` instances are *not* `NUL` terminated; in order
-/// to pass to e.g. Unix system call, you should create a [`CStr`].
+/// to pass to e.g., Unix system call, you should create a [`CStr`].
 ///
 /// `OsString` is to [`&OsStr`] as [`String`] is to [`&str`]: the former
 /// in each pair are owned strings; the latter are borrowed
@@ -536,17 +536,42 @@
     ///
     /// # Examples
     ///
-    /// Calling `to_string_lossy` on an `OsStr` with valid unicode:
+    /// Calling `to_string_lossy` on an `OsStr` with invalid unicode:
     ///
     /// ```
-    /// use std::ffi::OsStr;
+    /// // Note, due to differences in how Unix and Windows represent strings,
+    /// // we are forced to complicate this example, setting up example `OsStr`s
+    /// // with different source data and via different platform extensions.
+    /// // Understand that in reality you could end up with such example invalid
+    /// // sequences simply through collecting user command line arguments, for
+    /// // example.
     ///
-    /// let os_str = OsStr::new("foo");
-    /// assert_eq!(os_str.to_string_lossy(), "foo");
+    /// #[cfg(any(unix, target_os = "redox"))] {
+    ///     use std::ffi::OsStr;
+    ///     use std::os::unix::ffi::OsStrExt;
+    ///
+    ///     // Here, the values 0x66 and 0x6f correspond to 'f' and 'o'
+    ///     // respectively. The value 0x80 is a lone continuation byte, invalid
+    ///     // in a UTF-8 sequence.
+    ///     let source = [0x66, 0x6f, 0x80, 0x6f];
+    ///     let os_str = OsStr::from_bytes(&source[..]);
+    ///
+    ///     assert_eq!(os_str.to_string_lossy(), "fo�o");
+    /// }
+    /// #[cfg(windows)] {
+    ///     use std::ffi::OsString;
+    ///     use std::os::windows::prelude::*;
+    ///
+    ///     // Here the values 0x0066 and 0x006f correspond to 'f' and 'o'
+    ///     // respectively. The value 0xD800 is a lone surrogate half, invalid
+    ///     // in a UTF-16 sequence.
+    ///     let source = [0x0066, 0x006f, 0xD800, 0x006f];
+    ///     let os_string = OsString::from_wide(&source[..]);
+    ///     let os_str = os_string.as_os_str();
+    ///
+    ///     assert_eq!(os_str.to_string_lossy(), "fo�o");
+    /// }
     /// ```
-    ///
-    /// Had `os_str` contained invalid unicode, the `to_string_lossy` call might
-    /// have returned `"fo�"`.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_string_lossy(&self) -> Cow<str> {
         self.inner.to_string_lossy()
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 7d054a3..edcfdd9 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -195,9 +195,10 @@
 /// This module only currently provides one bit of information, [`readonly`],
 /// which is exposed on all currently supported platforms. Unix-specific
 /// functionality, such as mode bits, is available through the
-/// `os::unix::PermissionsExt` trait.
+/// [`PermissionsExt`] trait.
 ///
 /// [`readonly`]: struct.Permissions.html#method.readonly
+/// [`PermissionsExt`]: ../os/unix/fs/trait.PermissionsExt.html
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Permissions(fs_imp::FilePermissions);
@@ -1406,7 +1407,7 @@
 /// Removes a file from the filesystem.
 ///
 /// Note that there is no
-/// guarantee that the file is immediately deleted (e.g. depending on
+/// guarantee that the file is immediately deleted (e.g., depending on
 /// platform, other open file descriptors may prevent immediate removal).
 ///
 /// # Platform-specific behavior
@@ -2089,7 +2090,7 @@
     use fs::{self, File, OpenOptions};
     use io::{ErrorKind, SeekFrom};
     use path::Path;
-    use rand::{StdRng, FromEntropy, RngCore};
+    use rand::{rngs::StdRng, FromEntropy, RngCore};
     use str;
     use sys_common::io::test::{TempDir, tmpdir};
     use thread;
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 476ee3f..7ede050 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -918,7 +918,7 @@
         // some data then we *must* report that we wrote that data, so future
         // errors are ignored. We set our internal `need_flush` flag, though, in
         // case flushing fails and we need to try it first next time.
-        let n = self.inner.write(&buf[..i + 1])?;
+        let n = self.inner.write(&buf[..=i])?;
         self.need_flush = true;
         if self.flush().is_err() || n != i + 1 {
             return Ok(n)
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 14f2015..f7a9033 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -90,7 +90,7 @@
 impl<T> Cursor<T> {
     /// Creates a new cursor wrapping the provided underlying in-memory buffer.
     ///
-    /// Cursor initial position is `0` even if underlying buffer (e.g. `Vec`)
+    /// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`)
     /// is not empty. So writing to cursor starts with overwriting `Vec`
     /// content, not with appending to it.
     ///
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index 386de08..d3844eb 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -184,7 +184,7 @@
 }
 
 impl ErrorKind {
-    fn as_str(&self) -> &'static str {
+    pub(crate) fn as_str(&self) -> &'static str {
         match *self {
             ErrorKind::NotFound => "entity not found",
             ErrorKind::PermissionDenied => "permission denied",
@@ -555,6 +555,7 @@
         }
     }
 
+    #[allow(deprecated)]
     fn cause(&self) -> Option<&dyn error::Error> {
         match self.repr {
             Repr::Os(..) => None,
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 076524e..dc97701 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -1261,7 +1261,7 @@
             };
             match memchr::memchr(delim, available) {
                 Some(i) => {
-                    buf.extend_from_slice(&available[..i + 1]);
+                    buf.extend_from_slice(&available[..=i]);
                     (true, i + 1)
                 }
                 None => {
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index a413432..8c03f35 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -131,7 +131,7 @@
 ///
 /// Each handle is a shared reference to a global buffer of input data to this
 /// process. A handle can be `lock`'d to gain full access to [`BufRead`] methods
-/// (e.g. `.lines()`). Reads to this handle are otherwise locked with respect
+/// (e.g., `.lines()`). Reads to this handle are otherwise locked with respect
 /// to other reads.
 ///
 /// This handle implements the `Read` trait, but beware that concurrent reads
@@ -269,7 +269,7 @@
     ///
     /// You can run the example one of two ways:
     ///
-    /// - Pipe some text to it, e.g. `printf foo | path/to/executable`
+    /// - Pipe some text to it, e.g., `printf foo | path/to/executable`
     /// - Give it text interactively by running the executable directly,
     ///   in which case it will wait for the Enter key to be pressed before
     ///   continuing
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index c1eaf29..12b6031 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -188,7 +188,7 @@
 /// For external connections in Rust code.
 ///
 /// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`]
-/// keyword to make your Rust code aware of other Rust crates in your project, i.e. `extern crate
+/// keyword to make your Rust code aware of other Rust crates in your project, i.e., `extern crate
 /// lazy_static;`. The other use is in foreign function interfaces (FFI).
 ///
 /// `extern` is used in two different contexts within FFI. The first is in the form of external
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 78109a1..0febbe5 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -271,6 +271,7 @@
 #![feature(libc)]
 #![feature(link_args)]
 #![feature(linkage)]
+#![cfg_attr(not(stage0), feature(min_const_unsafe_fn))]
 #![feature(needs_panic_runtime)]
 #![feature(never_type)]
 #![feature(nll)]
@@ -287,7 +288,7 @@
 #![feature(rustc_attrs)]
 #![feature(rustc_const_unstable)]
 #![feature(std_internals)]
-#![cfg_attr(not(stage0), feature(stdsimd))]
+#![feature(stdsimd)]
 #![feature(shrink_to)]
 #![feature(slice_concat_ext)]
 #![feature(slice_internals)]
@@ -312,13 +313,11 @@
 #![feature(non_exhaustive)]
 #![feature(alloc_layout_extra)]
 #![feature(maybe_uninit)]
+#![cfg_attr(target_env = "sgx", feature(global_asm, range_contains, slice_index_methods,
+                                        decl_macro, coerce_unsized))]
 
 #![default_lib_allocator]
 
-#[cfg(stage0)]
-#[global_allocator]
-static ALLOC: alloc::System = alloc::System;
-
 // Explicitly import the prelude. The compiler uses this same unstable attribute
 // to import the prelude implicitly when building crates that depend on std.
 #[prelude_import]
@@ -354,6 +353,12 @@
 // testing gives test-std access to real-std lang items and globals. See #2912
 #[cfg(test)] extern crate std as realstd;
 
+#[cfg(target_env = "sgx")]
+#[macro_use]
+#[allow(unused_imports)] // FIXME: without `#[macro_use]`, get error: “cannot
+                         // determine resolution for the macro `usercalls_asm`”
+extern crate fortanix_sgx_abi;
+
 // The standard macros that are not built-in to the compiler.
 #[macro_use]
 mod macros;
@@ -506,18 +511,17 @@
 #[path = "../stdsimd/stdsimd/mod.rs"]
 #[allow(missing_debug_implementations, missing_docs, dead_code)]
 #[unstable(feature = "stdsimd", issue = "48556")]
-#[cfg(all(not(stage0), not(test)))]
+#[cfg(not(test))]
 mod stdsimd;
 
 // A "fake" module needed by the `stdsimd` module to compile, not actually
 // exported though.
-#[cfg(not(stage0))]
 mod coresimd {
     pub use core::arch;
 }
 
 #[stable(feature = "simd_arch", since = "1.27.0")]
-#[cfg(all(not(stage0), not(test)))]
+#[cfg(not(test))]
 pub use stdsimd::arch;
 
 // Include a number of private modules that exist solely to provide
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index ff35325..21def5d 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -16,10 +16,11 @@
 use option;
 use sys::net::netc as c;
 use sys_common::{FromInner, AsInner, IntoInner};
-use sys_common::net::lookup_host;
+use sys_common::net::LookupHost;
 use vec;
 use iter;
 use slice;
+use convert::TryInto;
 
 /// An internet socket address, either IPv4 or IPv6.
 ///
@@ -702,7 +703,7 @@
 /// the other: for simple uses a string like `"localhost:12345"` is much nicer
 /// than manual construction of the corresponding [`SocketAddr`], but sometimes
 /// [`SocketAddr`] value is *the* main source of the address, and converting it to
-/// some other type (e.g. a string) just for it to be converted back to
+/// some other type (e.g., a string) just for it to be converted back to
 /// [`SocketAddr`] in constructor methods is pointless.
 ///
 /// Addresses returned by the operating system that are not IP addresses are
@@ -863,9 +864,9 @@
     }
 }
 
-fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
-    let ips = lookup_host(s)?;
-    let v: Vec<_> = ips.map(|mut a| { a.set_port(p); a }).collect();
+fn resolve_socket_addr(lh: LookupHost) -> io::Result<vec::IntoIter<SocketAddr>> {
+    let p = lh.port();
+    let v: Vec<_> = lh.map(|mut a| { a.set_port(p); a }).collect();
     Ok(v.into_iter())
 }
 
@@ -885,7 +886,7 @@
             return Ok(vec![SocketAddr::V6(addr)].into_iter())
         }
 
-        resolve_socket_addr(host, port)
+        resolve_socket_addr((host, port).try_into()?)
     }
 }
 
@@ -899,22 +900,7 @@
             return Ok(vec![addr].into_iter());
         }
 
-        macro_rules! try_opt {
-            ($e:expr, $msg:expr) => (
-                match $e {
-                    Some(r) => r,
-                    None => return Err(io::Error::new(io::ErrorKind::InvalidInput,
-                                                      $msg)),
-                }
-            )
-        }
-
-        // split the string by ':' and convert the second part to u16
-        let mut parts_iter = self.rsplitn(2, ':');
-        let port_str = try_opt!(parts_iter.next(), "invalid socket address");
-        let host = try_opt!(parts_iter.next(), "invalid socket address");
-        let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
-        resolve_socket_addr(host, port)
+        resolve_socket_addr(self.try_into()?)
     }
 }
 
diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs
index be4bcee..ff579a5 100644
--- a/src/libstd/net/mod.rs
+++ b/src/libstd/net/mod.rs
@@ -112,11 +112,15 @@
 fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) }
 
 fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
-    where F: FnMut(&SocketAddr) -> io::Result<T>
+    where F: FnMut(io::Result<&SocketAddr>) -> io::Result<T>
 {
+    let addrs = match addr.to_socket_addrs() {
+        Ok(addrs) => addrs,
+        Err(e) => return f(Err(e))
+    };
     let mut last_err = None;
-    for addr in addr.to_socket_addrs()? {
-        match f(&addr) {
+    for addr in addrs {
+        match f(Ok(&addr)) {
             Ok(l) => return Ok(l),
             Err(e) => last_err = Some(e),
         }
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index be79780..5aa043b 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -530,7 +530,7 @@
     /// Moves this TCP stream into or out of nonblocking mode.
     ///
     /// This will result in `read`, `write`, `recv` and `send` operations
-    /// becoming nonblocking, i.e. immediately returning from their calls.
+    /// becoming nonblocking, i.e., immediately returning from their calls.
     /// If the IO operation is successful, `Ok` is returned and no further
     /// action is required. If the IO operation could not be completed and needs
     /// to be retried, an error with kind [`io::ErrorKind::WouldBlock`] is
@@ -840,7 +840,7 @@
     /// Moves this TCP stream into or out of nonblocking mode.
     ///
     /// This will result in the `accept` operation becoming nonblocking,
-    /// i.e. immediately returning from their calls. If the IO operation is
+    /// i.e., immediately returning from their calls. If the IO operation is
     /// successful, `Ok` is returned and no further action is required. If the
     /// IO operation could not be completed and needs to be retried, an error
     /// with kind [`io::ErrorKind::WouldBlock`] is returned.
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index fc68aba..6c0c636 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -752,7 +752,7 @@
     /// Moves this UDP socket into or out of nonblocking mode.
     ///
     /// This will result in `recv`, `recv_from`, `send`, and `send_to`
-    /// operations becoming nonblocking, i.e. immediately returning from their
+    /// operations becoming nonblocking, i.e., immediately returning from their
     /// calls. If the IO operation is successful, `Ok` is returned and no
     /// further action is required. If the IO operation could not be completed
     /// and needs to be retried, an error with kind
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 4bc18a5..3eacc7a 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -80,7 +80,7 @@
 /// Simply put, a type `T` implements `UnwindSafe` if it cannot easily allow
 /// witnessing a broken invariant through the use of `catch_unwind` (catching a
 /// panic). This trait is an auto trait, so it is automatically implemented for
-/// many types, and it is also structurally composed (e.g. a struct is unwind
+/// many types, and it is also structurally composed (e.g., a struct is unwind
 /// safe if all of its components are unwind safe).
 ///
 /// Note, however, that this is not an unsafe trait, so there is not a succinct
@@ -264,7 +264,7 @@
 #[cfg(target_has_atomic = "64")]
 #[unstable(feature = "integer_atomics", issue = "32976")]
 impl RefUnwindSafe for atomic::AtomicI64 {}
-#[cfg(all(not(stage0), target_has_atomic = "128"))]
+#[cfg(target_has_atomic = "128")]
 #[unstable(feature = "integer_atomics", issue = "32976")]
 impl RefUnwindSafe for atomic::AtomicI128 {}
 
@@ -283,7 +283,7 @@
 #[cfg(target_has_atomic = "64")]
 #[unstable(feature = "integer_atomics", issue = "32976")]
 impl RefUnwindSafe for atomic::AtomicU64 {}
-#[cfg(all(not(stage0), target_has_atomic = "128"))]
+#[cfg(target_has_atomic = "128")]
 #[unstable(feature = "integer_atomics", issue = "32976")]
 impl RefUnwindSafe for atomic::AtomicU128 {}
 
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 4930d35..b6180fb 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -29,7 +29,7 @@
 use mem;
 use ptr;
 use raw;
-use sys::stdio::{Stderr, stderr_prints_nothing};
+use sys::stdio::panic_output;
 use sys_common::rwlock::RWLock;
 use sys_common::thread_info;
 use sys_common::util;
@@ -193,7 +193,6 @@
             None => "Box<Any>",
         }
     };
-    let mut err = Stderr::new().ok();
     let thread = thread_info::current_thread();
     let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
 
@@ -210,22 +209,20 @@
             if let Some(format) = log_backtrace {
                 let _ = backtrace::print(err, format);
             } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
-                let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` for a backtrace.");
+                let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` \
+                                       environment variable to display a backtrace.");
             }
         }
     };
 
-    let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
-    match (prev, err.as_mut()) {
-       (Some(mut stderr), _) => {
-           write(&mut *stderr);
-           let mut s = Some(stderr);
-           LOCAL_STDERR.with(|slot| {
-               *slot.borrow_mut() = s.take();
-           });
-       }
-       (None, Some(ref mut err)) => { write(err) }
-       _ => {}
+    if let Some(mut local) = LOCAL_STDERR.with(|s| s.borrow_mut().take()) {
+       write(&mut *local);
+       let mut s = Some(local);
+       LOCAL_STDERR.with(|slot| {
+           *slot.borrow_mut() = s.take();
+       });
+    } else if let Some(mut out) = panic_output() {
+        write(&mut out);
     }
 }
 
@@ -464,7 +461,7 @@
 
     let panics = update_panic_count(1);
 
-    // If this is the third nested call (e.g. panics == 2, this is 0-indexed),
+    // If this is the third nested call (e.g., panics == 2, this is 0-indexed),
     // the panic hook probably triggered the last panic, otherwise the
     // double-panic check would have aborted the process. In this case abort the
     // process real quickly as we don't want to try calling it again as it'll
@@ -485,7 +482,7 @@
             // Some platforms know that printing to stderr won't ever actually
             // print anything, and if that's the case we can skip the default
             // hook.
-            Hook::Default if stderr_prints_nothing() => {}
+            Hook::Default if panic_output().is_none() => {}
             Hook::Default => {
                 info.set_payload(payload.get());
                 default_hook(&info);
@@ -494,7 +491,7 @@
                 info.set_payload(payload.get());
                 (*ptr)(&info);
             }
-        }
+        };
         HOOK_LOCK.read_unlock();
     }
 
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 9fad40c..b882442 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -109,11 +109,11 @@
 // Windows Prefixes
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Windows path prefixes, e.g. `C:` or `\\server\share`.
+/// Windows path prefixes, e.g., `C:` or `\\server\share`.
 ///
 /// Windows uses a variety of path prefix styles, including references to drive
 /// volumes (like `C:`), network shared folders (like `\\server\share`), and
-/// others. In addition, some path prefixes are "verbatim" (i.e. prefixed with
+/// others. In addition, some path prefixes are "verbatim" (i.e., prefixed with
 /// `\\?\`), in which case `/` is *not* treated as a separator and essentially
 /// no normalization is performed.
 ///
@@ -148,7 +148,7 @@
 #[derive(Copy, Clone, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Prefix<'a> {
-    /// Verbatim prefix, e.g. `\\?\cat_pics`.
+    /// Verbatim prefix, e.g., `\\?\cat_pics`.
     ///
     /// Verbatim prefixes consist of `\\?\` immediately followed by the given
     /// component.
@@ -156,7 +156,7 @@
     Verbatim(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
 
     /// Verbatim prefix using Windows' _**U**niform **N**aming **C**onvention_,
-    /// e.g. `\\?\UNC\server\share`.
+    /// e.g., `\\?\UNC\server\share`.
     ///
     /// Verbatim UNC prefixes consist of `\\?\UNC\` immediately followed by the
     /// server's hostname and a share name.
@@ -166,14 +166,14 @@
         #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
     ),
 
-    /// Verbatim disk prefix, e.g. `\\?\C:\`.
+    /// Verbatim disk prefix, e.g., `\\?\C:\`.
     ///
     /// Verbatim disk prefixes consist of `\\?\` immediately followed by the
     /// drive letter and `:\`.
     #[stable(feature = "rust1", since = "1.0.0")]
     VerbatimDisk(#[stable(feature = "rust1", since = "1.0.0")] u8),
 
-    /// Device namespace prefix, e.g. `\\.\COM42`.
+    /// Device namespace prefix, e.g., `\\.\COM42`.
     ///
     /// Device namespace prefixes consist of `\\.\` immediately followed by the
     /// device name.
@@ -227,7 +227,7 @@
 
     }
 
-    /// Determines if the prefix is verbatim, i.e. begins with `\\?\`.
+    /// Determines if the prefix is verbatim, i.e., begins with `\\?\`.
     ///
     /// # Examples
     ///
@@ -509,7 +509,7 @@
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Component<'a> {
-    /// A Windows path prefix, e.g. `C:` or `\\server\share`.
+    /// A Windows path prefix, e.g., `C:` or `\\server\share`.
     ///
     /// There is a large variety of prefix types, see [`Prefix`]'s documentation
     /// for more.
@@ -528,15 +528,15 @@
     #[stable(feature = "rust1", since = "1.0.0")]
     RootDir,
 
-    /// A reference to the current directory, i.e. `.`.
+    /// A reference to the current directory, i.e., `.`.
     #[stable(feature = "rust1", since = "1.0.0")]
     CurDir,
 
-    /// A reference to the parent directory, i.e. `..`.
+    /// A reference to the parent directory, i.e., `..`.
     #[stable(feature = "rust1", since = "1.0.0")]
     ParentDir,
 
-    /// A normal component, e.g. `a` and `b` in `a/b`.
+    /// A normal component, e.g., `a` and `b` in `a/b`.
     ///
     /// This variant is the most common one, it represents references to files
     /// or directories.
@@ -615,7 +615,7 @@
 
     // true if path *physically* has a root separator; for most Windows
     // prefixes, it may have a "logical" rootseparator for the purposes of
-    // normalization, e.g.  \\server\share == \\server\share\.
+    // normalization, e.g.,  \\server\share == \\server\share\.
     has_physical_root: bool,
 
     // The iterator is double-ended, and these two states keep track of what has
@@ -798,7 +798,7 @@
         (comp.len() + extra, self.parse_single_component(comp))
     }
 
-    // trim away repeated separators (i.e. empty components) on the left
+    // trim away repeated separators (i.e., empty components) on the left
     fn trim_left(&mut self) {
         while !self.path.is_empty() {
             let (size, comp) = self.parse_next_component();
@@ -810,7 +810,7 @@
         }
     }
 
-    // trim away repeated separators (i.e. empty components) on the right
+    // trim away repeated separators (i.e., empty components) on the right
     fn trim_right(&mut self) {
         while self.path.len() > self.len_before_body() {
             let (size, comp) = self.parse_next_component_back();
@@ -1178,7 +1178,7 @@
     ///
     /// On Windows:
     ///
-    /// * if `path` has a root but no prefix (e.g. `\windows`), it
+    /// * if `path` has a root but no prefix (e.g., `\windows`), it
     ///   replaces everything except for the prefix (if any) of `self`.
     /// * if `path` has a prefix but no root, it replaces `self`.
     ///
@@ -1225,7 +1225,7 @@
         if path.is_absolute() || path.prefix().is_some() {
             self.as_mut_vec().truncate(0);
 
-        // `path` has a root but no prefix, e.g. `\windows` (Windows only)
+        // `path` has a root but no prefix, e.g., `\windows` (Windows only)
         } else if path.has_root() {
             let prefix_len = self.components().prefix_remaining();
             self.as_mut_vec().truncate(prefix_len);
@@ -1810,7 +1810,7 @@
         PathBuf::from(self.inner.to_os_string())
     }
 
-    /// Returns `true` if the `Path` is absolute, i.e. if it is independent of
+    /// Returns `true` if the `Path` is absolute, i.e., if it is independent of
     /// the current directory.
     ///
     /// * On Unix, a path is absolute if it starts with the root, so
@@ -1839,7 +1839,7 @@
         }
     }
 
-    /// Returns `true` if the `Path` is relative, i.e. not absolute.
+    /// Returns `true` if the `Path` is relative, i.e., not absolute.
     ///
     /// See [`is_absolute`]'s documentation for more details.
     ///
@@ -1866,9 +1866,9 @@
     /// * On Unix, a path has a root if it begins with `/`.
     ///
     /// * On Windows, a path has a root if it:
-    ///     * has no prefix and begins with a separator, e.g. `\windows`
-    ///     * has a prefix followed by a separator, e.g. `c:\windows` but not `c:windows`
-    ///     * has any non-disk prefix, e.g. `\\server\share`
+    ///     * has no prefix and begins with a separator, e.g., `\windows`
+    ///     * has a prefix followed by a separator, e.g., `c:\windows` but not `c:windows`
+    ///     * has any non-disk prefix, e.g., `\\server\share`
     ///
     /// # Examples
     ///
@@ -1980,7 +1980,7 @@
     ///
     /// # Errors
     ///
-    /// If `base` is not a prefix of `self` (i.e. [`starts_with`]
+    /// If `base` is not a prefix of `self` (i.e., [`starts_with`]
     /// returns `false`), returns [`Err`].
     ///
     /// [`starts_with`]: #method.starts_with
@@ -2406,7 +2406,7 @@
     /// This function will traverse symbolic links to query information about the
     /// destination file. In case of broken symbolic links this will return `false`.
     ///
-    /// If you cannot access the directory containing the file, e.g. because of a
+    /// If you cannot access the directory containing the file, e.g., because of a
     /// permission error, this will return `false`.
     ///
     /// # Examples
@@ -2432,7 +2432,7 @@
     /// This function will traverse symbolic links to query information about the
     /// destination file. In case of broken symbolic links this will return `false`.
     ///
-    /// If you cannot access the directory containing the file, e.g. because of a
+    /// If you cannot access the directory containing the file, e.g., because of a
     /// permission error, this will return `false`.
     ///
     /// # Examples
@@ -2461,7 +2461,7 @@
     /// This function will traverse symbolic links to query information about the
     /// destination file. In case of broken symbolic links this will return `false`.
     ///
-    /// If you cannot access the directory containing the file, e.g. because of a
+    /// If you cannot access the directory containing the file, e.g., because of a
     /// permission error, this will return `false`.
     ///
     /// # Examples
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index 48acc10..7c1654f 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -426,7 +426,7 @@
 /// ## 3. Get it from C.
 ///
 /// ```
-/// # #![feature(libc)]
+/// # #![feature(rustc_private)]
 /// extern crate libc;
 ///
 /// use std::mem;
@@ -462,7 +462,7 @@
 ///
 /// There are two syntactic forms for creating an array:
 ///
-/// * A list with each element, i.e. `[x, y, z]`.
+/// * A list with each element, i.e., `[x, y, z]`.
 /// * A repeat expression `[x; N]`, which produces an array with `N` copies of `x`.
 ///   The type of `x` must be [`Copy`][copy].
 ///
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 2d08482..b42ad29 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -628,7 +628,7 @@
     ///
     /// # Platform-specific behavior
     ///
-    /// If the program path is relative (e.g. `"./script.sh"`), it's ambiguous
+    /// If the program path is relative (e.g., `"./script.sh"`), it's ambiguous
     /// whether it should be interpreted relative to the parent's working
     /// directory or relative to `current_dir`. The behavior in this case is
     /// platform specific and unstable, and it's recommended to use
diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs
index a7db372..81356e6 100644
--- a/src/libstd/sync/mod.rs
+++ b/src/libstd/sync/mod.rs
@@ -89,7 +89,7 @@
 //!
 //! - A **single processor** executing instructions [out-of-order]:
 //!   Modern CPUs are capable of [superscalar] execution,
-//!   i.e. multiple instructions might be executing at the same time,
+//!   i.e., multiple instructions might be executing at the same time,
 //!   even though the machine code describes a sequential process.
 //!
 //!   This kind of reordering is handled transparently by the CPU.
diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs
index 90f12c8..dc80f56 100644
--- a/src/libstd/sync/mpsc/sync.rs
+++ b/src/libstd/sync/mpsc/sync.rs
@@ -292,7 +292,7 @@
             }
         }
 
-        // NB: Channel could be disconnected while waiting, so the order of
+        // N.B., channel could be disconnected while waiting, so the order of
         // these conditionals is important.
         if guard.disconnected && guard.buf.size() == 0 {
             return Err(Disconnected);
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index cf9698c..13e0d2e 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -189,7 +189,7 @@
     /// static INIT: Once = Once::new();
     ///
     /// // Accessing a `static mut` is unsafe much of the time, but if we do so
-    /// // in a synchronized fashion (e.g. write once or read all) then we're
+    /// // in a synchronized fashion (e.g., write once or read all) then we're
     /// // good to go!
     /// //
     /// // This function will only call `expensive_computation` once, and will
@@ -232,7 +232,7 @@
 
     /// Performs the same function as [`call_once`] except ignores poisoning.
     ///
-    /// Unlike [`call_once`], if this `Once` has been poisoned (i.e. a previous
+    /// Unlike [`call_once`], if this `Once` has been poisoned (i.e., a previous
     /// call to `call_once` or `call_once_force` caused a panic), calling
     /// `call_once_force` will still invoke the closure `f` and will _not_
     /// result in an immediate panic. If `f` panics, the `Once` will remain
diff --git a/src/libstd/sys/cloudabi/condvar.rs b/src/libstd/sys/cloudabi/condvar.rs
index ccf848a..3229d98 100644
--- a/src/libstd/sys/cloudabi/condvar.rs
+++ b/src/libstd/sys/cloudabi/condvar.rs
@@ -13,7 +13,7 @@
 use sync::atomic::{AtomicU32, Ordering};
 use sys::cloudabi::abi;
 use sys::mutex::{self, Mutex};
-use sys::time::dur2intervals;
+use sys::time::checked_dur2intervals;
 use time::Duration;
 
 extern "C" {
@@ -114,6 +114,8 @@
 
         // Call into the kernel to wait on the condition variable.
         let condvar = self.condvar.get();
+        let timeout = checked_dur2intervals(&dur)
+            .expect("overflow converting duration to nanoseconds");
         let subscriptions = [
             abi::subscription {
                 type_: abi::eventtype::CONDVAR,
@@ -132,7 +134,7 @@
                 union: abi::subscription_union {
                     clock: abi::subscription_clock {
                         clock_id: abi::clockid::MONOTONIC,
-                        timeout: dur2intervals(&dur),
+                        timeout,
                         ..mem::zeroed()
                     },
                 },
diff --git a/src/libstd/sys/cloudabi/shims/net.rs b/src/libstd/sys/cloudabi/shims/net.rs
index 93eaf6a..7229e71 100644
--- a/src/libstd/sys/cloudabi/shims/net.rs
+++ b/src/libstd/sys/cloudabi/shims/net.rs
@@ -13,13 +13,14 @@
 use net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
 use time::Duration;
 use sys::{unsupported, Void};
+use convert::TryFrom;
 
 pub extern crate libc as netc;
 
 pub struct TcpStream(Void);
 
 impl TcpStream {
-    pub fn connect(_: &SocketAddr) -> io::Result<TcpStream> {
+    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
         unsupported()
     }
 
@@ -105,7 +106,7 @@
 pub struct TcpListener(Void);
 
 impl TcpListener {
-    pub fn bind(_: &SocketAddr) -> io::Result<TcpListener> {
+    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
         unsupported()
     }
 
@@ -155,7 +156,7 @@
 pub struct UdpSocket(Void);
 
 impl UdpSocket {
-    pub fn bind(_: &SocketAddr) -> io::Result<UdpSocket> {
+    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
         unsupported()
     }
 
@@ -271,7 +272,7 @@
         match self.0 {}
     }
 
-    pub fn connect(&self, _: &SocketAddr) -> io::Result<()> {
+    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
         match self.0 {}
     }
 }
@@ -284,6 +285,12 @@
 
 pub struct LookupHost(Void);
 
+impl LookupHost {
+    pub fn port(&self) -> u16 {
+        match self.0 {}
+    }
+}
+
 impl Iterator for LookupHost {
     type Item = SocketAddr;
     fn next(&mut self) -> Option<SocketAddr> {
@@ -291,6 +298,18 @@
     }
 }
 
-pub fn lookup_host(_: &str) -> io::Result<LookupHost> {
-    unsupported()
+impl<'a> TryFrom<&'a str> for LookupHost {
+    type Error = io::Error;
+
+    fn try_from(_v: &'a str) -> io::Result<LookupHost> {
+        unsupported()
+    }
+}
+
+impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
+    type Error = io::Error;
+
+    fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
+        unsupported()
+    }
 }
diff --git a/src/libstd/sys/cloudabi/stdio.rs b/src/libstd/sys/cloudabi/stdio.rs
index 1d7344f..c90dbd8 100644
--- a/src/libstd/sys/cloudabi/stdio.rs
+++ b/src/libstd/sys/cloudabi/stdio.rs
@@ -78,6 +78,6 @@
 
 pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;
 
-pub fn stderr_prints_nothing() -> bool {
-    false
+pub fn panic_output() -> Option<impl io::Write> {
+    Stderr::new().ok()
 }
diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs
index 8cca47e..1773214 100644
--- a/src/libstd/sys/cloudabi/thread.rs
+++ b/src/libstd/sys/cloudabi/thread.rs
@@ -16,7 +16,7 @@
 use mem;
 use ptr;
 use sys::cloudabi::abi;
-use sys::time::dur2intervals;
+use sys::time::checked_dur2intervals;
 use sys_common::thread::*;
 use time::Duration;
 
@@ -32,7 +32,8 @@
 unsafe impl Sync for Thread {}
 
 impl Thread {
-    pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> {
+    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
+    pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>) -> io::Result<Thread> {
         let p = box p;
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
@@ -69,13 +70,15 @@
     }
 
     pub fn sleep(dur: Duration) {
+        let timeout = checked_dur2intervals(&dur)
+            .expect("overflow converting duration to nanoseconds");
         unsafe {
             let subscription = abi::subscription {
                 type_: abi::eventtype::CLOCK,
                 union: abi::subscription_union {
                     clock: abi::subscription_clock {
                         clock_id: abi::clockid::MONOTONIC,
-                        timeout: dur2intervals(&dur),
+                        timeout,
                         ..mem::zeroed()
                     },
                 },
diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs
index a442d1e..c9fea18 100644
--- a/src/libstd/sys/cloudabi/time.rs
+++ b/src/libstd/sys/cloudabi/time.rs
@@ -19,15 +19,10 @@
     t: abi::timestamp,
 }
 
-fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> {
+pub fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> {
     dur.as_secs()
-        .checked_mul(NSEC_PER_SEC)
-        .and_then(|nanos| nanos.checked_add(dur.subsec_nanos() as abi::timestamp))
-}
-
-pub fn dur2intervals(dur: &Duration) -> abi::timestamp {
-    checked_dur2intervals(dur)
-        .expect("overflow converting duration to nanoseconds")
+        .checked_mul(NSEC_PER_SEC)?
+        .checked_add(dur.subsec_nanos() as abi::timestamp)
 }
 
 impl Instant {
@@ -47,20 +42,16 @@
         Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32)
     }
 
-    pub fn add_duration(&self, other: &Duration) -> Instant {
-        Instant {
-            t: self.t
-                .checked_add(dur2intervals(other))
-                .expect("overflow when adding duration to instant"),
-        }
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
+        Some(Instant {
+            t: self.t.checked_add(checked_dur2intervals(other)?)?,
+        })
     }
 
-    pub fn sub_duration(&self, other: &Duration) -> Instant {
-        Instant {
-            t: self.t
-                .checked_sub(dur2intervals(other))
-                .expect("overflow when subtracting duration from instant"),
-        }
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
+        Some(Instant {
+            t: self.t.checked_sub(checked_dur2intervals(other)?)?,
+        })
     }
 }
 
@@ -95,23 +86,16 @@
         }
     }
 
-    pub fn add_duration(&self, other: &Duration) -> SystemTime {
-        self.checked_add_duration(other)
-            .expect("overflow when adding duration to instant")
-    }
-
     pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-        checked_dur2intervals(other)
-            .and_then(|d| self.t.checked_add(d))
-            .map(|t| SystemTime {t})
+        Some(SystemTime {
+            t: self.t.checked_add(checked_dur2intervals(other)?)?,
+        })
     }
 
-    pub fn sub_duration(&self, other: &Duration) -> SystemTime {
-        SystemTime {
-            t: self.t
-                .checked_sub(dur2intervals(other))
-                .expect("overflow when subtracting duration from instant"),
-        }
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+        Some(SystemTime {
+            t: self.t.checked_sub(checked_dur2intervals(other)?)?,
+        })
     }
 }
 
diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs
index 61e4ce6..04c47ae 100644
--- a/src/libstd/sys/mod.rs
+++ b/src/libstd/sys/mod.rs
@@ -48,6 +48,9 @@
     } else if #[cfg(target_arch = "wasm32")] {
         mod wasm;
         pub use self::wasm::*;
+    } else if #[cfg(target_env = "sgx")] {
+        mod sgx;
+        pub use self::sgx::*;
     } else {
         compile_error!("libstd doesn't compile for this platform yet");
     }
diff --git a/src/libstd/sys/redox/net/mod.rs b/src/libstd/sys/redox/net/mod.rs
index 67f2223..04a183f 100644
--- a/src/libstd/sys/redox/net/mod.rs
+++ b/src/libstd/sys/redox/net/mod.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use fs::File;
-use io::{Error, Result, Read};
+use io::{Error, Read, self};
 use iter::Iterator;
 use net::{Ipv4Addr, SocketAddr, SocketAddrV4};
 use str::FromStr;
@@ -17,6 +17,7 @@
 use sys::syscall::EINVAL;
 use time::{self, Duration};
 use vec::{IntoIter, Vec};
+use convert::{TryFrom, TryInto};
 
 use self::dns::{Dns, DnsQuery};
 
@@ -29,7 +30,13 @@
 mod tcp;
 mod udp;
 
-pub struct LookupHost(IntoIter<SocketAddr>);
+pub struct LookupHost(IntoIter<SocketAddr>, u16);
+
+impl LookupHost {
+    pub fn port(&self) -> u16 {
+        self.1
+    }
+}
 
 impl Iterator for LookupHost {
     type Item = SocketAddr;
@@ -38,65 +45,93 @@
     }
 }
 
-pub fn lookup_host(host: &str) -> Result<LookupHost> {
-    let mut ip_string = String::new();
-    File::open("/etc/net/ip")?.read_to_string(&mut ip_string)?;
-    let ip: Vec<u8> = ip_string.trim().split('.').map(|part| part.parse::<u8>()
-                               .unwrap_or(0)).collect();
+impl<'a> TryFrom<&'a str> for LookupHost {
+    type Error = io::Error;
 
-    let mut dns_string = String::new();
-    File::open("/etc/net/dns")?.read_to_string(&mut dns_string)?;
-    let dns: Vec<u8> = dns_string.trim().split('.').map(|part| part.parse::<u8>()
-                                 .unwrap_or(0)).collect();
-
-    if ip.len() == 4 && dns.len() == 4 {
-        let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap();
-        let tid = (time.subsec_nanos() >> 16) as u16;
-
-        let packet = Dns {
-            transaction_id: tid,
-            flags: 0x0100,
-            queries: vec![DnsQuery {
-                name: host.to_string(),
-                q_type: 0x0001,
-                q_class: 0x0001,
-            }],
-            answers: vec![]
-        };
-
-        let packet_data = packet.compile();
-
-        let my_ip = Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]);
-        let dns_ip = Ipv4Addr::new(dns[0], dns[1], dns[2], dns[3]);
-        let socket = UdpSocket::bind(&SocketAddr::V4(SocketAddrV4::new(my_ip, 0)))?;
-        socket.set_read_timeout(Some(Duration::new(5, 0)))?;
-        socket.set_write_timeout(Some(Duration::new(5, 0)))?;
-        socket.connect(&SocketAddr::V4(SocketAddrV4::new(dns_ip, 53)))?;
-        socket.send(&packet_data)?;
-
-        let mut buf = [0; 65536];
-        let count = socket.recv(&mut buf)?;
-
-        match Dns::parse(&buf[.. count]) {
-            Ok(response) => {
-                let mut addrs = vec![];
-                for answer in response.answers.iter() {
-                    if answer.a_type == 0x0001 && answer.a_class == 0x0001
-                       && answer.data.len() == 4
-                    {
-                        let answer_ip = Ipv4Addr::new(answer.data[0],
-                                                      answer.data[1],
-                                                      answer.data[2],
-                                                      answer.data[3]);
-                        addrs.push(SocketAddr::V4(SocketAddrV4::new(answer_ip, 0)));
-                    }
+    fn try_from(s: &str) -> io::Result<LookupHost> {
+        macro_rules! try_opt {
+            ($e:expr, $msg:expr) => (
+                match $e {
+                    Some(r) => r,
+                    None => return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                                      $msg)),
                 }
-                Ok(LookupHost(addrs.into_iter()))
-            },
-            Err(_err) => Err(Error::from_raw_os_error(EINVAL))
+            )
         }
-    } else {
-        Err(Error::from_raw_os_error(EINVAL))
+
+        // split the string by ':' and convert the second part to u16
+        let mut parts_iter = s.rsplitn(2, ':');
+        let port_str = try_opt!(parts_iter.next(), "invalid socket address");
+        let host = try_opt!(parts_iter.next(), "invalid socket address");
+        let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
+
+        (host, port).try_into()
+    }
+}
+
+impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
+    type Error = io::Error;
+
+    fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
+        let mut ip_string = String::new();
+        File::open("/etc/net/ip")?.read_to_string(&mut ip_string)?;
+        let ip: Vec<u8> = ip_string.trim().split('.').map(|part| part.parse::<u8>()
+                                   .unwrap_or(0)).collect();
+
+        let mut dns_string = String::new();
+        File::open("/etc/net/dns")?.read_to_string(&mut dns_string)?;
+        let dns: Vec<u8> = dns_string.trim().split('.').map(|part| part.parse::<u8>()
+                                     .unwrap_or(0)).collect();
+
+        if ip.len() == 4 && dns.len() == 4 {
+            let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap();
+            let tid = (time.subsec_nanos() >> 16) as u16;
+
+            let packet = Dns {
+                transaction_id: tid,
+                flags: 0x0100,
+                queries: vec![DnsQuery {
+                    name: host.to_string(),
+                    q_type: 0x0001,
+                    q_class: 0x0001,
+                }],
+                answers: vec![]
+            };
+
+            let packet_data = packet.compile();
+
+            let my_ip = Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]);
+            let dns_ip = Ipv4Addr::new(dns[0], dns[1], dns[2], dns[3]);
+            let socket = UdpSocket::bind(Ok(&SocketAddr::V4(SocketAddrV4::new(my_ip, 0))))?;
+            socket.set_read_timeout(Some(Duration::new(5, 0)))?;
+            socket.set_write_timeout(Some(Duration::new(5, 0)))?;
+            socket.connect(Ok(&SocketAddr::V4(SocketAddrV4::new(dns_ip, 53))))?;
+            socket.send(&packet_data)?;
+
+            let mut buf = [0; 65536];
+            let count = socket.recv(&mut buf)?;
+
+            match Dns::parse(&buf[.. count]) {
+                Ok(response) => {
+                    let mut addrs = vec![];
+                    for answer in response.answers.iter() {
+                        if answer.a_type == 0x0001 && answer.a_class == 0x0001
+                           && answer.data.len() == 4
+                        {
+                            let answer_ip = Ipv4Addr::new(answer.data[0],
+                                                          answer.data[1],
+                                                          answer.data[2],
+                                                          answer.data[3]);
+                            addrs.push(SocketAddr::V4(SocketAddrV4::new(answer_ip, 0)));
+                        }
+                    }
+                    Ok(LookupHost(addrs.into_iter(), port))
+                },
+                Err(_err) => Err(Error::from_raw_os_error(EINVAL))
+            }
+        } else {
+            Err(Error::from_raw_os_error(EINVAL))
+        }
     }
 }
 
diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs
index b566490..37457d8 100644
--- a/src/libstd/sys/redox/net/tcp.rs
+++ b/src/libstd/sys/redox/net/tcp.rs
@@ -24,8 +24,8 @@
 pub struct TcpStream(File);
 
 impl TcpStream {
-    pub fn connect(addr: &SocketAddr) -> Result<TcpStream> {
-        let path = format!("tcp:{}", addr);
+    pub fn connect(addr: Result<&SocketAddr>) -> Result<TcpStream> {
+        let path = format!("tcp:{}", addr?);
         let mut options = OpenOptions::new();
         options.read(true);
         options.write(true);
@@ -180,8 +180,8 @@
 pub struct TcpListener(File);
 
 impl TcpListener {
-    pub fn bind(addr: &SocketAddr) -> Result<TcpListener> {
-        let path = format!("tcp:/{}", addr);
+    pub fn bind(addr: Result<&SocketAddr>) -> Result<TcpListener> {
+        let path = format!("tcp:/{}", addr?);
         let mut options = OpenOptions::new();
         options.read(true);
         options.write(true);
diff --git a/src/libstd/sys/redox/net/udp.rs b/src/libstd/sys/redox/net/udp.rs
index 22af020..85bfd42 100644
--- a/src/libstd/sys/redox/net/udp.rs
+++ b/src/libstd/sys/redox/net/udp.rs
@@ -25,8 +25,8 @@
 pub struct UdpSocket(File, UnsafeCell<Option<SocketAddr>>);
 
 impl UdpSocket {
-    pub fn bind(addr: &SocketAddr) -> Result<UdpSocket> {
-        let path = format!("udp:/{}", addr);
+    pub fn bind(addr: Result<&SocketAddr>) -> Result<UdpSocket> {
+        let path = format!("udp:/{}", addr?);
         let mut options = OpenOptions::new();
         options.read(true);
         options.write(true);
@@ -37,8 +37,8 @@
         unsafe { &mut *(self.1.get()) }
     }
 
-    pub fn connect(&self, addr: &SocketAddr) -> Result<()> {
-        unsafe { *self.1.get() = Some(*addr) };
+    pub fn connect(&self, addr: Result<&SocketAddr>) -> Result<()> {
+        unsafe { *self.1.get() = Some(*addr?) };
         Ok(())
     }
 
diff --git a/src/libstd/sys/redox/stdio.rs b/src/libstd/sys/redox/stdio.rs
index 7a4d11b..52cd933 100644
--- a/src/libstd/sys/redox/stdio.rs
+++ b/src/libstd/sys/redox/stdio.rs
@@ -76,6 +76,6 @@
 
 pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;
 
-pub fn stderr_prints_nothing() -> bool {
-    false
+pub fn panic_output() -> Option<impl io::Write> {
+    Stderr::new().ok()
 }
diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs
index bab91b1..ff86180 100644
--- a/src/libstd/sys/redox/thread.rs
+++ b/src/libstd/sys/redox/thread.rs
@@ -28,7 +28,8 @@
 unsafe impl Sync for Thread {}
 
 impl Thread {
-    pub unsafe fn new<'a>(_stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> {
+    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
+    pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>) -> io::Result<Thread> {
         let p = box p;
 
         let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?;
diff --git a/src/libstd/sys/redox/time.rs b/src/libstd/sys/redox/time.rs
index beff8d2..cb2eab5 100644
--- a/src/libstd/sys/redox/time.rs
+++ b/src/libstd/sys/redox/time.rs
@@ -41,10 +41,6 @@
         }
     }
 
-    fn add_duration(&self, other: &Duration) -> Timespec {
-        self.checked_add_duration(other).expect("overflow when adding duration to time")
-    }
-
     fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = other
             .as_secs()
@@ -67,27 +63,25 @@
         })
     }
 
-    fn sub_duration(&self, other: &Duration) -> Timespec {
+    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = other
             .as_secs()
             .try_into() // <- target type would be `i64`
             .ok()
-            .and_then(|secs| self.t.tv_sec.checked_sub(secs))
-            .expect("overflow when subtracting duration from time");
+            .and_then(|secs| self.t.tv_sec.checked_sub(secs))?;
 
         // Similar to above, nanos can't overflow.
         let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
         if nsec < 0 {
             nsec += NSEC_PER_SEC as i32;
-            secs = secs.checked_sub(1).expect("overflow when subtracting \
-                                               duration from time");
+            secs = secs.checked_sub(1)?;
         }
-        Timespec {
+        Some(Timespec {
             t: syscall::TimeSpec {
                 tv_sec: secs,
                 tv_nsec: nsec as i32,
             },
-        }
+        })
     }
 }
 
@@ -150,12 +144,12 @@
         })
     }
 
-    pub fn add_duration(&self, other: &Duration) -> Instant {
-        Instant { t: self.t.add_duration(other) }
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
+        Some(Instant { t: self.t.checked_add_duration(other)? })
     }
 
-    pub fn sub_duration(&self, other: &Duration) -> Instant {
-        Instant { t: self.t.sub_duration(other) }
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
+        Some(Instant { t: self.t.checked_sub_duration(other)? })
     }
 }
 
@@ -178,16 +172,12 @@
         self.t.sub_timespec(&other.t)
     }
 
-    pub fn add_duration(&self, other: &Duration) -> SystemTime {
-        SystemTime { t: self.t.add_duration(other) }
-    }
-
     pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-        self.t.checked_add_duration(other).map(|t| SystemTime { t })
+        Some(SystemTime { t: self.t.checked_add_duration(other)? })
     }
 
-    pub fn sub_duration(&self, other: &Duration) -> SystemTime {
-        SystemTime { t: self.t.sub_duration(other) }
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+        Some(SystemTime { t: self.t.checked_sub_duration(other)? })
     }
 }
 
diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S
new file mode 100644
index 0000000..4d5cc02
--- /dev/null
+++ b/src/libstd/sys/sgx/abi/entry.S
@@ -0,0 +1,327 @@
+/* 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.                                  */
+
+/*  This symbol is used at runtime to figure out the virtual address that the */
+/*  enclave is loaded at. */
+.section absolute
+.global IMAGE_BASE
+IMAGE_BASE:
+
+.section .rodata
+/*  The XSAVE area needs to be a large chunk of readable memory, but since we are */
+/*  going to restore everything to its initial state (XSTATE_BV=0), only certain */
+/*  parts need to have a defined value. In particular: */
+/*  */
+/*    * MXCSR in the legacy area. This register is always restored if RFBM[1] or */
+/*      RFBM[2] is set, regardless of the value of XSTATE_BV */
+/*    * XSAVE header */
+.align 64
+.Lxsave_clear:
+.org .+24
+.Lxsave_mxcsr:
+    .int 0
+
+/*  We can store a bunch of data in the gap between MXCSR and the XSAVE header */
+
+/*  The following symbols point at read-only data that will be filled in by the */
+/*  post-linker. */
+
+/*  When using this macro, don't forget to adjust the linker version script! */
+.macro globvar name:req size:req
+    .global \name
+    .protected \name
+    .align \size
+    .size \name , \size
+    \name :
+        .org .+\size
+.endm
+    /*  The base address (relative to enclave start) of the heap area */
+    globvar HEAP_BASE 8
+    /*  The heap size in bytes */
+    globvar HEAP_SIZE 8
+    /*  Value of the RELA entry in the dynamic table */
+    globvar RELA 8
+    /*  Value of the RELACOUNT entry in the dynamic table */
+    globvar RELACOUNT 8
+    /*  The enclave size in bytes */
+    globvar ENCLAVE_SIZE 8
+    /*  The base address (relative to enclave start) of the enclave configuration area */
+    globvar CFGDATA_BASE 8
+    /*  Non-zero if debugging is enabled, zero otherwise */
+    globvar DEBUG 1
+
+.Lreentry_panic_msg:
+    .asciz "Re-entered panicked enclave!"
+.Lreentry_panic_msg_end:
+
+.Lusercall_panic_msg:
+    .asciz "Invalid usercall#!"
+.Lusercall_panic_msg_end:
+
+.org .Lxsave_clear+512
+.Lxsave_header:
+    .int 0, 0 /*  XSTATE_BV */
+    .int 0, 0 /*  XCOMP_BV */
+    .org .+48 /*  reserved bits */
+
+.data
+.Lpanicked:
+    .byte 0
+
+/*  TCS local storage section */
+.equ tcsls_tos,                 0x00 /*  initialized by loader to *offset* from image base to TOS */
+.equ tcsls_flags,               0x08 /*  initialized by loader */
+.equ tcsls_flag_secondary,      0    /*  initialized by loader; 0 = standard TCS, 1 = secondary TCS */
+.equ tcsls_flag_init_once,      1    /*  initialized by loader to 0 */
+/*  14 unused bits */
+.equ tcsls_user_fcw,            0x0a
+.equ tcsls_user_mxcsr,          0x0c
+.equ tcsls_last_rsp,            0x10 /*  initialized by loader to 0 */
+.equ tcsls_panic_last_rsp,      0x18 /*  initialized by loader to 0 */
+.equ tcsls_debug_panic_buf_ptr, 0x20 /*  initialized by loader to 0 */
+.equ tcsls_user_rsp,            0x28
+.equ tcsls_user_retip,          0x30
+.equ tcsls_user_rbp,            0x38
+.equ tcsls_user_r12,            0x40
+.equ tcsls_user_r13,            0x48
+.equ tcsls_user_r14,            0x50
+.equ tcsls_user_r15,            0x58
+.equ tcsls_tls_ptr,             0x60
+.equ tcsls_tcs_addr,            0x68
+
+.macro load_tcsls_flag_secondary_bool reg:req comments:vararg
+    .ifne tcsls_flag_secondary /* to convert to a bool, must be the first bit */
+    .abort
+    .endif
+        mov $(1<<tcsls_flag_secondary),%e\reg
+        and %gs:tcsls_flags,%\reg
+.endm
+
+.text
+.global sgx_entry
+.type sgx_entry,function
+sgx_entry:
+/*  save user registers */
+    mov %rcx,%gs:tcsls_user_retip
+    mov %rsp,%gs:tcsls_user_rsp
+    mov %rbp,%gs:tcsls_user_rbp
+    mov %r12,%gs:tcsls_user_r12
+    mov %r13,%gs:tcsls_user_r13
+    mov %r14,%gs:tcsls_user_r14
+    mov %r15,%gs:tcsls_user_r15
+    mov %rbx,%gs:tcsls_tcs_addr
+    stmxcsr %gs:tcsls_user_mxcsr
+    fnstcw %gs:tcsls_user_fcw
+/*  reset user state */
+    cld /* x86-64 ABI requires DF to be unset at function entry/exit */
+/*  check for debug buffer pointer */
+    testb  $0xff,DEBUG(%rip)
+    jz .Lskip_debug_init
+    mov %r10,%gs:tcsls_debug_panic_buf_ptr
+.Lskip_debug_init:
+/*  check if returning from usercall */
+    mov %gs:tcsls_last_rsp,%r11
+    test %r11,%r11
+    jnz .Lusercall_ret
+/*  setup stack */
+    mov %gs:tcsls_tos,%rsp /*  initially, RSP is not set to the correct value */
+                           /*  here. This is fixed below under "adjust stack". */
+/*  check for thread init */
+    bts $tcsls_flag_init_once,%gs:tcsls_flags
+    jc .Lskip_init
+/*  adjust stack */
+    lea IMAGE_BASE(%rip),%rax
+    add %rax,%rsp
+    mov %rsp,%gs:tcsls_tos
+/*  call tcs_init */
+/*  store caller-saved registers in callee-saved registers */
+    mov %rdi,%rbx
+    mov %rsi,%r12
+    mov %rdx,%r13
+    mov %r8,%r14
+    mov %r9,%r15
+    load_tcsls_flag_secondary_bool di /* RDI = tcs_init() argument: secondary: bool */
+    call tcs_init
+/*  reload caller-saved registers */
+    mov %rbx,%rdi
+    mov %r12,%rsi
+    mov %r13,%rdx
+    mov %r14,%r8
+    mov %r15,%r9
+.Lskip_init:
+/*  check for panic */
+    bt $0,.Lpanicked(%rip)
+    jc .Lreentry_panic
+/*  call into main entry point */
+    load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */
+    call entry /* RDI, RSI, RDX, R8, R9 passed in from userspace */
+    mov %rax,%rsi  /* RSI = return value */
+    /* NOP: mov %rdx,%rdx */ /*  RDX = return value */
+    xor %rdi,%rdi  /* RDI = normal exit */
+.Lexit:
+/*  clear general purpose register state */
+    /*  RAX overwritten by ENCLU */
+    /*  RBX set later */
+    /*  RCX overwritten by ENCLU */
+    /*  RDX contains return value */
+    /*  RSP set later */
+    /*  RBP set later */
+    /*  RDI contains exit mode */
+    /*  RSI contains return value */
+    xor %r8,%r8
+    xor %r9,%r9
+    xor %r10,%r10
+    xor %r11,%r11
+    /*  R12 ~ R15 set by sgx_exit */
+.Lsgx_exit:
+/*  clear extended register state */
+    mov %rdx, %rcx /*  save RDX */
+    mov $-1, %rax
+    mov %rax, %rdx
+    xrstor .Lxsave_clear(%rip)
+    mov %rcx, %rdx /*  restore RDX */
+/*  clear flags */
+    pushq $0
+    popfq
+/*  restore user registers */
+    mov %gs:tcsls_user_r12,%r12
+    mov %gs:tcsls_user_r13,%r13
+    mov %gs:tcsls_user_r14,%r14
+    mov %gs:tcsls_user_r15,%r15
+    mov %gs:tcsls_user_retip,%rbx
+    mov %gs:tcsls_user_rsp,%rsp
+    mov %gs:tcsls_user_rbp,%rbp
+    fldcw %gs:tcsls_user_fcw
+    ldmxcsr %gs:tcsls_user_mxcsr
+/*  exit enclave */
+    mov $0x4,%eax /*  EEXIT */
+    enclu
+/*  end sgx_entry */
+
+.Lreentry_panic:
+    lea .Lreentry_panic_msg(%rip),%rdi
+    mov $.Lreentry_panic_msg_end-.Lreentry_panic_msg,%esi
+    orq $8,%rsp
+    jmp panic_msg
+
+.Lusercall_panic:
+    lea .Lusercall_panic_msg(%rip),%rdi
+    mov $.Lusercall_panic_msg_end-.Lusercall_panic_msg,%esi
+    orq $8,%rsp
+    jmp panic_msg
+
+.macro push_callee_saved_registers
+    push %r15
+    push %r14
+    push %r13
+    push %r12
+    push %rbp
+    push %rbx
+    sub $8, %rsp
+    fstcw 4(%rsp)
+    stmxcsr (%rsp)
+.endm
+
+.global panic_exit
+panic_exit:
+/* save registers in DEBUG mode, so that debugger can reconstruct the stack */
+    testb $0xff,DEBUG(%rip)
+    jz .Lskip_save_registers
+    push_callee_saved_registers
+    movq %rsp,%gs:tcsls_panic_last_rsp
+.Lskip_save_registers:
+/* set panicked bit */
+    movb $1,.Lpanicked(%rip)
+/* call usercall exit(true) */
+    mov $1,%esi   /*  RSI = usercall() argument: panic = true */
+    xor %rdx,%rdx /*  RDX cleared */
+    movq $usercall_nr_exit,%rdi /*  RDI = usercall exit */
+    jmp .Lexit
+
+/*  This *MUST* be called with 6 parameters, otherwise register information */
+/*  might leak! */
+.global usercall
+usercall:
+    test %rdi,%rdi
+    jle .Lusercall_panic
+/*  save callee-saved state */
+    push_callee_saved_registers
+    movq %rsp,%gs:tcsls_last_rsp
+/*  clear general purpose register state */
+    /*  RAX overwritten by ENCLU */
+    /*  RBX set by sgx_exit */
+    /*  RCX overwritten by ENCLU */
+    /*  RDX contains parameter */
+    /*  RSP set by sgx_exit */
+    /*  RBP set by sgx_exit */
+    /*  RDI contains parameter */
+    /*  RSI contains parameter */
+    /*  R8 contains parameter */
+    /*  R9 contains parameter */
+    xor %r10,%r10
+    xor %r11,%r11
+    /*  R12 ~ R15 set by sgx_exit */
+/*  extended registers/flags cleared by sgx_exit */
+/*  exit */
+    jmp .Lsgx_exit
+.Lusercall_ret:
+    movq $0,%gs:tcsls_last_rsp
+/*  restore callee-saved state, cf. push_callee_saved_registers */
+    mov %r11,%rsp
+    ldmxcsr (%rsp)
+    fldcw 4(%rsp)
+    add $8, %rsp
+    pop %rbx
+    pop %rbp
+    pop %r12
+    pop %r13
+    pop %r14
+    pop %r15
+/*  return */
+    mov %rsi,%rax /*  RAX = return value */
+    /* NOP: mov %rdx,%rdx */ /*  RDX = return value */
+    ret
+
+/*
+The following functions need to be defined externally:
+```
+// Called by entry code when it needs to panic
+extern "C" fn panic_msg(msg: &'static str) -> ! {
+    panic!(msg)
+}
+
+// Called once when a TCS is first entered
+extern "C" fn tcs_init(secondary: bool);
+
+// Standard TCS entrypoint
+extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64);
+```
+*/
+
+.global get_tcs_addr
+get_tcs_addr:
+    mov %gs:tcsls_tcs_addr,%rax
+    ret
+
+.global get_tls_ptr
+get_tls_ptr:
+    mov %gs:tcsls_tls_ptr,%rax
+    ret
+
+.global set_tls_ptr
+set_tls_ptr:
+    mov %rdi,%gs:tcsls_tls_ptr
+    ret
+
+.global take_debug_panic_buf_ptr
+take_debug_panic_buf_ptr:
+    xor %rax,%rax
+    xchg %gs:tcsls_debug_panic_buf_ptr,%rax
+    ret
diff --git a/src/libstd/sys/sgx/abi/mem.rs b/src/libstd/sys/sgx/abi/mem.rs
new file mode 100644
index 0000000..bf32c71
--- /dev/null
+++ b/src/libstd/sys/sgx/abi/mem.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.
+
+// Do not remove inline: will result in relocation failure
+#[inline(always)]
+pub unsafe fn rel_ptr<T>(offset: u64) -> *const T {
+    (image_base() + offset) as *const T
+}
+
+// Do not remove inline: will result in relocation failure
+#[inline(always)]
+pub unsafe fn rel_ptr_mut<T>(offset: u64) -> *mut T {
+    (image_base() + offset) as *mut T
+}
+
+extern {
+    static ENCLAVE_SIZE: usize;
+}
+
+// Do not remove inline: will result in relocation failure
+// For the same reason we use inline ASM here instead of an extern static to
+// locate the base
+#[inline(always)]
+fn image_base() -> u64 {
+    let base;
+    unsafe { asm!("lea IMAGE_BASE(%rip),$0":"=r"(base)) };
+    base
+}
+
+pub fn is_user_range(p: *const u8, len: usize) -> bool {
+    let start=p as u64;
+    let end=start + (len as u64);
+    end <= image_base() ||
+        start >= image_base() + (unsafe { ENCLAVE_SIZE } as u64) // unsafe ok: link-time constant
+}
diff --git a/src/libstd/sys/sgx/abi/mod.rs b/src/libstd/sys/sgx/abi/mod.rs
new file mode 100644
index 0000000..069cca3
--- /dev/null
+++ b/src/libstd/sys/sgx/abi/mod.rs
@@ -0,0 +1,99 @@
+// 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 core::sync::atomic::{AtomicUsize, Ordering};
+use io::Write;
+
+// runtime features
+mod reloc;
+mod mem;
+pub(super) mod panic;
+
+// library features
+pub mod thread;
+pub mod tls;
+#[macro_use]
+pub mod usercalls;
+
+global_asm!(concat!(usercalls_asm!(), include_str!("entry.S")));
+
+#[no_mangle]
+unsafe extern "C" fn tcs_init(secondary: bool) {
+    // Be very careful when changing this code: it runs before the binary has been
+    // relocated. Any indirect accesses to symbols will likely fail.
+    const UNINIT: usize = 0;
+    const BUSY: usize = 1;
+    const DONE: usize = 2;
+    // Three-state spin-lock
+    static RELOC_STATE: AtomicUsize = AtomicUsize::new(UNINIT);
+
+    if secondary && RELOC_STATE.load(Ordering::Relaxed) != DONE {
+        panic::panic_msg("Entered secondary TCS before main TCS!")
+    }
+
+    // Try to atomically swap UNINIT with BUSY. The returned state can be:
+    match RELOC_STATE.compare_and_swap(UNINIT, BUSY, Ordering::Acquire) {
+        // This thread just obtained the lock and other threads will observe BUSY
+        UNINIT => {
+            reloc::relocate_elf_rela();
+            RELOC_STATE.store(DONE, Ordering::Release);
+        },
+        // We need to wait until the initialization is done.
+        BUSY => while RELOC_STATE.load(Ordering::Acquire) == BUSY  {
+            ::core::arch::x86_64::_mm_pause()
+        },
+        // Initialization is done.
+        DONE => {},
+        _ => unreachable!()
+    }
+}
+
+// FIXME: this item should only exist if this is linked into an executable
+// (main function exists). If this is a library, the crate author should be
+// able to specify this
+#[no_mangle]
+extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) {
+    // FIXME: how to support TLS in library mode?
+    let tls = Box::new(tls::Tls::new());
+    let _tls_guard = unsafe { tls.activate() };
+
+    if secondary {
+        super::thread::Thread::entry();
+
+        (0, 0)
+    } else {
+        extern "C" {
+            fn main(argc: isize, argv: *const *const u8) -> isize;
+        }
+
+        // check entry is being called according to ABI
+        assert_eq!(p3, 0);
+        assert_eq!(p4, 0);
+        assert_eq!(p5, 0);
+
+        unsafe {
+            // The actual types of these arguments are `p1: *const Arg, p2:
+            // usize`. We can't currently customize the argument list of Rust's
+            // main function, so we pass these in as the standard pointer-sized
+            // values in `argc` and `argv`.
+            let ret = main(p2 as _, p1 as _);
+            exit_with_code(ret)
+        }
+    }
+}
+
+pub(super) fn exit_with_code(code: isize) -> ! {
+    if code != 0 {
+        if let Some(mut out) = panic::SgxPanicOutput::new() {
+            let _ = write!(out, "Exited with status code {}", code);
+        }
+    }
+    usercalls::exit(code != 0);
+}
diff --git a/src/libstd/sys/sgx/abi/panic.rs b/src/libstd/sys/sgx/abi/panic.rs
new file mode 100644
index 0000000..dd9159b
--- /dev/null
+++ b/src/libstd/sys/sgx/abi/panic.rs
@@ -0,0 +1,58 @@
+// 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 io::{self, Write};
+use slice::from_raw_parts_mut;
+
+extern "C" {
+    fn take_debug_panic_buf_ptr() -> *mut u8;
+    static DEBUG: u8;
+}
+
+pub(crate) struct SgxPanicOutput(Option<&'static mut [u8]>);
+
+impl SgxPanicOutput {
+    pub(crate) fn new() -> Option<Self> {
+        if unsafe { DEBUG == 0 } {
+            None
+        } else {
+            Some(SgxPanicOutput(None))
+        }
+    }
+
+    fn init(&mut self) -> &mut &'static mut [u8] {
+        self.0.get_or_insert_with(|| unsafe {
+            let ptr = take_debug_panic_buf_ptr();
+            if ptr.is_null() {
+                &mut []
+            } else {
+                from_raw_parts_mut(ptr, 1024)
+            }
+        })
+    }
+}
+
+impl Write for SgxPanicOutput {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.init().write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.init().flush()
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn panic_msg(msg: &str) -> ! {
+    let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes()));
+    unsafe { panic_exit(); }
+}
+
+extern "C" { pub fn panic_exit() -> !; }
diff --git a/src/libstd/sys/sgx/abi/reloc.rs b/src/libstd/sys/sgx/abi/reloc.rs
new file mode 100644
index 0000000..2d5e14d
--- /dev/null
+++ b/src/libstd/sys/sgx/abi/reloc.rs
@@ -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.
+
+use slice::from_raw_parts;
+use super::mem;
+
+const R_X86_64_RELATIVE: u32 = 8;
+
+#[repr(packed)]
+struct Rela<T> {
+    offset: T,
+    info: T,
+    addend: T,
+}
+
+pub fn relocate_elf_rela() {
+    extern {
+        static RELA: u64;
+        static RELACOUNT: usize;
+    }
+
+    if unsafe { RELACOUNT } == 0 { return }  // unsafe ok: link-time constant
+
+    let relas = unsafe {
+        from_raw_parts::<Rela<u64>>(mem::rel_ptr(RELA), RELACOUNT)  // unsafe ok: link-time constant
+    };
+    for rela in relas {
+        if rela.info != (/*0 << 32 |*/ R_X86_64_RELATIVE as u64) {
+            panic!("Invalid relocation");
+        }
+        unsafe { *mem::rel_ptr_mut::<*const ()>(rela.offset) = mem::rel_ptr(rela.addend) };
+    }
+}
diff --git a/src/libstd/sys/sgx/abi/thread.rs b/src/libstd/sys/sgx/abi/thread.rs
new file mode 100644
index 0000000..4640b81
--- /dev/null
+++ b/src/libstd/sys/sgx/abi/thread.rs
@@ -0,0 +1,20 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use fortanix_sgx_abi::Tcs;
+
+/// Get the ID for the current thread. The ID is guaranteed to be unique among
+/// all currently running threads in the enclave, and it is guaranteed to be
+/// constant for the lifetime of the thread. More specifically for SGX, there
+/// is a one-to-one correspondence of the ID to the address of the TCS.
+pub fn current() -> Tcs {
+    extern "C" { fn get_tcs_addr() -> Tcs; }
+    unsafe { get_tcs_addr() }
+}
diff --git a/src/libstd/sys/sgx/abi/tls.rs b/src/libstd/sys/sgx/abi/tls.rs
new file mode 100644
index 0000000..ab78221
--- /dev/null
+++ b/src/libstd/sys/sgx/abi/tls.rs
@@ -0,0 +1,246 @@
+// 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 sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+use ptr;
+use mem;
+use cell::Cell;
+use num::NonZeroUsize;
+use self::sync_bitset::*;
+
+#[cfg(target_pointer_width="64")]
+const USIZE_BITS: usize = 64;
+const TLS_KEYS: usize = 128; // Same as POSIX minimum
+const TLS_KEYS_BITSET_SIZE: usize = (TLS_KEYS + (USIZE_BITS - 1)) / USIZE_BITS;
+
+static TLS_KEY_IN_USE: SyncBitset = SYNC_BITSET_INIT;
+macro_rules! dup {
+    ((* $($exp:tt)*) $($val:tt)*) => (dup!( ($($exp)*) $($val)* $($val)* ));
+    (() $($val:tt)*) => ([$($val),*])
+}
+static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = dup!((* * * * * * *) ATOMIC_USIZE_INIT);
+
+extern "C" {
+    fn get_tls_ptr() -> *const u8;
+    fn set_tls_ptr(tls: *const u8);
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub struct Key(NonZeroUsize);
+
+impl Key {
+    fn to_index(self) -> usize {
+        self.0.get() - 1
+    }
+
+    fn from_index(index: usize) -> Self {
+        Key(NonZeroUsize::new(index + 1).unwrap())
+    }
+
+    pub fn as_usize(self) -> usize {
+        self.0.get()
+    }
+
+    pub fn from_usize(index: usize) -> Self {
+        Key(NonZeroUsize::new(index).unwrap())
+    }
+}
+
+#[repr(C)]
+pub struct Tls {
+    data: [Cell<*mut u8>; TLS_KEYS]
+}
+
+pub struct ActiveTls<'a> {
+    tls: &'a Tls
+}
+
+impl<'a> Drop for ActiveTls<'a> {
+    fn drop(&mut self) {
+        let value_with_destructor = |key: usize| {
+            let ptr = TLS_DESTRUCTOR[key].load(Ordering::Relaxed);
+            unsafe { mem::transmute::<_,Option<unsafe extern fn(*mut u8)>>(ptr) }
+                .map(|dtor| (&self.tls.data[key], dtor))
+        };
+
+        let mut any_non_null_dtor = true;
+        while any_non_null_dtor {
+            any_non_null_dtor = false;
+            for (value, dtor) in TLS_KEY_IN_USE.iter().filter_map(&value_with_destructor) {
+                let value = value.replace(ptr::null_mut());
+                if value != ptr::null_mut() {
+                    any_non_null_dtor = true;
+                    unsafe { dtor(value) }
+                }
+            }
+        }
+    }
+}
+
+impl Tls {
+    pub fn new() -> Tls {
+        Tls { data: dup!((* * * * * * *) (Cell::new(ptr::null_mut()))) }
+    }
+
+    pub unsafe fn activate(&self) -> ActiveTls {
+        set_tls_ptr(self as *const Tls as _);
+        ActiveTls { tls: self }
+    }
+
+    #[allow(unused)]
+    pub unsafe fn activate_persistent(self: Box<Self>) {
+        set_tls_ptr((&*self) as *const Tls as _);
+        mem::forget(self);
+    }
+
+    unsafe fn current<'a>() -> &'a Tls {
+        &*(get_tls_ptr() as *const Tls)
+    }
+
+    pub fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
+        let index = TLS_KEY_IN_USE.set().expect("TLS limit exceeded");
+        TLS_DESTRUCTOR[index].store(dtor.map_or(0, |f| f as usize), Ordering::Relaxed);
+        Key::from_index(index)
+    }
+
+    pub fn set(key: Key, value: *mut u8) {
+        let index = key.to_index();
+        assert!(TLS_KEY_IN_USE.get(index));
+        unsafe { Self::current() }.data[index].set(value);
+    }
+
+    pub fn get(key: Key) -> *mut u8 {
+        let index = key.to_index();
+        assert!(TLS_KEY_IN_USE.get(index));
+        unsafe { Self::current() }.data[index].get()
+    }
+
+    pub fn destroy(key: Key) {
+        TLS_KEY_IN_USE.clear(key.to_index());
+    }
+}
+
+mod sync_bitset {
+    use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+    use iter::{Enumerate, Peekable};
+    use slice::Iter;
+    use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS};
+
+    /// A bitset that can be used synchronously.
+    pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]);
+
+    pub(super) const SYNC_BITSET_INIT: SyncBitset =
+        SyncBitset([ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT]);
+
+    impl SyncBitset {
+        pub fn get(&self, index: usize) -> bool {
+            let (hi, lo) = Self::split(index);
+            (self.0[hi].load(Ordering::Relaxed) & lo) != 0
+        }
+
+        /// Not atomic.
+        pub fn iter(&self) -> SyncBitsetIter {
+            SyncBitsetIter {
+                iter: self.0.iter().enumerate().peekable(),
+                elem_idx: 0,
+            }
+        }
+
+        pub fn clear(&self, index: usize) {
+            let (hi, lo) = Self::split(index);
+            self.0[hi].fetch_and(!lo, Ordering::Relaxed);
+        }
+
+        /// Set any unset bit. Not atomic. Returns `None` if all bits were
+        /// observed to be set.
+        pub fn set(&self) -> Option<usize> {
+            'elems: for (idx, elem) in self.0.iter().enumerate() {
+                let mut current = elem.load(Ordering::Relaxed);
+                loop {
+                    if 0 == !current {
+                        continue 'elems;
+                    }
+                    let trailing_ones = (!current).trailing_zeros() as usize;
+                    match elem.compare_exchange(
+                        current,
+                        current | (1 << trailing_ones),
+                        Ordering::AcqRel,
+                        Ordering::Relaxed
+                    ) {
+                        Ok(_) => return Some(idx * USIZE_BITS + trailing_ones),
+                        Err(previous) => current = previous,
+                    }
+                }
+            }
+            None
+        }
+
+        fn split(index: usize) -> (usize, usize) {
+            (index / USIZE_BITS, 1 << (index % USIZE_BITS))
+        }
+    }
+
+    pub(super) struct SyncBitsetIter<'a> {
+        iter: Peekable<Enumerate<Iter<'a, AtomicUsize>>>,
+        elem_idx: usize,
+    }
+
+    impl<'a> Iterator for SyncBitsetIter<'a> {
+        type Item = usize;
+
+        fn next(&mut self) -> Option<usize> {
+            self.iter.peek().cloned().and_then(|(idx, elem)| {
+                let elem = elem.load(Ordering::Relaxed);
+                let low_mask = (1 << self.elem_idx) - 1;
+                let next = elem & !low_mask;
+                let next_idx = next.trailing_zeros() as usize;
+                self.elem_idx = next_idx + 1;
+                if self.elem_idx >= 64 {
+                    self.elem_idx = 0;
+                    self.iter.next();
+                }
+                match next_idx {
+                    64 => self.next(),
+                    _ => Some(idx * USIZE_BITS + next_idx),
+                }
+            })
+        }
+    }
+
+    #[cfg(test)]
+    mod tests {
+        use super::*;
+
+        fn test_data(bitset: [usize; 2], bit_indices: &[usize]) {
+            let set = SyncBitset([AtomicUsize::new(bitset[0]), AtomicUsize::new(bitset[1])]);
+            assert_eq!(set.iter().collect::<Vec<_>>(), bit_indices);
+            for &i in bit_indices {
+                assert!(set.get(i));
+            }
+        }
+
+        #[test]
+        fn iter() {
+            test_data([0b0110_1001, 0], &[0, 3, 5, 6]);
+            test_data([0x8000_0000_0000_0000, 0x8000_0000_0000_0001], &[63, 64, 127]);
+            test_data([0, 0], &[]);
+        }
+
+        #[test]
+        fn set_get_clear() {
+            let set = SYNC_BITSET_INIT;
+            let key = set.set().unwrap();
+            assert!(set.get(key));
+            set.clear(key);
+            assert!(!set.get(key));
+        }
+    }
+}
diff --git a/src/libstd/sys/sgx/abi/usercalls/alloc.rs b/src/libstd/sys/sgx/abi/usercalls/alloc.rs
new file mode 100644
index 0000000..64968a9
--- /dev/null
+++ b/src/libstd/sys/sgx/abi/usercalls/alloc.rs
@@ -0,0 +1,404 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused)]
+
+use ptr;
+use mem;
+use cell::UnsafeCell;
+use slice;
+use ops::{Deref, DerefMut, Index, IndexMut, CoerceUnsized};
+use slice::SliceIndex;
+
+use fortanix_sgx_abi::*;
+use super::super::mem::is_user_range;
+
+/// A type that can be safely read from or written to userspace.
+///
+/// Non-exhaustive list of specific requirements for reading and writing:
+/// * **Type is `Copy`** (and therefore also not `Drop`). Copies will be
+///   created when copying from/to userspace. Destructors will not be called.
+/// * **No references or Rust-style owned pointers** (`Vec`, `Arc`, etc.). When
+///   reading from userspace, references into enclave memory must not be
+///   created. Also, only enclave memory is considered managed by the Rust
+///   compiler's static analysis. When reading from userspace, there can be no
+///   guarantee that the value correctly adheres to the expectations of the
+///   type. When writing to userspace, memory addresses of data in enclave
+///   memory must not be leaked for confidentiality reasons. `User` and
+///   `UserRef` are also not allowed for the same reasons.
+/// * **No fat pointers.** When reading from userspace, the size or vtable
+///   pointer could be automatically interpreted and used by the code. When
+///   writing to userspace, memory addresses of data in enclave memory (such
+///   as vtable pointers) must not be leaked for confidentiality reasons.
+///
+/// Non-exhaustive list of specific requirements for reading from userspace:
+/// * Any bit pattern is valid for this type (no `enum`s). There can be no
+///   guarantee that the value correctly adheres to the expectations of the
+///   type, so any value must be valid for this type.
+///
+/// Non-exhaustive list of specific requirements for writing to userspace:
+/// * No pointers to enclave memory. Memory addresses of data in enclave memory
+///   must not be leaked for confidentiality reasons.
+/// * No internal padding. Padding might contain previously-initialized secret
+///   data stored at that memory location and must not be leaked for
+///   confidentiality reasons.
+pub unsafe trait UserSafeSized: Copy + Sized {}
+
+unsafe impl UserSafeSized for u8 {}
+unsafe impl<T> UserSafeSized for FifoDescriptor<T> {}
+unsafe impl UserSafeSized for ByteBuffer {}
+unsafe impl UserSafeSized for Usercall {}
+unsafe impl UserSafeSized for Return {}
+unsafe impl<T: UserSafeSized> UserSafeSized for [T; 2] {}
+
+/// A type that can be represented in memory as one or more `UserSafeSized`s.
+pub unsafe trait UserSafe {
+    unsafe fn align_of() -> usize;
+
+    /// NB. This takes a size, not a length!
+    unsafe fn from_raw_sized_unchecked(ptr: *const u8, size: usize) -> *const Self;
+
+    /// NB. This takes a size, not a length!
+    unsafe fn from_raw_sized(ptr: *const u8, size: usize) -> *const Self {
+        let ret = Self::from_raw_sized_unchecked(ptr, size);
+        Self::check_ptr(ret);
+        ret
+    }
+
+    unsafe fn check_ptr(ptr: *const Self) {
+        let is_aligned = |p| -> bool {
+            0 == (p as usize) & (Self::align_of() - 1)
+        };
+
+        assert!(is_aligned(ptr as *const u8));
+        assert!(is_user_range(ptr as _, mem::size_of_val(&*ptr)));
+        assert!(!ptr.is_null());
+    }
+}
+
+unsafe impl<T: UserSafeSized> UserSafe for T {
+    unsafe fn align_of() -> usize {
+        mem::align_of::<T>()
+    }
+
+    unsafe fn from_raw_sized_unchecked(ptr: *const u8, size: usize) -> *const Self {
+        assert_eq!(size, mem::size_of::<T>());
+        ptr as _
+    }
+}
+
+unsafe impl<T: UserSafeSized> UserSafe for [T] {
+    unsafe fn align_of() -> usize {
+        mem::align_of::<T>()
+    }
+
+    unsafe fn from_raw_sized_unchecked(ptr: *const u8, size: usize) -> *const Self {
+        let elem_size = mem::size_of::<T>();
+        assert_eq!(size % elem_size, 0);
+        let len = size / elem_size;
+        slice::from_raw_parts(ptr as _, len)
+    }
+}
+
+/// A reference to some type in userspace memory. `&UserRef<T>` is equivalent
+/// to `&T` in enclave memory. Access to the memory is only allowed by copying
+/// to avoid TOCTTOU issues. After copying, code should make sure to completely
+/// check the value before use.
+pub struct UserRef<T: ?Sized>(UnsafeCell<T>);
+/// An owned type in userspace memory. `User<T>` is equivalent to `Box<T>` in
+/// enclave memory. Access to the memory is only allowed by copying to avoid
+/// TOCTTOU issues. The user memory will be freed when the value is dropped.
+/// After copying, code should make sure to completely check the value before
+/// use.
+pub struct User<T: UserSafe + ?Sized>(*mut UserRef<T>);
+
+impl<T: ?Sized> User<T> where T: UserSafe {
+    // This function returns memory that is practically uninitialized, but is
+    // not considered "unspecified" or "undefined" for purposes of an
+    // optimizing compiler. This is achieved by returning a pointer from
+    // from outside as obtained by `super::alloc`.
+    fn new_uninit_bytes(size: usize) -> Self {
+        unsafe {
+            let ptr = super::alloc(size, T::align_of()).expect("User memory allocation failed");
+            User(T::from_raw_sized(ptr as _, size) as _)
+        }
+    }
+
+    pub fn new_from_enclave(val: &T) -> Self {
+        unsafe {
+            let ret = Self::new_uninit_bytes(mem::size_of_val(val));
+            ptr::copy(
+                val as *const T as *const u8,
+                ret.0 as *mut T as *mut u8,
+                mem::size_of_val(val)
+            );
+            ret
+        }
+    }
+
+    /// Create an owned `User<T>` from a raw pointer. The pointer should be
+    /// freeable with the `free` usercall and the alignment of `T`.
+    ///
+    /// # Panics
+    /// This function panics if:
+    ///
+    /// * The pointer is not aligned
+    /// * The pointer is null
+    /// * The pointed-to range is not in user memory
+    pub unsafe fn from_raw(ptr: *mut T) -> Self {
+        T::check_ptr(ptr);
+        User(ptr as _)
+    }
+
+    /// Convert this value into a raw pointer. The value will no longer be
+    /// automatically freed.
+    pub fn into_raw(self) -> *mut T {
+        let ret = self.0;
+        mem::forget(self);
+        ret as _
+    }
+}
+
+impl<T> User<T> where T: UserSafe {
+    pub fn uninitialized() -> Self {
+        Self::new_uninit_bytes(mem::size_of::<T>())
+    }
+}
+
+impl<T> User<[T]> where [T]: UserSafe {
+    pub fn uninitialized(n: usize) -> Self {
+        Self::new_uninit_bytes(n * mem::size_of::<T>())
+    }
+
+    /// Create an owned `User<[T]>` from a raw thin pointer and a slice length.
+    /// The pointer should be freeable with the `free` usercall and the
+    /// alignment of `T`.
+    ///
+    /// # Panics
+    /// This function panics if:
+    ///
+    /// * The pointer is not aligned
+    /// * The pointer is null
+    /// * The pointed-to range is not in user memory
+    pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self {
+        User(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()) as _)
+    }
+}
+
+impl<T: ?Sized> UserRef<T> where T: UserSafe {
+    /// Create a `&UserRef<[T]>` from a raw pointer.
+    ///
+    /// # Panics
+    /// This function panics if:
+    ///
+    /// * The pointer is not aligned
+    /// * The pointer is null
+    /// * The pointed-to range is not in user memory
+    pub unsafe fn from_ptr<'a>(ptr: *const T) -> &'a Self {
+        T::check_ptr(ptr);
+        &*(ptr as *const Self)
+    }
+
+    /// Create a `&mut UserRef<[T]>` from a raw pointer.
+    ///
+    /// # Panics
+    /// This function panics if:
+    ///
+    /// * The pointer is not aligned
+    /// * The pointer is null
+    /// * The pointed-to range is not in user memory
+    pub unsafe fn from_mut_ptr<'a>(ptr: *mut T) -> &'a mut Self {
+        T::check_ptr(ptr);
+        &mut*(ptr as *mut Self)
+    }
+
+    /// # Panics
+    /// This function panics if the destination doesn't have the same size as
+    /// the source. This can happen for dynamically-sized types such as slices.
+    pub fn copy_from_enclave(&mut self, val: &T) {
+        unsafe {
+            assert_eq!(mem::size_of_val(val), mem::size_of_val( &*self.0.get() ));
+            ptr::copy(
+                val as *const T as *const u8,
+                self.0.get() as *mut T as *mut u8,
+                mem::size_of_val(val)
+            );
+        }
+    }
+
+    /// # Panics
+    /// This function panics if the destination doesn't have the same size as
+    /// the source. This can happen for dynamically-sized types such as slices.
+    pub fn copy_to_enclave(&self, dest: &mut T) {
+        unsafe {
+            assert_eq!(mem::size_of_val(dest), mem::size_of_val( &*self.0.get() ));
+            ptr::copy(
+                self.0.get() as *const T as *const u8,
+                dest as *mut T as *mut u8,
+                mem::size_of_val(dest)
+            );
+        }
+    }
+
+    pub fn as_raw_ptr(&self) -> *const T {
+        self as *const _ as _
+    }
+
+    pub fn as_raw_mut_ptr(&mut self) -> *mut T {
+        self as *mut _ as _
+    }
+}
+
+impl<T> UserRef<T> where T: UserSafe {
+    pub fn to_enclave(&self) -> T {
+        unsafe { ptr::read(self.0.get()) }
+    }
+}
+
+impl<T> UserRef<[T]> where [T]: UserSafe {
+    /// Create a `&UserRef<[T]>` from a raw thin pointer and a slice length.
+    ///
+    /// # Panics
+    /// This function panics if:
+    ///
+    /// * The pointer is not aligned
+    /// * The pointer is null
+    /// * The pointed-to range is not in user memory
+    pub unsafe fn from_raw_parts<'a>(ptr: *const T, len: usize) -> &'a Self {
+        &*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()) as *const Self)
+    }
+
+    /// Create a `&mut UserRef<[T]>` from a raw thin pointer and a slice length.
+    ///
+    /// # Panics
+    /// This function panics if:
+    ///
+    /// * The pointer is not aligned
+    /// * The pointer is null
+    /// * The pointed-to range is not in user memory
+    pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut T, len: usize) -> &'a mut Self {
+        &mut*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()) as *mut Self)
+    }
+
+    pub fn as_ptr(&self) -> *const T {
+        self.0.get() as _
+    }
+
+    pub fn as_mut_ptr(&mut self) -> *mut T {
+        self.0.get() as _
+    }
+
+    pub fn len(&self) -> usize {
+        unsafe { (*self.0.get()).len() }
+    }
+
+    pub fn copy_to_enclave_vec(&self, dest: &mut Vec<T>) {
+        unsafe {
+            if let Some(missing) = self.len().checked_sub(dest.capacity()) {
+                dest.reserve(missing)
+            }
+            dest.set_len(self.len());
+            self.copy_to_enclave(&mut dest[..]);
+        }
+    }
+
+    pub fn to_enclave(&self) -> Vec<T> {
+        let mut ret = Vec::with_capacity(self.len());
+        self.copy_to_enclave_vec(&mut ret);
+        ret
+    }
+
+    pub fn iter(&self) -> Iter<T>
+        where T: UserSafe // FIXME: should be implied by [T]: UserSafe?
+    {
+        unsafe {
+            Iter((&*self.as_raw_ptr()).iter())
+        }
+    }
+
+    pub fn iter_mut(&mut self) -> IterMut<T>
+        where T: UserSafe // FIXME: should be implied by [T]: UserSafe?
+    {
+        unsafe {
+            IterMut((&mut*self.as_raw_mut_ptr()).iter_mut())
+        }
+    }
+}
+
+pub struct Iter<'a, T: 'a + UserSafe>(slice::Iter<'a, T>);
+
+impl<'a, T: UserSafe> Iterator for Iter<'a, T> {
+    type Item = &'a UserRef<T>;
+
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        unsafe {
+            self.0.next().map(|e| UserRef::from_ptr(e))
+        }
+    }
+}
+
+pub struct IterMut<'a, T: 'a + UserSafe>(slice::IterMut<'a, T>);
+
+impl<'a, T: UserSafe> Iterator for IterMut<'a, T> {
+    type Item = &'a mut UserRef<T>;
+
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        unsafe {
+            self.0.next().map(|e| UserRef::from_mut_ptr(e))
+        }
+    }
+}
+
+impl<T: ?Sized> Deref for User<T> where T: UserSafe {
+    type Target = UserRef<T>;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe { &*self.0 }
+    }
+}
+
+impl<T: ?Sized> DerefMut for User<T> where T: UserSafe {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        unsafe { &mut*self.0 }
+    }
+}
+
+impl<T: ?Sized> Drop for User<T> where T: UserSafe {
+    fn drop(&mut self) {
+        unsafe {
+            let ptr = (*self.0).0.get();
+            super::free(ptr as _, mem::size_of_val(&mut*ptr), T::align_of());
+        }
+    }
+}
+
+impl<T: CoerceUnsized<U>, U> CoerceUnsized<UserRef<U>> for UserRef<T> {}
+
+impl<T, I: SliceIndex<[T]>> Index<I> for UserRef<[T]> where [T]: UserSafe, I::Output: UserSafe {
+    type Output = UserRef<I::Output>;
+
+    #[inline]
+    fn index(&self, index: I) -> &UserRef<I::Output> {
+        unsafe {
+            UserRef::from_ptr(index.index(&*self.as_raw_ptr()))
+        }
+    }
+}
+
+impl<T, I: SliceIndex<[T]>> IndexMut<I> for UserRef<[T]> where [T]: UserSafe, I::Output: UserSafe {
+    #[inline]
+    fn index_mut(&mut self, index: I) -> &mut UserRef<I::Output> {
+        unsafe {
+            UserRef::from_mut_ptr(index.index_mut(&mut*self.as_raw_mut_ptr()))
+        }
+    }
+}
diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs
new file mode 100644
index 0000000..d1d180e
--- /dev/null
+++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs
@@ -0,0 +1,189 @@
+// 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.
+
+pub use fortanix_sgx_abi::*;
+
+use io::{Error as IoError, Result as IoResult};
+use time::Duration;
+
+pub mod alloc;
+#[macro_use]
+mod raw;
+
+pub(crate) fn copy_user_buffer(buf: &alloc::UserRef<ByteBuffer>) -> Vec<u8> {
+    unsafe {
+        let buf = buf.to_enclave();
+        alloc::User::from_raw_parts(buf.data as _, buf.len).to_enclave()
+    }
+}
+
+pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult<usize> {
+    unsafe {
+        let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.len());
+        let len = raw::read(fd, userbuf.as_mut_ptr(), userbuf.len()).from_sgx_result()?;
+        userbuf[..len].copy_to_enclave(&mut buf[..len]);
+        Ok(len)
+    }
+}
+
+pub fn write(fd: Fd, buf: &[u8]) -> IoResult<usize> {
+    unsafe {
+        let userbuf = alloc::User::new_from_enclave(buf);
+        raw::write(fd, userbuf.as_ptr(), userbuf.len()).from_sgx_result()
+    }
+}
+
+pub fn flush(fd: Fd) -> IoResult<()> {
+    unsafe { raw::flush(fd).from_sgx_result() }
+}
+
+pub fn close(fd: Fd) {
+    unsafe { raw::close(fd) }
+}
+
+fn string_from_bytebuffer(buf: &alloc::UserRef<ByteBuffer>, usercall: &str, arg: &str) -> String {
+    String::from_utf8(copy_user_buffer(buf))
+        .unwrap_or_else(|_| panic!("Usercall {}: expected {} to be valid UTF-8", usercall, arg))
+}
+
+pub fn bind_stream(addr: &str) -> IoResult<(Fd, String)> {
+    unsafe {
+        let addr_user = alloc::User::new_from_enclave(addr.as_bytes());
+        let mut local = alloc::User::<ByteBuffer>::uninitialized();
+        let fd = raw::bind_stream(
+            addr_user.as_ptr(),
+            addr_user.len(),
+            local.as_raw_mut_ptr()
+        ).from_sgx_result()?;
+        let local = string_from_bytebuffer(&local, "bind_stream", "local_addr");
+        Ok((fd, local))
+    }
+}
+
+pub fn accept_stream(fd: Fd) -> IoResult<(Fd, String, String)> {
+    unsafe {
+        let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized();
+        let mut buf_it = alloc::UserRef::iter_mut(&mut *bufs); // FIXME: can this be done
+                                                               // without forcing coercion?
+        let (local, peer) = (buf_it.next().unwrap(), buf_it.next().unwrap());
+        let fd = raw::accept_stream(
+            fd,
+            local.as_raw_mut_ptr(),
+            peer.as_raw_mut_ptr()
+        ).from_sgx_result()?;
+        let local = string_from_bytebuffer(&local, "accept_stream", "local_addr");
+        let peer = string_from_bytebuffer(&peer, "accept_stream", "peer_addr");
+        Ok((fd, local, peer))
+    }
+}
+
+pub fn connect_stream(addr: &str) -> IoResult<(Fd, String, String)> {
+    unsafe {
+        let addr_user = alloc::User::new_from_enclave(addr.as_bytes());
+        let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized();
+        let mut buf_it = alloc::UserRef::iter_mut(&mut *bufs); // FIXME: can this be done
+                                                               // without forcing coercion?
+        let (local, peer) = (buf_it.next().unwrap(), buf_it.next().unwrap());
+        let fd = raw::connect_stream(
+            addr_user.as_ptr(),
+            addr_user.len(),
+            local.as_raw_mut_ptr(),
+            peer.as_raw_mut_ptr()
+        ).from_sgx_result()?;
+        let local = string_from_bytebuffer(&local, "connect_stream", "local_addr");
+        let peer = string_from_bytebuffer(&peer, "connect_stream", "peer_addr");
+        Ok((fd, local, peer))
+    }
+}
+
+pub fn launch_thread() -> IoResult<()> {
+    unsafe { raw::launch_thread().from_sgx_result() }
+}
+
+pub fn exit(panic: bool) -> ! {
+    unsafe { raw::exit(panic) }
+}
+
+pub fn wait(event_mask: u64, timeout: u64) -> IoResult<u64> {
+    unsafe { raw::wait(event_mask, timeout).from_sgx_result() }
+}
+
+pub fn send(event_set: u64, tcs: Option<Tcs>) -> IoResult<()> {
+    unsafe { raw::send(event_set, tcs).from_sgx_result() }
+}
+
+pub fn insecure_time() -> Duration {
+    let t = unsafe { raw::insecure_time() };
+    Duration::new(t / 1_000_000_000, (t % 1_000_000_000) as _)
+}
+
+pub fn alloc(size: usize, alignment: usize) -> IoResult<*mut u8> {
+    unsafe { raw::alloc(size, alignment).from_sgx_result() }
+}
+
+pub use self::raw::free;
+
+fn check_os_error(err: Result) -> i32 {
+    // FIXME: not sure how to make sure all variants of Error are covered
+    if err == Error::NotFound as _ ||
+       err == Error::PermissionDenied as _ ||
+       err == Error::ConnectionRefused as _ ||
+       err == Error::ConnectionReset as _ ||
+       err == Error::ConnectionAborted as _ ||
+       err == Error::NotConnected as _ ||
+       err == Error::AddrInUse as _ ||
+       err == Error::AddrNotAvailable as _ ||
+       err == Error::BrokenPipe as _ ||
+       err == Error::AlreadyExists as _ ||
+       err == Error::WouldBlock as _ ||
+       err == Error::InvalidInput as _ ||
+       err == Error::InvalidData as _ ||
+       err == Error::TimedOut as _ ||
+       err == Error::WriteZero as _ ||
+       err == Error::Interrupted as _ ||
+       err == Error::Other as _ ||
+       err == Error::UnexpectedEof as _ ||
+       ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&err)
+    {
+        err
+    } else {
+        panic!("Usercall: returned invalid error value {}", err)
+    }
+}
+
+trait FromSgxResult {
+    type Return;
+
+    fn from_sgx_result(self) -> IoResult<Self::Return>;
+}
+
+impl<T> FromSgxResult for (Result, T) {
+    type Return = T;
+
+    fn from_sgx_result(self) -> IoResult<Self::Return> {
+        if self.0 == RESULT_SUCCESS {
+            Ok(self.1)
+        } else {
+            Err(IoError::from_raw_os_error(check_os_error(self.0)))
+        }
+    }
+}
+
+impl FromSgxResult for Result {
+    type Return = ();
+
+    fn from_sgx_result(self) -> IoResult<Self::Return> {
+        if self == RESULT_SUCCESS {
+            Ok(())
+        } else {
+            Err(IoError::from_raw_os_error(check_os_error(self)))
+        }
+    }
+}
diff --git a/src/libstd/sys/sgx/abi/usercalls/raw.rs b/src/libstd/sys/sgx/abi/usercalls/raw.rs
new file mode 100644
index 0000000..a28d41c
--- /dev/null
+++ b/src/libstd/sys/sgx/abi/usercalls/raw.rs
@@ -0,0 +1,231 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused)]
+
+use fortanix_sgx_abi::*;
+
+use ptr::NonNull;
+
+#[repr(C)]
+struct UsercallReturn(u64, u64);
+
+extern "C" {
+    fn usercall(nr: u64, p1: u64, p2: u64, _ignore: u64, p3: u64, p4: u64) -> UsercallReturn;
+}
+
+unsafe fn do_usercall(nr: u64, p1: u64, p2: u64, p3: u64, p4: u64) -> (u64, u64) {
+    if nr==0 { panic!("Invalid usercall number {}",nr) }
+    let UsercallReturn(a, b) = usercall(nr,p1,p2,0,p3,p4);
+    (a, b)
+}
+
+type Register = u64;
+
+trait RegisterArgument {
+    fn from_register(Register) -> Self;
+    fn into_register(self) -> Register;
+}
+
+trait ReturnValue {
+    fn from_registers(call: &'static str, regs: (Register, Register)) -> Self;
+}
+
+macro_rules! define_usercalls {
+    // Using `$r:tt` because `$r:ty` doesn't match ! in `clobber_diverging`
+    ($(fn $f:ident($($n:ident: $t:ty),*) $(-> $r:tt)*; )*) => {
+        #[repr(C)]
+        #[allow(non_camel_case_types)]
+        enum Usercalls {
+            __enclave_usercalls_invalid,
+            $($f,)*
+        }
+
+        $(enclave_usercalls_internal_define_usercalls!(def fn $f($($n: $t),*) $(-> $r)*);)*
+    };
+}
+
+macro_rules! define_usercalls_asm {
+    ($(fn $f:ident($($n:ident: $t:ty),*) $(-> $r:ty)*; )*) => {
+        macro_rules! usercalls_asm {
+            () => {
+                concat!(
+                    ".equ usercall_nr_LAST, 0\n",
+                    $(
+                    ".equ usercall_nr_", stringify!($f), ", usercall_nr_LAST+1\n",
+                    ".equ usercall_nr_LAST, usercall_nr_", stringify!($f), "\n"
+                    ),*
+                )
+            }
+        }
+    };
+}
+
+macro_rules! define_ra {
+    (< $i:ident > $t:ty) => {
+        impl<$i> RegisterArgument for $t {
+            fn from_register(a: Register) -> Self {
+                a as _
+            }
+            fn into_register(self) -> Register {
+                self as _
+            }
+        }
+    };
+    ($i:ty as $t:ty) => {
+        impl RegisterArgument for $t {
+            fn from_register(a: Register) -> Self {
+                a as $i as _
+            }
+            fn into_register(self) -> Register {
+                self as $i as _
+            }
+        }
+    };
+    ($t:ty) => {
+        impl RegisterArgument for $t {
+            fn from_register(a: Register) -> Self {
+                a as _
+            }
+            fn into_register(self) -> Register {
+                self as _
+            }
+        }
+    };
+}
+
+define_ra!(Register);
+define_ra!(i64);
+define_ra!(u32);
+define_ra!(u32 as i32);
+define_ra!(u16);
+define_ra!(u16 as i16);
+define_ra!(u8);
+define_ra!(u8 as i8);
+define_ra!(usize);
+define_ra!(usize as isize);
+define_ra!(<T> *const T);
+define_ra!(<T> *mut T);
+
+impl RegisterArgument for bool {
+    fn from_register(a: Register) -> bool {
+        if a != 0 {
+            true
+        } else {
+            false
+        }
+    }
+    fn into_register(self) -> Register {
+        self as _
+    }
+}
+
+impl<T: RegisterArgument> RegisterArgument for Option<NonNull<T>> {
+    fn from_register(a: Register) -> Option<NonNull<T>> {
+        NonNull::new(a as _)
+    }
+    fn into_register(self) -> Register {
+        self.map_or(0 as _, NonNull::as_ptr) as _
+    }
+}
+
+impl ReturnValue for ! {
+    fn from_registers(call: &'static str, _regs: (Register, Register)) -> Self {
+        panic!("Usercall {}: did not expect to be re-entered", call);
+    }
+}
+
+impl ReturnValue for () {
+    fn from_registers(call: &'static str, regs: (Register, Register)) -> Self {
+        assert_eq!(regs.0, 0, "Usercall {}: expected {} return value to be 0", call, "1st");
+        assert_eq!(regs.1, 0, "Usercall {}: expected {} return value to be 0", call, "2nd");
+        ()
+    }
+}
+
+impl<T: RegisterArgument> ReturnValue for T {
+    fn from_registers(call: &'static str, regs: (Register, Register)) -> Self {
+        assert_eq!(regs.1, 0, "Usercall {}: expected {} return value to be 0", call, "2nd");
+        T::from_register(regs.0)
+    }
+}
+
+impl<T: RegisterArgument, U: RegisterArgument> ReturnValue for (T, U) {
+    fn from_registers(_call: &'static str, regs: (Register, Register)) -> Self {
+        (
+            T::from_register(regs.0),
+            U::from_register(regs.1)
+        )
+    }
+}
+
+macro_rules! enclave_usercalls_internal_define_usercalls {
+    (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty,
+                     $n3:ident: $t3:ty, $n4:ident: $t4:ty) -> $r:ty) => (
+        #[inline(always)]
+        pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3, $n4: $t4) -> $r {
+            ReturnValue::from_registers(stringify!($f), do_usercall(
+                Usercalls::$f as Register,
+                RegisterArgument::into_register($n1),
+                RegisterArgument::into_register($n2),
+                RegisterArgument::into_register($n3),
+                RegisterArgument::into_register($n4),
+            ))
+        }
+    );
+    (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty, $n3:ident: $t3:ty) -> $r:ty) => (
+        #[inline(always)]
+        pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3) -> $r {
+            ReturnValue::from_registers(stringify!($f), do_usercall(
+                Usercalls::$f as Register,
+                RegisterArgument::into_register($n1),
+                RegisterArgument::into_register($n2),
+                RegisterArgument::into_register($n3),
+                0
+            ))
+        }
+    );
+    (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty) -> $r:ty) => (
+        #[inline(always)]
+        pub unsafe fn $f($n1: $t1, $n2: $t2) -> $r {
+            ReturnValue::from_registers(stringify!($f), do_usercall(
+                Usercalls::$f as Register,
+                RegisterArgument::into_register($n1),
+                RegisterArgument::into_register($n2),
+                0,0
+            ))
+        }
+    );
+    (def fn $f:ident($n1:ident: $t1:ty) -> $r:ty) => (
+        #[inline(always)]
+        pub unsafe fn $f($n1: $t1) -> $r {
+            ReturnValue::from_registers(stringify!($f), do_usercall(
+                Usercalls::$f as Register,
+                RegisterArgument::into_register($n1),
+                0,0,0
+            ))
+        }
+    );
+    (def fn $f:ident() -> $r:ty) => (
+        #[inline(always)]
+        pub unsafe fn $f() -> $r {
+            ReturnValue::from_registers(stringify!($f), do_usercall(
+                Usercalls::$f as Register,
+                0,0,0,0
+            ))
+        }
+    );
+    (def fn $f:ident($($n:ident: $t:ty),*)) => (
+        enclave_usercalls_internal_define_usercalls!(def fn $f($($n: $t),*) -> ());
+    );
+}
+
+invoke_with_usercalls!(define_usercalls);
+invoke_with_usercalls!(define_usercalls_asm);
diff --git a/src/libstd/sys/sgx/alloc.rs b/src/libstd/sys/sgx/alloc.rs
new file mode 100644
index 0000000..83c20ac
--- /dev/null
+++ b/src/libstd/sys/sgx/alloc.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.
+
+extern crate dlmalloc;
+
+use alloc::{GlobalAlloc, Layout, System};
+
+use super::waitqueue::SpinMutex;
+
+// Using a SpinMutex because we never want to exit the enclave waiting for the
+// allocator.
+static DLMALLOC: SpinMutex<dlmalloc::Dlmalloc> = SpinMutex::new(dlmalloc::DLMALLOC_INIT);
+
+#[stable(feature = "alloc_system_type", since = "1.28.0")]
+unsafe impl GlobalAlloc for System {
+    #[inline]
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        DLMALLOC.lock().malloc(layout.size(), layout.align())
+    }
+
+    #[inline]
+    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+        DLMALLOC.lock().calloc(layout.size(), layout.align())
+    }
+
+    #[inline]
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+        DLMALLOC.lock().free(ptr, layout.size(), layout.align())
+    }
+
+    #[inline]
+    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+        DLMALLOC.lock().realloc(ptr, layout.size(), layout.align(), new_size)
+    }
+}
diff --git a/src/libstd/sys/sgx/args.rs b/src/libstd/sys/sgx/args.rs
new file mode 100644
index 0000000..8fb35d7
--- /dev/null
+++ b/src/libstd/sys/sgx/args.rs
@@ -0,0 +1,75 @@
+// 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 ffi::OsString;
+use super::abi::usercalls::{copy_user_buffer, alloc, ByteBuffer};
+use sync::atomic::{AtomicUsize, Ordering};
+use sys::os_str::Buf;
+use sys_common::FromInner;
+use slice;
+
+static ARGS: AtomicUsize = AtomicUsize::new(0);
+type ArgsStore = Vec<OsString>;
+
+pub unsafe fn init(argc: isize, argv: *const *const u8) {
+    if argc != 0 {
+        let args = alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _);
+        let args = args.iter()
+            .map( |a| OsString::from_inner(Buf { inner: copy_user_buffer(a) }) )
+            .collect::<ArgsStore>();
+        ARGS.store(Box::into_raw(Box::new(args)) as _, Ordering::Relaxed);
+    }
+}
+
+pub unsafe fn cleanup() {
+    let args = ARGS.swap(0, Ordering::Relaxed);
+    if args != 0 {
+        drop(Box::<ArgsStore>::from_raw(args as _))
+    }
+}
+
+pub fn args() -> Args {
+    let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
+    if let Some(args) = args {
+        Args(args.iter())
+    } else {
+        Args([].iter())
+    }
+}
+
+pub struct Args(slice::Iter<'static, OsString>);
+
+impl Args {
+    pub fn inner_debug(&self) -> &[OsString] {
+        self.0.as_slice()
+    }
+}
+
+impl Iterator for Args {
+    type Item = OsString;
+    fn next(&mut self) -> Option<OsString> {
+        self.0.next().cloned()
+    }
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
+impl ExactSizeIterator for Args {
+    fn len(&self) -> usize {
+        self.0.len()
+    }
+}
+
+impl DoubleEndedIterator for Args {
+    fn next_back(&mut self) -> Option<OsString> {
+        self.0.next_back().cloned()
+    }
+}
diff --git a/src/libstd/sys/sgx/backtrace.rs b/src/libstd/sys/sgx/backtrace.rs
new file mode 100644
index 0000000..ca4a7c9
--- /dev/null
+++ b/src/libstd/sys/sgx/backtrace.rs
@@ -0,0 +1,37 @@
+// 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 io;
+use sys::unsupported;
+use sys_common::backtrace::Frame;
+
+pub struct BacktraceContext;
+
+pub fn unwind_backtrace(_frames: &mut [Frame])
+    -> io::Result<(usize, BacktraceContext)>
+{
+    unsupported()
+}
+
+pub fn resolve_symname<F>(_frame: Frame,
+                          _callback: F,
+                          _: &BacktraceContext) -> io::Result<()>
+    where F: FnOnce(Option<&str>) -> io::Result<()>
+{
+    unsupported()
+}
+
+pub fn foreach_symbol_fileline<F>(_: Frame,
+                                  _: F,
+                                  _: &BacktraceContext) -> io::Result<bool>
+    where F: FnMut(&[u8], u32) -> io::Result<()>
+{
+    unsupported()
+}
diff --git a/src/libstd/sys/sgx/cmath.rs b/src/libstd/sys/sgx/cmath.rs
new file mode 100644
index 0000000..0c1300f
--- /dev/null
+++ b/src/libstd/sys/sgx/cmath.rs
@@ -0,0 +1,41 @@
+// 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.
+
+#![cfg(not(test))]
+
+// These symbols are all defined in `compiler-builtins`
+extern {
+    pub fn acos(n: f64) -> f64;
+    pub fn acosf(n: f32) -> f32;
+    pub fn asin(n: f64) -> f64;
+    pub fn asinf(n: f32) -> f32;
+    pub fn atan(n: f64) -> f64;
+    pub fn atan2(a: f64, b: f64) -> f64;
+    pub fn atan2f(a: f32, b: f32) -> f32;
+    pub fn atanf(n: f32) -> f32;
+    pub fn cbrt(n: f64) -> f64;
+    pub fn cbrtf(n: f32) -> f32;
+    pub fn cosh(n: f64) -> f64;
+    pub fn coshf(n: f32) -> f32;
+    pub fn expm1(n: f64) -> f64;
+    pub fn expm1f(n: f32) -> f32;
+    pub fn fdim(a: f64, b: f64) -> f64;
+    pub fn fdimf(a: f32, b: f32) -> f32;
+    pub fn hypot(x: f64, y: f64) -> f64;
+    pub fn hypotf(x: f32, y: f32) -> f32;
+    pub fn log1p(n: f64) -> f64;
+    pub fn log1pf(n: f32) -> f32;
+    pub fn sinh(n: f64) -> f64;
+    pub fn sinhf(n: f32) -> f32;
+    pub fn tan(n: f64) -> f64;
+    pub fn tanf(n: f32) -> f32;
+    pub fn tanh(n: f64) -> f64;
+    pub fn tanhf(n: f32) -> f32;
+}
diff --git a/src/libstd/sys/sgx/condvar.rs b/src/libstd/sys/sgx/condvar.rs
new file mode 100644
index 0000000..940f50f
--- /dev/null
+++ b/src/libstd/sys/sgx/condvar.rs
@@ -0,0 +1,51 @@
+// 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 sys::mutex::Mutex;
+use time::Duration;
+
+use super::waitqueue::{WaitVariable, WaitQueue, SpinMutex};
+
+pub struct Condvar {
+    inner: SpinMutex<WaitVariable<()>>,
+}
+
+impl Condvar {
+    pub const fn new() -> Condvar {
+        Condvar { inner: SpinMutex::new(WaitVariable::new(())) }
+    }
+
+    #[inline]
+    pub unsafe fn init(&mut self) {}
+
+    #[inline]
+    pub unsafe fn notify_one(&self) {
+        let _ = WaitQueue::notify_one(self.inner.lock());
+    }
+
+    #[inline]
+    pub unsafe fn notify_all(&self) {
+        let _ = WaitQueue::notify_all(self.inner.lock());
+    }
+
+    pub unsafe fn wait(&self, mutex: &Mutex) {
+        let guard = self.inner.lock();
+        mutex.unlock();
+        WaitQueue::wait(guard);
+        mutex.lock()
+    }
+
+    pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
+        panic!("timeout not supported in SGX");
+    }
+
+    #[inline]
+    pub unsafe fn destroy(&self) {}
+}
diff --git a/src/libstd/sys/sgx/env.rs b/src/libstd/sys/sgx/env.rs
new file mode 100644
index 0000000..146ce02
--- /dev/null
+++ b/src/libstd/sys/sgx/env.rs
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+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 = ".sgxs";
+    pub const DLL_EXTENSION: &'static str = "sgxs";
+    pub const EXE_SUFFIX: &'static str = ".sgxs";
+    pub const EXE_EXTENSION: &'static str = "sgxs";
+}
diff --git a/src/libstd/sys/sgx/fd.rs b/src/libstd/sys/sgx/fd.rs
new file mode 100644
index 0000000..31c4199
--- /dev/null
+++ b/src/libstd/sys/sgx/fd.rs
@@ -0,0 +1,58 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use fortanix_sgx_abi::Fd;
+
+use io;
+use mem;
+use sys_common::AsInner;
+use super::abi::usercalls;
+
+#[derive(Debug)]
+pub struct FileDesc {
+    fd: Fd,
+}
+
+impl FileDesc {
+    pub fn new(fd: Fd) -> FileDesc {
+        FileDesc { fd: fd }
+    }
+
+    pub fn raw(&self) -> Fd { self.fd }
+
+    /// Extracts the actual filedescriptor without closing it.
+    pub fn into_raw(self) -> Fd {
+        let fd = self.fd;
+        mem::forget(self);
+        fd
+    }
+
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        usercalls::read(self.fd, buf)
+    }
+
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        usercalls::write(self.fd, buf)
+    }
+
+    pub fn flush(&self) -> io::Result<()> {
+        usercalls::flush(self.fd)
+    }
+}
+
+impl AsInner<Fd> for FileDesc {
+    fn as_inner(&self) -> &Fd { &self.fd }
+}
+
+impl Drop for FileDesc {
+    fn drop(&mut self) {
+        usercalls::close(self.fd)
+    }
+}
diff --git a/src/libstd/sys/sgx/fs.rs b/src/libstd/sys/sgx/fs.rs
new file mode 100644
index 0000000..1dcea3e
--- /dev/null
+++ b/src/libstd/sys/sgx/fs.rs
@@ -0,0 +1,304 @@
+// 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 ffi::OsString;
+use fmt;
+use hash::{Hash, Hasher};
+use io::{self, SeekFrom};
+use path::{Path, PathBuf};
+use sys::time::SystemTime;
+use sys::{unsupported, Void};
+
+pub struct File(Void);
+
+pub struct FileAttr(Void);
+
+pub struct ReadDir(Void);
+
+pub struct DirEntry(Void);
+
+#[derive(Clone, Debug)]
+pub struct OpenOptions { }
+
+pub struct FilePermissions(Void);
+
+pub struct FileType(Void);
+
+#[derive(Debug)]
+pub struct DirBuilder { }
+
+impl FileAttr {
+    pub fn size(&self) -> u64 {
+        match self.0 {}
+    }
+
+    pub fn perm(&self) -> FilePermissions {
+        match self.0 {}
+    }
+
+    pub fn file_type(&self) -> FileType {
+        match self.0 {}
+    }
+
+    pub fn modified(&self) -> io::Result<SystemTime> {
+        match self.0 {}
+    }
+
+    pub fn accessed(&self) -> io::Result<SystemTime> {
+        match self.0 {}
+    }
+
+    pub fn created(&self) -> io::Result<SystemTime> {
+        match self.0 {}
+    }
+}
+
+impl Clone for FileAttr {
+    fn clone(&self) -> FileAttr {
+        match self.0 {}
+    }
+}
+
+impl FilePermissions {
+    pub fn readonly(&self) -> bool {
+        match self.0 {}
+    }
+
+    pub fn set_readonly(&mut self, _readonly: bool) {
+        match self.0 {}
+    }
+}
+
+impl Clone for FilePermissions {
+    fn clone(&self) -> FilePermissions {
+        match self.0 {}
+    }
+}
+
+impl PartialEq for FilePermissions {
+    fn eq(&self, _other: &FilePermissions) -> bool {
+        match self.0 {}
+    }
+}
+
+impl Eq for FilePermissions {
+}
+
+impl fmt::Debug for FilePermissions {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+impl FileType {
+    pub fn is_dir(&self) -> bool {
+        match self.0 {}
+    }
+
+    pub fn is_file(&self) -> bool {
+        match self.0 {}
+    }
+
+    pub fn is_symlink(&self) -> bool {
+        match self.0 {}
+    }
+}
+
+impl Clone for FileType {
+    fn clone(&self) -> FileType {
+        match self.0 {}
+    }
+}
+
+impl Copy for FileType {}
+
+impl PartialEq for FileType {
+    fn eq(&self, _other: &FileType) -> bool {
+        match self.0 {}
+    }
+}
+
+impl Eq for FileType {
+}
+
+impl Hash for FileType {
+    fn hash<H: Hasher>(&self, _h: &mut H) {
+        match self.0 {}
+    }
+}
+
+impl fmt::Debug for FileType {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+impl fmt::Debug for ReadDir {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+impl Iterator for ReadDir {
+    type Item = io::Result<DirEntry>;
+
+    fn next(&mut self) -> Option<io::Result<DirEntry>> {
+        match self.0 {}
+    }
+}
+
+impl DirEntry {
+    pub fn path(&self) -> PathBuf {
+        match self.0 {}
+    }
+
+    pub fn file_name(&self) -> OsString {
+        match self.0 {}
+    }
+
+    pub fn metadata(&self) -> io::Result<FileAttr> {
+        match self.0 {}
+    }
+
+    pub fn file_type(&self) -> io::Result<FileType> {
+        match self.0 {}
+    }
+}
+
+impl OpenOptions {
+    pub fn new() -> OpenOptions {
+        OpenOptions { }
+    }
+
+    pub fn read(&mut self, _read: bool) { }
+    pub fn write(&mut self, _write: bool) { }
+    pub fn append(&mut self, _append: bool) { }
+    pub fn truncate(&mut self, _truncate: bool) { }
+    pub fn create(&mut self, _create: bool) { }
+    pub fn create_new(&mut self, _create_new: bool) { }
+}
+
+impl File {
+    pub fn open(_path: &Path, _opts: &OpenOptions) -> io::Result<File> {
+        unsupported()
+    }
+
+    pub fn file_attr(&self) -> io::Result<FileAttr> {
+        match self.0 {}
+    }
+
+    pub fn fsync(&self) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn datasync(&self) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn truncate(&self, _size: u64) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn flush(&self) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn seek(&self, _pos: SeekFrom) -> io::Result<u64> {
+        match self.0 {}
+    }
+
+    pub fn duplicate(&self) -> io::Result<File> {
+        match self.0 {}
+    }
+
+    pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn diverge(&self) -> ! {
+        match self.0 {}
+    }
+}
+
+impl DirBuilder {
+    pub fn new() -> DirBuilder {
+        DirBuilder { }
+    }
+
+    pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
+        unsupported()
+    }
+}
+
+impl fmt::Debug for File {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+pub fn readdir(_p: &Path) -> io::Result<ReadDir> {
+    unsupported()
+}
+
+pub fn unlink(_p: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> {
+    match perm.0 {}
+}
+
+pub fn rmdir(_p: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn remove_dir_all(_path: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn readlink(_p: &Path) -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub fn symlink(_src: &Path, _dst: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub fn stat(_p: &Path) -> io::Result<FileAttr> {
+    unsupported()
+}
+
+pub fn lstat(_p: &Path) -> io::Result<FileAttr> {
+    unsupported()
+}
+
+pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> {
+    unsupported()
+}
diff --git a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs b/src/libstd/sys/sgx/memchr.rs
similarity index 77%
copy from src/test/ui/feature-gate-exhaustive_integer_patterns.rs
copy to src/libstd/sys/sgx/memchr.rs
index 3aa1522..0998bc5 100644
--- a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs
+++ b/src/libstd/sys/sgx/memchr.rs
@@ -8,9 +8,4 @@
 // 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 => {}
-    }
-}
+pub use core::slice::memchr::{memchr, memrchr};
diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs
new file mode 100644
index 0000000..dd6862e
--- /dev/null
+++ b/src/libstd/sys/sgx/mod.rs
@@ -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.
+
+//! System bindings for the Fortanix SGX platform
+//!
+//! This module contains the facade (aka platform-specific) implementations of
+//! OS level functionality for Fortanix SGX.
+
+use io;
+use os::raw::c_char;
+use sync::atomic::{AtomicBool, Ordering};
+
+pub mod abi;
+mod waitqueue;
+
+pub mod alloc;
+pub mod args;
+#[cfg(feature = "backtrace")]
+pub mod backtrace;
+pub mod cmath;
+pub mod condvar;
+pub mod env;
+pub mod fd;
+pub mod fs;
+pub mod memchr;
+pub mod mutex;
+pub mod net;
+pub mod os;
+pub mod os_str;
+pub mod path;
+pub mod pipe;
+pub mod process;
+pub mod rwlock;
+pub mod stack_overflow;
+pub mod thread;
+pub mod thread_local;
+pub mod time;
+pub mod stdio;
+
+#[cfg(not(test))]
+pub fn init() {
+}
+
+/// This function is used to implement functionality that simply doesn't exist.
+/// Programs relying on this functionality will need to deal with the error.
+pub fn unsupported<T>() -> io::Result<T> {
+    Err(unsupported_err())
+}
+
+pub fn unsupported_err() -> io::Error {
+    io::Error::new(io::ErrorKind::Other,
+                   "operation not supported on SGX yet")
+}
+
+/// This function is used to implement various functions that doesn't exist,
+/// but the lack of which might not be reason for error. If no error is
+/// returned, the program might very well be able to function normally. This is
+/// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is
+/// `false`, the behavior is the same as `unsupported`.
+pub fn sgx_ineffective<T>(v: T) -> io::Result<T> {
+    static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
+    if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
+        Err(io::Error::new(io::ErrorKind::Other,
+                       "operation can't be trusted to have any effect on SGX"))
+    } else {
+        Ok(v)
+    }
+}
+
+pub fn decode_error_kind(code: i32) -> io::ErrorKind {
+    use fortanix_sgx_abi::Error;
+
+    // FIXME: not sure how to make sure all variants of Error are covered
+    if code == Error::NotFound as _ {
+        io::ErrorKind::NotFound
+    } else if code == Error::PermissionDenied as _ {
+        io::ErrorKind::PermissionDenied
+    } else if code == Error::ConnectionRefused as _ {
+        io::ErrorKind::ConnectionRefused
+    } else if code == Error::ConnectionReset as _ {
+        io::ErrorKind::ConnectionReset
+    } else if code == Error::ConnectionAborted as _ {
+        io::ErrorKind::ConnectionAborted
+    } else if code == Error::NotConnected as _ {
+        io::ErrorKind::NotConnected
+    } else if code == Error::AddrInUse as _ {
+        io::ErrorKind::AddrInUse
+    } else if code == Error::AddrNotAvailable as _ {
+        io::ErrorKind::AddrNotAvailable
+    } else if code == Error::BrokenPipe as _ {
+        io::ErrorKind::BrokenPipe
+    } else if code == Error::AlreadyExists as _ {
+        io::ErrorKind::AlreadyExists
+    } else if code == Error::WouldBlock as _ {
+        io::ErrorKind::WouldBlock
+    } else if code == Error::InvalidInput as _ {
+        io::ErrorKind::InvalidInput
+    } else if code == Error::InvalidData as _ {
+        io::ErrorKind::InvalidData
+    } else if code == Error::TimedOut as _ {
+        io::ErrorKind::TimedOut
+    } else if code == Error::WriteZero as _ {
+        io::ErrorKind::WriteZero
+    } else if code == Error::Interrupted as _ {
+        io::ErrorKind::Interrupted
+    } else if code == Error::Other as _ {
+        io::ErrorKind::Other
+    } else if code == Error::UnexpectedEof as _ {
+        io::ErrorKind::UnexpectedEof
+    } else {
+        io::ErrorKind::Other
+    }
+}
+
+// This enum is used as the storage for a bunch of types which can't actually
+// exist.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+pub enum Void {}
+
+pub unsafe fn strlen(mut s: *const c_char) -> usize {
+    let mut n = 0;
+    while *s != 0 {
+        n += 1;
+        s = s.offset(1);
+    }
+    return n
+}
+
+pub unsafe fn abort_internal() -> ! {
+    abi::panic::panic_exit()
+}
+
+pub fn hashmap_random_keys() -> (u64, u64) {
+    fn rdrand64() -> u64 {
+        unsafe {
+            let mut ret: u64 = ::mem::uninitialized();
+            for _ in 0..10 {
+                if ::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
+                    return ret;
+                }
+            }
+            panic!("Failed to obtain random data");
+        }
+    }
+    (rdrand64(), rdrand64())
+}
diff --git a/src/libstd/sys/sgx/mutex.rs b/src/libstd/sys/sgx/mutex.rs
new file mode 100644
index 0000000..994cf91
--- /dev/null
+++ b/src/libstd/sys/sgx/mutex.rs
@@ -0,0 +1,150 @@
+// 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 fortanix_sgx_abi::Tcs;
+
+use super::abi::thread;
+
+use super::waitqueue::{WaitVariable, WaitQueue, SpinMutex, NotifiedTcs, try_lock_or_false};
+
+pub struct Mutex {
+    inner: SpinMutex<WaitVariable<bool>>,
+}
+
+// Implementation according to “Operating Systems: Three Easy Pieces”, chapter 28
+impl Mutex {
+    pub const fn new() -> Mutex {
+        Mutex { inner: SpinMutex::new(WaitVariable::new(false)) }
+    }
+
+    #[inline]
+    pub unsafe fn init(&mut self) {}
+
+    #[inline]
+    pub unsafe fn lock(&self) {
+        let mut guard = self.inner.lock();
+        if *guard.lock_var() {
+            // Another thread has the lock, wait
+            WaitQueue::wait(guard)
+            // Another thread has passed the lock to us
+        } else {
+            // We are just now obtaining the lock
+            *guard.lock_var_mut() = true;
+        }
+    }
+
+    #[inline]
+    pub unsafe fn unlock(&self) {
+        let guard = self.inner.lock();
+        if let Err(mut guard) = WaitQueue::notify_one(guard) {
+            // No other waiters, unlock
+            *guard.lock_var_mut() = false;
+        } else {
+            // There was a thread waiting, just pass the lock
+        }
+    }
+
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool {
+        let mut guard = try_lock_or_false!(self.inner);
+        if *guard.lock_var() {
+            // Another thread has the lock
+            false
+        } else {
+            // We are just now obtaining the lock
+            *guard.lock_var_mut() = true;
+            true
+        }
+    }
+
+    #[inline]
+    pub unsafe fn destroy(&self) {}
+}
+
+struct ReentrantLock {
+    owner: Option<Tcs>,
+    count: usize
+}
+
+pub struct ReentrantMutex {
+    inner: SpinMutex<WaitVariable<ReentrantLock>>,
+}
+
+impl ReentrantMutex {
+    pub const fn uninitialized() -> ReentrantMutex {
+        ReentrantMutex {
+            inner: SpinMutex::new(WaitVariable::new(ReentrantLock { owner: None, count: 0 }))
+        }
+    }
+
+    #[inline]
+    pub unsafe fn init(&mut self) {}
+
+    #[inline]
+    pub unsafe fn lock(&self) {
+        let mut guard = self.inner.lock();
+        match guard.lock_var().owner {
+            Some(tcs) if tcs != thread::current() => {
+                // Another thread has the lock, wait
+                WaitQueue::wait(guard);
+                // Another thread has passed the lock to us
+            },
+            _ => {
+                // We are just now obtaining the lock
+                guard.lock_var_mut().owner = Some(thread::current());
+                guard.lock_var_mut().count += 1;
+            },
+        }
+    }
+
+    #[inline]
+    pub unsafe fn unlock(&self) {
+        let mut guard = self.inner.lock();
+        if guard.lock_var().count > 1 {
+            guard.lock_var_mut().count -= 1;
+        } else {
+            match WaitQueue::notify_one(guard) {
+                Err(mut guard) => {
+                    // No other waiters, unlock
+                    guard.lock_var_mut().count = 0;
+                    guard.lock_var_mut().owner = None;
+                },
+                Ok(mut guard) => {
+                    // There was a thread waiting, just pass the lock
+                    if let NotifiedTcs::Single(tcs) = guard.notified_tcs() {
+                        guard.lock_var_mut().owner = Some(tcs)
+                    } else {
+                        unreachable!() // called notify_one
+                    }
+                }
+            }
+        }
+    }
+
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool {
+        let mut guard = try_lock_or_false!(self.inner);
+        match guard.lock_var().owner {
+            Some(tcs) if tcs != thread::current() => {
+                // Another thread has the lock
+                false
+            },
+            _ => {
+                // We are just now obtaining the lock
+                guard.lock_var_mut().owner = Some(thread::current());
+                guard.lock_var_mut().count += 1;
+                true
+            },
+        }
+    }
+
+    #[inline]
+    pub unsafe fn destroy(&self) {}
+}
diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs
new file mode 100644
index 0000000..176d230
--- /dev/null
+++ b/src/libstd/sys/sgx/net.rs
@@ -0,0 +1,415 @@
+// 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 fmt;
+use io;
+use net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr, ToSocketAddrs};
+use time::Duration;
+use sys::{unsupported, Void, sgx_ineffective};
+use sys::fd::FileDesc;
+use convert::TryFrom;
+use error;
+use sync::Arc;
+
+use super::abi::usercalls;
+
+const DEFAULT_FAKE_TTL: u32 = 64;
+
+#[derive(Debug, Clone)]
+struct Socket {
+    inner: Arc<FileDesc>,
+    local_addr: String,
+}
+
+impl Socket {
+    fn new(fd: usercalls::Fd, local_addr: String) -> Socket {
+        Socket { inner: Arc::new(FileDesc::new(fd)), local_addr }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct TcpStream {
+    inner: Socket,
+    peer_addr: String,
+}
+
+fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
+    match result {
+        Ok(saddr) => Ok(saddr.to_string()),
+        // need to downcast twice because io::Error::into_inner doesn't return the original
+        // value if the conversion fails
+        Err(e) => if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() {
+            Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host)
+        } else {
+            Err(e)
+        }
+    }
+}
+
+fn addr_to_sockaddr(addr: &str) -> io::Result<SocketAddr> {
+    // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry
+    addr.to_socket_addrs().map(|mut it| it.next().unwrap())
+}
+
+impl TcpStream {
+    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
+        let addr = io_err_to_addr(addr)?;
+        let (fd, local_addr, peer_addr) = usercalls::connect_stream(&addr)?;
+        Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr })
+    }
+
+    pub fn connect_timeout(addr: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
+        Self::connect(Ok(addr)) // FIXME: ignoring timeout
+    }
+
+    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        sgx_ineffective(())
+    }
+
+    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        sgx_ineffective(())
+    }
+
+    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        sgx_ineffective(None)
+    }
+
+    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        sgx_ineffective(None)
+    }
+
+    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
+        Ok(0)
+    }
+
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.inner.inner.read(buf)
+    }
+
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        self.inner.inner.write(buf)
+    }
+
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        addr_to_sockaddr(&self.peer_addr)
+    }
+
+    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+        addr_to_sockaddr(&self.inner.local_addr)
+    }
+
+    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
+        sgx_ineffective(())
+    }
+
+    pub fn duplicate(&self) -> io::Result<TcpStream> {
+        Ok(self.clone())
+    }
+
+    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
+        sgx_ineffective(())
+    }
+
+    pub fn nodelay(&self) -> io::Result<bool> {
+        sgx_ineffective(false)
+    }
+
+    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
+        sgx_ineffective(())
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        sgx_ineffective(DEFAULT_FAKE_TTL)
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        Ok(None)
+    }
+
+    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
+        sgx_ineffective(())
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct TcpListener {
+    inner: Socket,
+}
+
+impl TcpListener {
+    pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
+        let addr = io_err_to_addr(addr)?;
+        let (fd, local_addr) = usercalls::bind_stream(&addr)?;
+        Ok(TcpListener { inner: Socket::new(fd, local_addr) })
+    }
+
+    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+        addr_to_sockaddr(&self.inner.local_addr)
+    }
+
+    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
+        let (fd, local_addr, peer_addr) = usercalls::accept_stream(self.inner.inner.raw())?;
+        let ret_peer = addr_to_sockaddr(&peer_addr).unwrap_or_else(|_| ([0; 4], 0).into());
+        Ok((TcpStream { inner: Socket::new(fd, local_addr), peer_addr }, ret_peer))
+    }
+
+    pub fn duplicate(&self) -> io::Result<TcpListener> {
+        Ok(self.clone())
+    }
+
+    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
+        sgx_ineffective(())
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        sgx_ineffective(DEFAULT_FAKE_TTL)
+    }
+
+    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
+        sgx_ineffective(())
+    }
+
+    pub fn only_v6(&self) -> io::Result<bool> {
+        sgx_ineffective(false)
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        Ok(None)
+    }
+
+    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
+        sgx_ineffective(())
+    }
+}
+
+pub struct UdpSocket(Void);
+
+impl UdpSocket {
+    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
+        unsupported()
+    }
+
+    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+        match self.0 {}
+    }
+
+    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        match self.0 {}
+    }
+
+    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        match self.0 {}
+    }
+
+    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn duplicate(&self) -> io::Result<UdpSocket> {
+        match self.0 {}
+    }
+
+    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        match self.0 {}
+    }
+
+    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        match self.0 {}
+    }
+
+    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn broadcast(&self) -> io::Result<bool> {
+        match self.0 {}
+    }
+
+    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
+        match self.0 {}
+    }
+
+    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
+        match self.0 {}
+    }
+
+    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
+        match self.0 {}
+    }
+
+    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
+                         -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
+                         -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
+                          -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
+                          -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        match self.0 {}
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        match self.0 {}
+    }
+
+    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
+        match self.0 {}
+    }
+}
+
+impl fmt::Debug for UdpSocket {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+#[derive(Debug)]
+pub struct NonIpSockAddr {
+    host: String
+}
+
+impl error::Error for NonIpSockAddr {
+    fn description(&self) -> &str {
+        "Failed to convert address to SocketAddr"
+    }
+}
+
+impl fmt::Display for NonIpSockAddr {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Failed to convert address to SocketAddr: {}", self.host)
+    }
+}
+
+pub struct LookupHost(Void);
+
+impl LookupHost {
+    fn new(host: String) -> io::Result<LookupHost> {
+        Err(io::Error::new(io::ErrorKind::Other, NonIpSockAddr { host }))
+    }
+
+    pub fn port(&self) -> u16 {
+        match self.0 {}
+    }
+}
+
+impl Iterator for LookupHost {
+    type Item = SocketAddr;
+    fn next(&mut self) -> Option<SocketAddr> {
+        match self.0 {}
+    }
+}
+
+impl<'a> TryFrom<&'a str> for LookupHost {
+    type Error = io::Error;
+
+    fn try_from(v: &'a str) -> io::Result<LookupHost> {
+        LookupHost::new(v.to_owned())
+    }
+}
+
+impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
+    type Error = io::Error;
+
+    fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
+        LookupHost::new(format!("{}:{}", host, port))
+    }
+}
+
+#[allow(bad_style)]
+pub mod netc {
+    pub const AF_INET: u8 = 0;
+    pub const AF_INET6: u8 = 1;
+    pub type sa_family_t = u8;
+
+    #[derive(Copy, Clone)]
+    pub struct in_addr {
+        pub s_addr: u32,
+    }
+
+    #[derive(Copy, Clone)]
+    pub struct sockaddr_in {
+        pub sin_family: sa_family_t,
+        pub sin_port: u16,
+        pub sin_addr: in_addr,
+    }
+
+    #[derive(Copy, Clone)]
+    pub struct in6_addr {
+        pub s6_addr: [u8; 16],
+    }
+
+    #[derive(Copy, Clone)]
+    pub struct sockaddr_in6 {
+        pub sin6_family: sa_family_t,
+        pub sin6_port: u16,
+        pub sin6_addr: in6_addr,
+        pub sin6_flowinfo: u32,
+        pub sin6_scope_id: u32,
+    }
+
+    #[derive(Copy, Clone)]
+    pub struct sockaddr {
+    }
+
+    pub type socklen_t = usize;
+}
diff --git a/src/libstd/sys/sgx/os.rs b/src/libstd/sys/sgx/os.rs
new file mode 100644
index 0000000..79ebafe
--- /dev/null
+++ b/src/libstd/sys/sgx/os.rs
@@ -0,0 +1,147 @@
+// 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 fortanix_sgx_abi::{Error, RESULT_SUCCESS};
+
+use error::Error as StdError;
+use ffi::{OsString, OsStr};
+use fmt;
+use io;
+use path::{self, PathBuf};
+use str;
+use sys::{unsupported, Void, sgx_ineffective, decode_error_kind};
+use collections::HashMap;
+use vec;
+use sync::Mutex;
+use sync::atomic::{AtomicUsize, Ordering};
+use sync::Once;
+
+pub fn errno() -> i32 {
+    RESULT_SUCCESS
+}
+
+pub fn error_string(errno: i32) -> String {
+    if errno == RESULT_SUCCESS {
+        "operation succesful".into()
+    } else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) {
+        format!("user-specified error {:08x}", errno)
+    } else {
+        decode_error_kind(errno).as_str().into()
+    }
+}
+
+pub fn getcwd() -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub fn chdir(_: &path::Path) -> io::Result<()> {
+    sgx_ineffective(())
+}
+
+pub struct SplitPaths<'a>(&'a Void);
+
+pub fn split_paths(_unparsed: &OsStr) -> SplitPaths {
+    panic!("unsupported")
+}
+
+impl<'a> Iterator for SplitPaths<'a> {
+    type Item = PathBuf;
+    fn next(&mut self) -> Option<PathBuf> {
+        match *self.0 {}
+    }
+}
+
+#[derive(Debug)]
+pub struct JoinPathsError;
+
+pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
+    where I: Iterator<Item=T>, T: AsRef<OsStr>
+{
+    Err(JoinPathsError)
+}
+
+impl fmt::Display for JoinPathsError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "not supported in SGX yet".fmt(f)
+    }
+}
+
+impl StdError for JoinPathsError {
+    fn description(&self) -> &str {
+        "not supported in SGX yet"
+    }
+}
+
+pub fn current_exe() -> io::Result<PathBuf> {
+    unsupported()
+}
+
+static ENV: AtomicUsize = AtomicUsize::new(0);
+static ENV_INIT: Once = Once::new();
+type EnvStore = Mutex<HashMap<OsString, OsString>>;
+
+fn get_env_store() -> Option<&'static EnvStore> {
+    unsafe { (ENV.load(Ordering::Relaxed) as *const EnvStore).as_ref() }
+}
+
+fn create_env_store() -> &'static EnvStore {
+    ENV_INIT.call_once(|| {
+        ENV.store(Box::into_raw(Box::new(EnvStore::default())) as _, Ordering::Relaxed)
+    });
+    unsafe {
+        &*(ENV.load(Ordering::Relaxed) as *const EnvStore)
+    }
+}
+
+pub type Env = vec::IntoIter<(OsString, OsString)>;
+
+pub fn env() -> Env {
+    let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> {
+        map.iter().map(|(k, v)| (k.clone(), v.clone()) ).collect()
+    };
+
+    get_env_store()
+        .map(|env| clone_to_vec(&env.lock().unwrap()) )
+        .unwrap_or_default()
+        .into_iter()
+}
+
+pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
+    Ok(get_env_store().and_then(|s| s.lock().unwrap().get(k).cloned() ))
+}
+
+pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
+    let (k, v) = (k.to_owned(), v.to_owned());
+    create_env_store().lock().unwrap().insert(k, v);
+    Ok(())
+}
+
+pub fn unsetenv(k: &OsStr) -> io::Result<()> {
+    if let Some(env) = get_env_store() {
+        env.lock().unwrap().remove(k);
+    }
+    Ok(())
+}
+
+pub fn temp_dir() -> PathBuf {
+    panic!("no filesystem in SGX")
+}
+
+pub fn home_dir() -> Option<PathBuf> {
+    None
+}
+
+pub fn exit(code: i32) -> ! {
+    super::abi::exit_with_code(code as _)
+}
+
+pub fn getpid() -> u32 {
+    panic!("no pids in SGX")
+}
diff --git a/src/libstd/sys/sgx/os_str.rs b/src/libstd/sys/sgx/os_str.rs
new file mode 100644
index 0000000..9bfb84d
--- /dev/null
+++ b/src/libstd/sys/sgx/os_str.rs
@@ -0,0 +1,189 @@
+// 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.
+
+/// The underlying OsString/OsStr implementation on Unix systems: just
+/// a `Vec<u8>`/`[u8]`.
+
+use borrow::Cow;
+use fmt;
+use str;
+use mem;
+use rc::Rc;
+use sync::Arc;
+use sys_common::{AsInner, IntoInner};
+use sys_common::bytestring::debug_fmt_bytestring;
+use core::str::lossy::Utf8Lossy;
+
+#[derive(Clone, Hash)]
+pub struct Buf {
+    pub inner: Vec<u8>
+}
+
+pub struct Slice {
+    pub inner: [u8]
+}
+
+impl fmt::Debug for Slice {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        debug_fmt_bytestring(&self.inner, formatter)
+    }
+}
+
+impl fmt::Display for Slice {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
+    }
+}
+
+impl fmt::Debug for Buf {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(self.as_slice(), formatter)
+    }
+}
+
+impl fmt::Display for Buf {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self.as_slice(), formatter)
+    }
+}
+
+impl IntoInner<Vec<u8>> for Buf {
+    fn into_inner(self) -> Vec<u8> {
+        self.inner
+    }
+}
+
+impl AsInner<[u8]> for Buf {
+    fn as_inner(&self) -> &[u8] {
+        &self.inner
+    }
+}
+
+
+impl Buf {
+    pub fn from_string(s: String) -> Buf {
+        Buf { inner: s.into_bytes() }
+    }
+
+    #[inline]
+    pub fn with_capacity(capacity: usize) -> Buf {
+        Buf {
+            inner: Vec::with_capacity(capacity)
+        }
+    }
+
+    #[inline]
+    pub fn clear(&mut self) {
+        self.inner.clear()
+    }
+
+    #[inline]
+    pub fn capacity(&self) -> usize {
+        self.inner.capacity()
+    }
+
+    #[inline]
+    pub fn reserve(&mut self, additional: usize) {
+        self.inner.reserve(additional)
+    }
+
+    #[inline]
+    pub fn reserve_exact(&mut self, additional: usize) {
+        self.inner.reserve_exact(additional)
+    }
+
+    #[inline]
+    pub fn shrink_to_fit(&mut self) {
+        self.inner.shrink_to_fit()
+    }
+
+    #[inline]
+    pub fn shrink_to(&mut self, min_capacity: usize) {
+        self.inner.shrink_to(min_capacity)
+    }
+
+    pub fn as_slice(&self) -> &Slice {
+        unsafe { mem::transmute(&*self.inner) }
+    }
+
+    pub fn into_string(self) -> Result<String, Buf> {
+        String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() } )
+    }
+
+    pub fn push_slice(&mut self, s: &Slice) {
+        self.inner.extend_from_slice(&s.inner)
+    }
+
+    #[inline]
+    pub fn into_box(self) -> Box<Slice> {
+        unsafe { mem::transmute(self.inner.into_boxed_slice()) }
+    }
+
+    #[inline]
+    pub fn from_box(boxed: Box<Slice>) -> Buf {
+        let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
+        Buf { inner: inner.into_vec() }
+    }
+
+    #[inline]
+    pub fn into_arc(&self) -> Arc<Slice> {
+        self.as_slice().into_arc()
+    }
+
+    #[inline]
+    pub fn into_rc(&self) -> Rc<Slice> {
+        self.as_slice().into_rc()
+    }
+}
+
+impl Slice {
+    fn from_u8_slice(s: &[u8]) -> &Slice {
+        unsafe { mem::transmute(s) }
+    }
+
+    pub fn from_str(s: &str) -> &Slice {
+        Slice::from_u8_slice(s.as_bytes())
+    }
+
+    pub fn to_str(&self) -> Option<&str> {
+        str::from_utf8(&self.inner).ok()
+    }
+
+    pub fn to_string_lossy(&self) -> Cow<str> {
+        String::from_utf8_lossy(&self.inner)
+    }
+
+    pub fn to_owned(&self) -> Buf {
+        Buf { inner: self.inner.to_vec() }
+    }
+
+    #[inline]
+    pub fn into_box(&self) -> Box<Slice> {
+        let boxed: Box<[u8]> = self.inner.into();
+        unsafe { mem::transmute(boxed) }
+    }
+
+    pub fn empty_box() -> Box<Slice> {
+        let boxed: Box<[u8]> = Default::default();
+        unsafe { mem::transmute(boxed) }
+    }
+
+    #[inline]
+    pub fn into_arc(&self) -> Arc<Slice> {
+        let arc: Arc<[u8]> = Arc::from(&self.inner);
+        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
+    }
+
+    #[inline]
+    pub fn into_rc(&self) -> Rc<Slice> {
+        let rc: Rc<[u8]> = Rc::from(&self.inner);
+        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
+    }
+}
diff --git a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs b/src/libstd/sys/sgx/path.rs
similarity index 60%
copy from src/test/ui/feature-gate-exhaustive_integer_patterns.rs
copy to src/libstd/sys/sgx/path.rs
index 3aa1522..afe0c49 100644
--- a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs
+++ b/src/libstd/sys/sgx/path.rs
@@ -8,9 +8,22 @@
 // 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 => {}
-    }
+use path::Prefix;
+use ffi::OsStr;
+
+#[inline]
+pub fn is_sep_byte(b: u8) -> bool {
+    b == b'/'
 }
+
+#[inline]
+pub fn is_verbatim_sep(b: u8) -> bool {
+    b == b'/'
+}
+
+pub fn parse_prefix(_: &OsStr) -> Option<Prefix> {
+    None
+}
+
+pub const MAIN_SEP_STR: &'static str = "/";
+pub const MAIN_SEP: char = '/';
diff --git a/src/libstd/sys/sgx/pipe.rs b/src/libstd/sys/sgx/pipe.rs
new file mode 100644
index 0000000..6c6cbc1
--- /dev/null
+++ b/src/libstd/sys/sgx/pipe.rs
@@ -0,0 +1,35 @@
+// 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 io;
+use sys::Void;
+
+pub struct AnonPipe(Void);
+
+impl AnonPipe {
+    pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
+    pub fn diverge(&self) -> ! {
+        match self.0 {}
+    }
+}
+
+pub fn read2(p1: AnonPipe,
+             _v1: &mut Vec<u8>,
+             _p2: AnonPipe,
+             _v2: &mut Vec<u8>) -> io::Result<()> {
+    match p1.0 {}
+}
diff --git a/src/libstd/sys/sgx/process.rs b/src/libstd/sys/sgx/process.rs
new file mode 100644
index 0000000..01a12fb
--- /dev/null
+++ b/src/libstd/sys/sgx/process.rs
@@ -0,0 +1,162 @@
+// 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 ffi::OsStr;
+use fmt;
+use io;
+use sys::fs::File;
+use sys::pipe::AnonPipe;
+use sys::{unsupported, Void};
+use sys_common::process::{CommandEnv, DefaultEnvKey};
+
+////////////////////////////////////////////////////////////////////////////////
+// Command
+////////////////////////////////////////////////////////////////////////////////
+
+pub struct Command {
+    env: CommandEnv<DefaultEnvKey>
+}
+
+// passed back to std::process with the pipes connected to the child, if any
+// were requested
+pub struct StdioPipes {
+    pub stdin: Option<AnonPipe>,
+    pub stdout: Option<AnonPipe>,
+    pub stderr: Option<AnonPipe>,
+}
+
+pub enum Stdio {
+    Inherit,
+    Null,
+    MakePipe,
+}
+
+impl Command {
+    pub fn new(_program: &OsStr) -> Command {
+        Command {
+            env: Default::default()
+        }
+    }
+
+    pub fn arg(&mut self, _arg: &OsStr) {
+    }
+
+    pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
+        &mut self.env
+    }
+
+    pub fn cwd(&mut self, _dir: &OsStr) {
+    }
+
+    pub fn stdin(&mut self, _stdin: Stdio) {
+    }
+
+    pub fn stdout(&mut self, _stdout: Stdio) {
+    }
+
+    pub fn stderr(&mut self, _stderr: Stdio) {
+    }
+
+    pub fn spawn(&mut self, _default: Stdio, _needs_stdin: bool)
+        -> io::Result<(Process, StdioPipes)> {
+        unsupported()
+    }
+}
+
+impl From<AnonPipe> for Stdio {
+    fn from(pipe: AnonPipe) -> Stdio {
+        pipe.diverge()
+    }
+}
+
+impl From<File> for Stdio {
+    fn from(file: File) -> Stdio {
+        file.diverge()
+    }
+}
+
+impl fmt::Debug for Command {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        Ok(())
+    }
+}
+
+pub struct ExitStatus(Void);
+
+impl ExitStatus {
+    pub fn success(&self) -> bool {
+        match self.0 {}
+    }
+
+    pub fn code(&self) -> Option<i32> {
+        match self.0 {}
+    }
+}
+
+impl Clone for ExitStatus {
+    fn clone(&self) -> ExitStatus {
+        match self.0 {}
+    }
+}
+
+impl Copy for ExitStatus {}
+
+impl PartialEq for ExitStatus {
+    fn eq(&self, _other: &ExitStatus) -> bool {
+        match self.0 {}
+    }
+}
+
+impl Eq for ExitStatus {
+}
+
+impl fmt::Debug for ExitStatus {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+impl fmt::Display for ExitStatus {
+    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+        match self.0 {}
+    }
+}
+
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct ExitCode(bool);
+
+impl ExitCode {
+    pub const SUCCESS: ExitCode = ExitCode(false);
+    pub const FAILURE: ExitCode = ExitCode(true);
+
+    pub fn as_i32(&self) -> i32 {
+        self.0 as i32
+    }
+}
+
+pub struct Process(Void);
+
+impl Process {
+    pub fn id(&self) -> u32 {
+        match self.0 {}
+    }
+
+    pub fn kill(&mut self) -> io::Result<()> {
+        match self.0 {}
+    }
+
+    pub fn wait(&mut self) -> io::Result<ExitStatus> {
+        match self.0 {}
+    }
+
+    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
+        match self.0 {}
+    }
+}
diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs
new file mode 100644
index 0000000..a1551db
--- /dev/null
+++ b/src/libstd/sys/sgx/rwlock.rs
@@ -0,0 +1,133 @@
+// 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 num::NonZeroUsize;
+
+use super::waitqueue::{WaitVariable, WaitQueue, SpinMutex, NotifiedTcs, try_lock_or_false};
+
+pub struct RWLock {
+    readers: SpinMutex<WaitVariable<Option<NonZeroUsize>>>,
+    writer: SpinMutex<WaitVariable<bool>>,
+}
+
+//unsafe impl Send for RWLock {}
+//unsafe impl Sync for RWLock {} // FIXME
+
+impl RWLock {
+    pub const fn new() -> RWLock {
+        RWLock {
+            readers: SpinMutex::new(WaitVariable::new(None)),
+            writer: SpinMutex::new(WaitVariable::new(false))
+        }
+    }
+
+    #[inline]
+    pub unsafe fn read(&self) {
+        let mut rguard = self.readers.lock();
+        let wguard = self.writer.lock();
+        if *wguard.lock_var() || !wguard.queue_empty() {
+            // Another thread has or is waiting for the write lock, wait
+            drop(wguard);
+            WaitQueue::wait(rguard);
+            // Another thread has passed the lock to us
+        } else {
+            // No waiting writers, acquire the read lock
+            *rguard.lock_var_mut() =
+                NonZeroUsize::new(rguard.lock_var().map_or(0, |n| n.get()) + 1);
+        }
+    }
+
+    #[inline]
+    pub unsafe fn try_read(&self) -> bool {
+        let mut rguard = try_lock_or_false!(self.readers);
+        let wguard = try_lock_or_false!(self.writer);
+        if *wguard.lock_var() || !wguard.queue_empty() {
+            // Another thread has or is waiting for the write lock
+            false
+        } else {
+            // No waiting writers, acquire the read lock
+            *rguard.lock_var_mut() =
+                NonZeroUsize::new(rguard.lock_var().map_or(0, |n| n.get()) + 1);
+            true
+        }
+    }
+
+    #[inline]
+    pub unsafe fn write(&self) {
+        let rguard = self.readers.lock();
+        let mut wguard = self.writer.lock();
+        if *wguard.lock_var() || rguard.lock_var().is_some() {
+            // Another thread has the lock, wait
+            drop(rguard);
+            WaitQueue::wait(wguard);
+            // Another thread has passed the lock to us
+        } else {
+            // We are just now obtaining the lock
+            *wguard.lock_var_mut() = true;
+        }
+    }
+
+    #[inline]
+    pub unsafe fn try_write(&self) -> bool {
+        let rguard = try_lock_or_false!(self.readers);
+        let mut wguard = try_lock_or_false!(self.writer);
+        if *wguard.lock_var() || rguard.lock_var().is_some() {
+            // Another thread has the lock
+            false
+        } else {
+            // We are just now obtaining the lock
+            *wguard.lock_var_mut() = true;
+            true
+        }
+    }
+
+    #[inline]
+    pub unsafe fn read_unlock(&self) {
+        let mut rguard = self.readers.lock();
+        let wguard = self.writer.lock();
+        *rguard.lock_var_mut() = NonZeroUsize::new(rguard.lock_var().unwrap().get() - 1);
+        if rguard.lock_var().is_some() {
+            // There are other active readers
+        } else {
+            if let Ok(mut wguard) = WaitQueue::notify_one(wguard) {
+                // A writer was waiting, pass the lock
+                *wguard.lock_var_mut() = true;
+            } else {
+                // No writers were waiting, the lock is released
+                assert!(rguard.queue_empty());
+            }
+        }
+    }
+
+    #[inline]
+    pub unsafe fn write_unlock(&self) {
+        let rguard = self.readers.lock();
+        let wguard = self.writer.lock();
+        if let Err(mut wguard) = WaitQueue::notify_one(wguard) {
+            // No writers waiting, release the write lock
+            *wguard.lock_var_mut() = false;
+            if let Ok(mut rguard) = WaitQueue::notify_all(rguard) {
+                // One or more readers were waiting, pass the lock to them
+                if let NotifiedTcs::All { count } = rguard.notified_tcs() {
+                    *rguard.lock_var_mut() = Some(count)
+                } else {
+                    unreachable!() // called notify_all
+                }
+            } else {
+                // No readers waiting, the lock is released
+            }
+        } else {
+            // There was a thread waiting for write, just pass the lock
+        }
+    }
+
+    #[inline]
+    pub unsafe fn destroy(&self) {}
+}
diff --git a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs b/src/libstd/sys/sgx/stack_overflow.rs
similarity index 76%
copy from src/test/ui/feature-gate-exhaustive_integer_patterns.rs
copy to src/libstd/sys/sgx/stack_overflow.rs
index 3aa1522..0176b74 100644
--- a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs
+++ b/src/libstd/sys/sgx/stack_overflow.rs
@@ -8,9 +8,16 @@
 // 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 => {}
+pub struct Handler;
+
+impl Handler {
+    pub unsafe fn new() -> Handler {
+        Handler
     }
 }
+
+pub unsafe fn init() {
+}
+
+pub unsafe fn cleanup() {
+}
diff --git a/src/libstd/sys/sgx/stdio.rs b/src/libstd/sys/sgx/stdio.rs
new file mode 100644
index 0000000..13c9119
--- /dev/null
+++ b/src/libstd/sys/sgx/stdio.rs
@@ -0,0 +1,81 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use fortanix_sgx_abi as abi;
+
+use io;
+use sys::fd::FileDesc;
+
+pub struct Stdin(());
+pub struct Stdout(());
+pub struct Stderr(());
+
+fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R {
+    let fd = FileDesc::new(fd);
+    let ret = f(&fd);
+    fd.into_raw();
+    ret
+}
+
+impl Stdin {
+    pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }
+
+    pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
+        with_std_fd(abi::FD_STDIN, |fd| fd.read(data))
+    }
+}
+
+impl Stdout {
+    pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
+
+    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        with_std_fd(abi::FD_STDOUT, |fd| fd.write(data))
+    }
+
+    pub fn flush(&self) -> io::Result<()> {
+        with_std_fd(abi::FD_STDOUT, |fd| fd.flush())
+    }
+}
+
+impl Stderr {
+    pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }
+
+    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        with_std_fd(abi::FD_STDERR, |fd| fd.write(data))
+    }
+
+    pub fn flush(&self) -> io::Result<()> {
+        with_std_fd(abi::FD_STDERR, |fd| fd.flush())
+    }
+}
+
+// FIXME: right now this raw stderr handle is used in a few places because
+//        std::io::stderr_raw isn't exposed, but once that's exposed this impl
+//        should go away
+impl io::Write for Stderr {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+        Stderr::write(self, data)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Stderr::flush(self)
+    }
+}
+
+pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;
+
+pub fn is_ebadf(err: &io::Error) -> bool {
+    // FIXME: Rust normally maps Unix EBADF to `Other`
+    err.raw_os_error() == Some(abi::Error::BrokenPipe as _)
+}
+
+pub fn panic_output() -> Option<impl io::Write> {
+    super::abi::panic::SgxPanicOutput::new()
+}
diff --git a/src/libstd/sys/sgx/thread.rs b/src/libstd/sys/sgx/thread.rs
new file mode 100644
index 0000000..9de12a5
--- /dev/null
+++ b/src/libstd/sys/sgx/thread.rs
@@ -0,0 +1,101 @@
+// 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 boxed::FnBox;
+use ffi::CStr;
+use io;
+use time::Duration;
+
+use super::abi::usercalls;
+
+pub struct Thread(task_queue::JoinHandle);
+
+pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
+
+mod task_queue {
+    use sync::{Mutex, MutexGuard, Once};
+    use sync::mpsc;
+    use boxed::FnBox;
+
+    pub type JoinHandle = mpsc::Receiver<()>;
+
+    pub(super) struct Task {
+        p: Box<dyn FnBox()>,
+        done: mpsc::Sender<()>,
+    }
+
+    impl Task {
+        pub(super) fn new(p: Box<dyn FnBox()>) -> (Task, JoinHandle) {
+            let (done, recv) = mpsc::channel();
+            (Task { p, done }, recv)
+        }
+
+        pub(super) fn run(self) {
+            (self.p)();
+            let _ = self.done.send(());
+        }
+    }
+
+    static TASK_QUEUE_INIT: Once = Once::new();
+    static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
+
+    pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
+        unsafe {
+            TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()) );
+            TASK_QUEUE.as_ref().unwrap().lock().unwrap()
+        }
+    }
+}
+
+impl Thread {
+    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
+    pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>)
+        -> io::Result<Thread>
+    {
+        let mut queue_lock = task_queue::lock();
+        usercalls::launch_thread()?;
+        let (task, handle) = task_queue::Task::new(p);
+        queue_lock.push(task);
+        Ok(Thread(handle))
+    }
+
+    pub(super) fn entry() {
+        let mut guard = task_queue::lock();
+        let task = guard.pop().expect("Thread started but no tasks pending");
+        drop(guard); // make sure to not hold the task queue lock longer than necessary
+        task.run()
+    }
+
+    pub fn yield_now() {
+        assert_eq!(
+            usercalls::wait(0, usercalls::WAIT_NO).unwrap_err().kind(),
+            io::ErrorKind::WouldBlock
+        );
+    }
+
+    pub fn set_name(_name: &CStr) {
+        // FIXME: could store this pointer in TLS somewhere
+    }
+
+    pub fn sleep(_dur: Duration) {
+        panic!("can't sleep"); // FIXME
+    }
+
+    pub fn join(self) {
+        let _ = self.0.recv();
+    }
+}
+
+pub mod guard {
+    pub type Guard = !;
+    pub unsafe fn current() -> Option<Guard> { None }
+    pub unsafe fn init() -> Option<Guard> { None }
+    pub unsafe fn deinit() {}
+}
diff --git a/src/libstd/sys/sgx/thread_local.rs b/src/libstd/sys/sgx/thread_local.rs
new file mode 100644
index 0000000..3b628ba
--- /dev/null
+++ b/src/libstd/sys/sgx/thread_local.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.
+
+use super::abi::tls::{Tls, Key as AbiKey};
+
+pub type Key = usize;
+
+#[inline]
+pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
+    Tls::create(dtor).as_usize()
+}
+
+#[inline]
+pub unsafe fn set(key: Key, value: *mut u8) {
+    Tls::set(AbiKey::from_usize(key), value)
+}
+
+#[inline]
+pub unsafe fn get(key: Key) -> *mut u8 {
+    Tls::get(AbiKey::from_usize(key))
+}
+
+#[inline]
+pub unsafe fn destroy(key: Key) {
+    Tls::destroy(AbiKey::from_usize(key))
+}
+
+#[inline]
+pub fn requires_synchronized_create() -> bool {
+    false
+}
diff --git a/src/libstd/sys/sgx/time.rs b/src/libstd/sys/sgx/time.rs
new file mode 100644
index 0000000..196e1a9
--- /dev/null
+++ b/src/libstd/sys/sgx/time.rs
@@ -0,0 +1,57 @@
+// 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 time::Duration;
+use super::abi::usercalls;
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+pub struct Instant(Duration);
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+pub struct SystemTime(Duration);
+
+pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
+
+impl Instant {
+    pub fn now() -> Instant {
+        Instant(usercalls::insecure_time())
+    }
+
+    pub fn sub_instant(&self, other: &Instant) -> Duration {
+        self.0 - other.0
+    }
+
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
+        Some(Instant(self.0.checked_add(*other)?))
+    }
+
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
+        Some(Instant(self.0.checked_sub(*other)?))
+    }
+}
+
+impl SystemTime {
+    pub fn now() -> SystemTime {
+        SystemTime(usercalls::insecure_time())
+    }
+
+    pub fn sub_time(&self, other: &SystemTime)
+                    -> Result<Duration, Duration> {
+        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    }
+
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+        Some(SystemTime(self.0.checked_add(*other)?))
+    }
+
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+        Some(SystemTime(self.0.checked_sub(*other)?))
+    }
+}
diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs
new file mode 100644
index 0000000..ef0def1
--- /dev/null
+++ b/src/libstd/sys/sgx/waitqueue.rs
@@ -0,0 +1,549 @@
+// 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.
+
+/// A simple queue implementation for synchronization primitives.
+///
+/// This queue is used to implement condition variable and mutexes.
+///
+/// Users of this API are expected to use the `WaitVariable<T>` type. Since
+/// that type is not `Sync`, it needs to be protected by e.g. a `SpinMutex` to
+/// allow shared access.
+///
+/// Since userspace may send spurious wake-ups, the wakeup event state is
+/// recorded in the enclave. The wakeup event state is protected by a spinlock.
+/// The queue and associated wait state are stored in a `WaitVariable`.
+
+use ops::{Deref, DerefMut};
+use num::NonZeroUsize;
+
+use fortanix_sgx_abi::{Tcs, EV_UNPARK, WAIT_INDEFINITE};
+use super::abi::usercalls;
+use super::abi::thread;
+
+use self::unsafe_list::{UnsafeList, UnsafeListEntry};
+pub use self::spin_mutex::{SpinMutex, SpinMutexGuard, try_lock_or_false};
+
+/// An queue entry in a `WaitQueue`.
+struct WaitEntry {
+    /// TCS address of the thread that is waiting
+    tcs: Tcs,
+    /// Whether this thread has been notified to be awoken
+    wake: bool
+}
+
+/// Data stored with a `WaitQueue` alongside it. This ensures accesses to the
+/// queue and the data are synchronized, since the type itself is not `Sync`.
+///
+/// Consumers of this API should use a synchronization primitive for shared
+/// access, such as `SpinMutex`.
+#[derive(Default)]
+pub struct WaitVariable<T> {
+    queue: WaitQueue,
+    lock: T
+}
+
+impl<T> WaitVariable<T> {
+    pub const fn new(var: T) -> Self {
+        WaitVariable {
+            queue: WaitQueue::new(),
+            lock: var
+        }
+    }
+
+    pub fn queue_empty(&self) -> bool {
+        self.queue.is_empty()
+    }
+
+    pub fn lock_var(&self) -> &T {
+        &self.lock
+    }
+
+    pub fn lock_var_mut(&mut self) -> &mut T {
+        &mut self.lock
+    }
+}
+
+#[derive(Copy, Clone)]
+pub enum NotifiedTcs {
+    Single(Tcs),
+    All { count: NonZeroUsize }
+}
+
+/// An RAII guard that will notify a set of target threads as well as unlock
+/// a mutex on drop.
+pub struct WaitGuard<'a, T: 'a> {
+    mutex_guard: Option<SpinMutexGuard<'a, WaitVariable<T>>>,
+    notified_tcs: NotifiedTcs
+}
+
+/// A queue of threads that are waiting on some synchronization primitive.
+///
+/// `UnsafeList` entries are allocated on the waiting thread's stack. This
+/// avoids any global locking that might happen in the heap allocator. This is
+/// safe because the waiting thread will not return from that stack frame until
+/// after it is notified. The notifying thread ensures to clean up any
+/// references to the list entries before sending the wakeup event.
+pub struct WaitQueue {
+    // We use an inner Mutex here to protect the data in the face of spurious
+    // wakeups.
+    inner: UnsafeList<SpinMutex<WaitEntry>>,
+}
+unsafe impl Send for WaitQueue {}
+
+impl Default for WaitQueue {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl<'a, T> WaitGuard<'a, T> {
+    /// Returns which TCSes will be notified when this guard drops.
+    pub fn notified_tcs(&self) -> NotifiedTcs {
+        self.notified_tcs
+    }
+}
+
+impl<'a, T> Deref for WaitGuard<'a, T> {
+    type Target = SpinMutexGuard<'a, WaitVariable<T>>;
+
+    fn deref(&self) -> &Self::Target {
+        self.mutex_guard.as_ref().unwrap()
+    }
+}
+
+impl<'a, T> DerefMut for WaitGuard<'a, T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        self.mutex_guard.as_mut().unwrap()
+    }
+}
+
+impl<'a, T> Drop for WaitGuard<'a, T> {
+    fn drop(&mut self) {
+        drop(self.mutex_guard.take());
+        let target_tcs = match self.notified_tcs {
+            NotifiedTcs::Single(tcs) => Some(tcs),
+            NotifiedTcs::All { .. } => None
+        };
+        usercalls::send(EV_UNPARK, target_tcs).unwrap();
+    }
+}
+
+impl WaitQueue {
+    pub const fn new() -> Self {
+        WaitQueue {
+            inner: UnsafeList::new()
+        }
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.inner.is_empty()
+    }
+
+    /// Add the calling thread to the WaitVariable's wait queue, then wait
+    /// until a wakeup event.
+    ///
+    /// This function does not return until this thread has been awoken.
+    pub fn wait<T>(mut guard: SpinMutexGuard<WaitVariable<T>>) {
+        unsafe {
+            let mut entry = UnsafeListEntry::new(SpinMutex::new(WaitEntry {
+                tcs: thread::current(),
+                wake: false
+            }));
+            let entry = guard.queue.inner.push(&mut entry);
+            drop(guard);
+            while !entry.lock().wake {
+                assert_eq!(
+                    usercalls::wait(EV_UNPARK, WAIT_INDEFINITE).unwrap() & EV_UNPARK,
+                    EV_UNPARK
+                );
+            }
+        }
+    }
+
+    /// Either find the next waiter on the wait queue, or return the mutex
+    /// guard unchanged.
+    ///
+    /// If a waiter is found, a `WaitGuard` is returned which will notify the
+    /// waiter when it is dropped.
+    pub fn notify_one<T>(mut guard: SpinMutexGuard<WaitVariable<T>>)
+        -> Result<WaitGuard<T>, SpinMutexGuard<WaitVariable<T>>>
+    {
+        unsafe {
+            if let Some(entry) = guard.queue.inner.pop() {
+                let mut entry_guard = entry.lock();
+                let tcs = entry_guard.tcs;
+                entry_guard.wake = true;
+                drop(entry);
+                Ok(WaitGuard {
+                    mutex_guard: Some(guard),
+                    notified_tcs: NotifiedTcs::Single(tcs)
+                })
+            } else {
+                Err(guard)
+            }
+        }
+    }
+
+    /// Either find any and all waiters on the wait queue, or return the mutex
+    /// guard unchanged.
+    ///
+    /// If at least one waiter is found, a `WaitGuard` is returned which will
+    /// notify all waiters when it is dropped.
+    pub fn notify_all<T>(mut guard: SpinMutexGuard<WaitVariable<T>>)
+        -> Result<WaitGuard<T>, SpinMutexGuard<WaitVariable<T>>>
+    {
+        unsafe {
+            let mut count = 0;
+            while let Some(entry) = guard.queue.inner.pop() {
+                count += 1;
+                let mut entry_guard = entry.lock();
+                entry_guard.wake = true;
+            }
+            if let Some(count) = NonZeroUsize::new(count) {
+                Ok(WaitGuard {
+                    mutex_guard: Some(guard),
+                    notified_tcs: NotifiedTcs::All { count }
+                })
+            } else {
+                Err(guard)
+            }
+        }
+    }
+}
+
+/// A doubly-linked list where callers are in charge of memory allocation
+/// of the nodes in the list.
+mod unsafe_list {
+    use ptr::NonNull;
+    use mem;
+
+    pub struct UnsafeListEntry<T> {
+        next: NonNull<UnsafeListEntry<T>>,
+        prev: NonNull<UnsafeListEntry<T>>,
+        value: Option<T>
+    }
+
+    impl<T> UnsafeListEntry<T> {
+        fn dummy() -> Self {
+            UnsafeListEntry {
+                next: NonNull::dangling(),
+                prev: NonNull::dangling(),
+                value: None
+            }
+        }
+
+        pub fn new(value: T) -> Self {
+            UnsafeListEntry {
+                value: Some(value),
+                ..Self::dummy()
+            }
+        }
+    }
+
+    pub struct UnsafeList<T> {
+        head_tail: NonNull<UnsafeListEntry<T>>,
+        head_tail_entry: Option<UnsafeListEntry<T>>,
+    }
+
+    impl<T> UnsafeList<T> {
+        pub const fn new() -> Self {
+            unsafe {
+                UnsafeList {
+                    head_tail: NonNull::new_unchecked(1 as _),
+                    head_tail_entry: None
+                }
+            }
+        }
+
+        unsafe fn init(&mut self) {
+            if self.head_tail_entry.is_none() {
+                self.head_tail_entry = Some(UnsafeListEntry::dummy());
+                self.head_tail = NonNull::new_unchecked(self.head_tail_entry.as_mut().unwrap());
+                self.head_tail.as_mut().next = self.head_tail;
+                self.head_tail.as_mut().prev = self.head_tail;
+            }
+        }
+
+        pub fn is_empty(&self) -> bool {
+            unsafe {
+                if self.head_tail_entry.is_some() {
+                    let first = self.head_tail.as_ref().next;
+                    if first == self.head_tail {
+                        // ,-------> /---------\ next ---,
+                        // |         |head_tail|         |
+                        // `--- prev \---------/ <-------`
+                        assert_eq!(self.head_tail.as_ref().prev, first);
+                        true
+                    } else {
+                        false
+                    }
+                } else {
+                    true
+                }
+            }
+        }
+
+        /// Pushes an entry onto the back of the list.
+        ///
+        /// # Safety
+        ///
+        /// The entry must remain allocated until the entry is removed from the
+        /// list AND the caller who popped is done using the entry.
+        pub unsafe fn push<'a>(&mut self, entry: &'a mut UnsafeListEntry<T>) -> &'a T {
+            self.init();
+
+            // BEFORE:
+            //     /---------\ next ---> /---------\
+            // ... |prev_tail|           |head_tail| ...
+            //     \---------/ <--- prev \---------/
+            //
+            // AFTER:
+            //     /---------\ next ---> /-----\ next ---> /---------\
+            // ... |prev_tail|           |entry|           |head_tail| ...
+            //     \---------/ <--- prev \-----/ <--- prev \---------/
+            let mut entry = NonNull::new_unchecked(entry);
+            let mut prev_tail = mem::replace(&mut self.head_tail.as_mut().prev, entry);
+            entry.as_mut().prev = prev_tail;
+            entry.as_mut().next = self.head_tail;
+            prev_tail.as_mut().next = entry;
+            (*entry.as_ptr()).value.as_ref().unwrap()
+        }
+
+        /// Pops an entry from the front of the list.
+        ///
+        /// # Safety
+        ///
+        /// The caller must make sure to synchronize ending the borrow of the
+        /// return value and deallocation of the containing entry.
+        pub unsafe fn pop<'a>(&mut self) -> Option<&'a T> {
+            self.init();
+
+            if self.is_empty() {
+                None
+            } else {
+                // BEFORE:
+                //     /---------\ next ---> /-----\ next ---> /------\
+                // ... |head_tail|           |first|           |second| ...
+                //     \---------/ <--- prev \-----/ <--- prev \------/
+                //
+                // AFTER:
+                //     /---------\ next ---> /------\
+                // ... |head_tail|           |second| ...
+                //     \---------/ <--- prev \------/
+                let mut first = self.head_tail.as_mut().next;
+                let mut second = first.as_mut().next;
+                self.head_tail.as_mut().next = second;
+                second.as_mut().prev = self.head_tail;
+                first.as_mut().next = NonNull::dangling();
+                first.as_mut().prev = NonNull::dangling();
+                Some((*first.as_ptr()).value.as_ref().unwrap())
+            }
+        }
+    }
+
+    #[cfg(test)]
+    mod tests {
+        use super::*;
+        use cell::Cell;
+
+        unsafe fn assert_empty<T>(list: &mut UnsafeList<T>) {
+            assert!(list.pop().is_none(), "assertion failed: list is not empty");
+        }
+
+        #[test]
+        fn init_empty() {
+            unsafe {
+                assert_empty(&mut UnsafeList::<i32>::new());
+            }
+        }
+
+        #[test]
+        fn push_pop() {
+            unsafe {
+                let mut node = UnsafeListEntry::new(1234);
+                let mut list = UnsafeList::new();
+                assert_eq!(list.push(&mut node), &1234);
+                assert_eq!(list.pop().unwrap(), &1234);
+                assert_empty(&mut list);
+            }
+        }
+
+        #[test]
+        fn complex_pushes_pops() {
+            unsafe {
+                let mut node1 = UnsafeListEntry::new(1234);
+                let mut node2 = UnsafeListEntry::new(4567);
+                let mut node3 = UnsafeListEntry::new(9999);
+                let mut node4 = UnsafeListEntry::new(8642);
+                let mut list = UnsafeList::new();
+                list.push(&mut node1);
+                list.push(&mut node2);
+                assert_eq!(list.pop().unwrap(), &1234);
+                list.push(&mut node3);
+                assert_eq!(list.pop().unwrap(), &4567);
+                assert_eq!(list.pop().unwrap(), &9999);
+                assert_empty(&mut list);
+                list.push(&mut node4);
+                assert_eq!(list.pop().unwrap(), &8642);
+                assert_empty(&mut list);
+            }
+        }
+
+        #[test]
+        fn cell() {
+            unsafe {
+                let mut node = UnsafeListEntry::new(Cell::new(0));
+                let mut list = UnsafeList::new();
+                let noderef = list.push(&mut node);
+                assert_eq!(noderef.get(), 0);
+                list.pop().unwrap().set(1);
+                assert_empty(&mut list);
+                assert_eq!(noderef.get(), 1);
+            }
+        }
+    }
+}
+
+/// Trivial spinlock-based implementation of `sync::Mutex`.
+// FIXME: Perhaps use Intel TSX to avoid locking?
+mod spin_mutex {
+    use cell::UnsafeCell;
+    use sync::atomic::{AtomicBool, Ordering, spin_loop_hint};
+    use ops::{Deref, DerefMut};
+
+    #[derive(Default)]
+    pub struct SpinMutex<T> {
+        value: UnsafeCell<T>,
+        lock: AtomicBool,
+    }
+
+    unsafe impl<T: Send> Send for SpinMutex<T> {}
+    unsafe impl<T: Send> Sync for SpinMutex<T> {}
+
+    pub struct SpinMutexGuard<'a, T: 'a> {
+        mutex: &'a SpinMutex<T>,
+    }
+
+    impl<'a, T> !Send for SpinMutexGuard<'a, T> {}
+    unsafe impl<'a, T: Sync> Sync for SpinMutexGuard<'a, T> {}
+
+    impl<T> SpinMutex<T> {
+        pub const fn new(value: T) -> Self {
+            SpinMutex {
+                value: UnsafeCell::new(value),
+                lock: AtomicBool::new(false)
+            }
+        }
+
+        #[inline(always)]
+        pub fn lock(&self) -> SpinMutexGuard<T> {
+            loop {
+                match self.try_lock() {
+                    None => while self.lock.load(Ordering::Relaxed) {
+                        spin_loop_hint()
+                    },
+                    Some(guard) => return guard
+                }
+            }
+        }
+
+        #[inline(always)]
+        pub fn try_lock(&self) -> Option<SpinMutexGuard<T>> {
+            if !self.lock.compare_and_swap(false, true, Ordering::Acquire) {
+                Some(SpinMutexGuard {
+                    mutex: self,
+                })
+            } else {
+                None
+            }
+        }
+    }
+
+    pub macro try_lock_or_false {
+        ($e:expr) => {
+            if let Some(v) = $e.try_lock() {
+                v
+            } else {
+                return false
+            }
+        }
+    }
+
+    impl<'a, T> Deref for SpinMutexGuard<'a, T> {
+        type Target = T;
+
+        fn deref(&self) -> &T {
+            unsafe {
+                &*self.mutex.value.get()
+            }
+        }
+    }
+
+    impl<'a, T> DerefMut for SpinMutexGuard<'a, T> {
+        fn deref_mut(&mut self) -> &mut T {
+            unsafe {
+                &mut*self.mutex.value.get()
+            }
+        }
+    }
+
+    impl<'a, T> Drop for SpinMutexGuard<'a, T> {
+        fn drop(&mut self) {
+            self.mutex.lock.store(false, Ordering::Release)
+        }
+    }
+
+    #[cfg(test)]
+    mod tests {
+        #![allow(deprecated)]
+
+        use super::*;
+        use sync::Arc;
+        use thread;
+
+        #[test]
+        fn sleep() {
+            let mutex = Arc::new(SpinMutex::<i32>::default());
+            let mutex2 = mutex.clone();
+            let guard = mutex.lock();
+            let t1 = thread::spawn(move || {
+                *mutex2.lock() = 1;
+            });
+            thread::sleep_ms(50);
+            assert_eq!(*guard, 0);
+            drop(guard);
+            t1.join().unwrap();
+            assert_eq!(*mutex.lock(), 1);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use sync::Arc;
+    use thread;
+
+    #[test]
+    fn queue() {
+        let wq = Arc::new(SpinMutex::<WaitVariable<()>>::default());
+        let wq2 = wq.clone();
+
+        let locked = wq.lock();
+
+        let t1 = thread::spawn(move || {
+            assert!(WaitQueue::notify_one(wq2.lock()).is_none())
+        });
+
+        WaitQueue::wait(locked);
+
+        t1.join().unwrap();
+    }
+}
diff --git a/src/libstd/sys/unix/android.rs b/src/libstd/sys/unix/android.rs
index 1043672..462eab5 100644
--- a/src/libstd/sys/unix/android.rs
+++ b/src/libstd/sys/unix/android.rs
@@ -15,7 +15,7 @@
 //! always work with the most recent version of Android, but we also want to
 //! work with older versions of Android for whenever projects need to.
 //!
-//! Our current minimum supported Android version is `android-9`, e.g. Android
+//! Our current minimum supported Android version is `android-9`, e.g., Android
 //! with API level 9. We then in theory want to work on that and all future
 //! versions of Android!
 //!
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index 7e65bbd..af2f199 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -348,7 +348,7 @@
     /// # Examples
     ///
     /// ```no_run
-    /// # #![feature(libc)]
+    /// # #![feature(rustc_private)]
     /// extern crate libc;
     /// use std::fs::OpenOptions;
     /// use std::os::unix::fs::OpenOptionsExt;
diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs
index 737437c..bcf0d44 100644
--- a/src/libstd/sys/unix/ext/net.rs
+++ b/src/libstd/sys/unix/ext/net.rs
@@ -132,7 +132,7 @@
         if len == 0 {
             // When there is a datagram from unnamed unix socket
             // linux returns zero bytes of address
-            len = sun_path_offset() as libc::socklen_t;  // i.e. zero-length address
+            len = sun_path_offset() as libc::socklen_t;  // i.e., zero-length address
         } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
             return Err(io::Error::new(io::ErrorKind::InvalidInput,
                                       "file descriptor did not correspond to a Unix socket"));
diff --git a/src/libstd/sys/unix/l4re.rs b/src/libstd/sys/unix/l4re.rs
index 2121848..bbb0fd4 100644
--- a/src/libstd/sys/unix/l4re.rs
+++ b/src/libstd/sys/unix/l4re.rs
@@ -21,7 +21,7 @@
     use sys_common::{AsInner, FromInner, IntoInner};
     use sys::fd::FileDesc;
     use time::Duration;
-
+    use convert::TryFrom;
 
     pub extern crate libc as netc;
 
@@ -118,7 +118,7 @@
     }
 
     impl TcpStream {
-        pub fn connect(_: &SocketAddr) -> io::Result<TcpStream> {
+        pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
             unimpl!();
         }
 
@@ -216,7 +216,7 @@
     }
 
     impl TcpListener {
-        pub fn bind(_: &SocketAddr) -> io::Result<TcpListener> {
+        pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
             unimpl!();
         }
 
@@ -278,7 +278,7 @@
     }
 
     impl UdpSocket {
-        pub fn bind(_: &SocketAddr) -> io::Result<UdpSocket> {
+        pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
             unimpl!();
         }
 
@@ -402,7 +402,7 @@
             unimpl!();
         }
 
-        pub fn connect(&self, _: &SocketAddr) -> io::Result<()> {
+        pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
             unimpl!();
         }
     }
@@ -431,11 +431,30 @@
         }
     }
 
+    impl LookupHost {
+        pub fn port(&self) -> u16 {
+            unimpl!();
+        }
+    }
+
     unsafe impl Sync for LookupHost {}
     unsafe impl Send for LookupHost {}
 
-    pub fn lookup_host(_: &str) -> io::Result<LookupHost> {
-        unimpl!();
+
+    impl<'a> TryFrom<&'a str> for LookupHost {
+        type Error = io::Error;
+
+        fn try_from(_v: &'a str) -> io::Result<LookupHost> {
+            unimpl!();
+        }
+    }
+
+    impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
+        type Error = io::Error;
+
+        fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
+            unimpl!();
+        }
     }
 }
 
diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs
index 2d10541..d922be5 100644
--- a/src/libstd/sys/unix/net.rs
+++ b/src/libstd/sys/unix/net.rs
@@ -26,7 +26,7 @@
 pub type wrlen_t = size_t;
 
 // See below for the usage of SOCK_CLOEXEC, but this constant is only defined on
-// Linux currently (e.g. support doesn't exist on other platforms). In order to
+// Linux currently (e.g., support doesn't exist on other platforms). In order to
 // get name resolution to work and things to compile we just define a dummy
 // SOCK_CLOEXEC here for other platforms. Note that the dummy constant isn't
 // actually ever used (the blocks below are wrapped in `if cfg!` as well.
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/process/zircon.rs b/src/libstd/sys/unix/process/zircon.rs
index a06c73e..0335c1e 100644
--- a/src/libstd/sys/unix/process/zircon.rs
+++ b/src/libstd/sys/unix/process/zircon.rs
@@ -215,7 +215,7 @@
 // and has a closed remote end will return ERR_REMOTE_CLOSED.
 #[allow(unused)] pub const ERR_SHOULD_WAIT: zx_status_t = -22;
 
-// ERR_CANCELED: The in-progress operation (e.g. a wait) has been
+// ERR_CANCELED: The in-progress operation (e.g., a wait) has been
 // // canceled.
 #[allow(unused)] pub const ERR_CANCELED: zx_status_t = -23;
 
diff --git a/src/libstd/sys/unix/stdio.rs b/src/libstd/sys/unix/stdio.rs
index 87ba2ae..63e341a 100644
--- a/src/libstd/sys/unix/stdio.rs
+++ b/src/libstd/sys/unix/stdio.rs
@@ -76,6 +76,6 @@
 
 pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;
 
-pub fn stderr_prints_nothing() -> bool {
-    false
+pub fn panic_output() -> Option<impl io::Write> {
+    Stderr::new().ok()
 }
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index f3a45d2..4ff0600 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -49,7 +49,8 @@
 }
 
 impl Thread {
-    pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>)
+    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
+    pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>)
                           -> io::Result<Thread> {
         let p = box p;
         let mut native: libc::pthread_t = mem::zeroed();
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index 1f9539c..8f8aaa8 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -42,10 +42,6 @@
         }
     }
 
-    fn add_duration(&self, other: &Duration) -> Timespec {
-        self.checked_add_duration(other).expect("overflow when adding duration to time")
-    }
-
     fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = other
             .as_secs()
@@ -68,27 +64,25 @@
         })
     }
 
-    fn sub_duration(&self, other: &Duration) -> Timespec {
+    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = other
             .as_secs()
             .try_into() // <- target type would be `libc::time_t`
             .ok()
-            .and_then(|secs| self.t.tv_sec.checked_sub(secs))
-            .expect("overflow when subtracting duration from time");
+            .and_then(|secs| self.t.tv_sec.checked_sub(secs))?;
 
         // Similar to above, nanos can't overflow.
         let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
         if nsec < 0 {
             nsec += NSEC_PER_SEC as i32;
-            secs = secs.checked_sub(1).expect("overflow when subtracting \
-                                               duration from time");
+            secs = secs.checked_sub(1)?;
         }
-        Timespec {
+        Some(Timespec {
             t: libc::timespec {
                 tv_sec: secs,
                 tv_nsec: nsec as _,
             },
-        }
+        })
     }
 }
 
@@ -165,18 +159,16 @@
             Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
         }
 
-        pub fn add_duration(&self, other: &Duration) -> Instant {
-            Instant {
-                t: self.t.checked_add(dur2intervals(other))
-                       .expect("overflow when adding duration to instant"),
-            }
+        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
+            Some(Instant {
+                t: self.t.checked_add(checked_dur2intervals(other)?)?,
+            })
         }
 
-        pub fn sub_duration(&self, other: &Duration) -> Instant {
-            Instant {
-                t: self.t.checked_sub(dur2intervals(other))
-                       .expect("overflow when subtracting duration from instant"),
-            }
+        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
+            Some(Instant {
+                t: self.t.checked_sub(checked_dur2intervals(other)?)?,
+            })
         }
     }
 
@@ -199,16 +191,12 @@
             self.t.sub_timespec(&other.t)
         }
 
-        pub fn add_duration(&self, other: &Duration) -> SystemTime {
-            SystemTime { t: self.t.add_duration(other) }
-        }
-
         pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-            self.t.checked_add_duration(other).map(|t| SystemTime { t })
+            Some(SystemTime { t: self.t.checked_add_duration(other)? })
         }
 
-        pub fn sub_duration(&self, other: &Duration) -> SystemTime {
-            SystemTime { t: self.t.sub_duration(other) }
+        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
         }
     }
 
@@ -236,12 +224,12 @@
         }
     }
 
-    fn dur2intervals(dur: &Duration) -> u64 {
+    fn checked_dur2intervals(dur: &Duration) -> Option<u64> {
+        let nanos = dur.as_secs()
+            .checked_mul(NSEC_PER_SEC)?
+            .checked_add(dur.subsec_nanos() as u64)?;
         let info = info();
-        let nanos = dur.as_secs().checked_mul(NSEC_PER_SEC).and_then(|nanos| {
-            nanos.checked_add(dur.subsec_nanos() as u64)
-        }).expect("overflow converting duration to nanoseconds");
-        mul_div_u64(nanos, info.denom as u64, info.numer as u64)
+        Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64))
     }
 
     fn info() -> &'static libc::mach_timebase_info {
@@ -299,12 +287,12 @@
             })
         }
 
-        pub fn add_duration(&self, other: &Duration) -> Instant {
-            Instant { t: self.t.add_duration(other) }
+        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
+            Some(Instant { t: self.t.checked_add_duration(other)? })
         }
 
-        pub fn sub_duration(&self, other: &Duration) -> Instant {
-            Instant { t: self.t.sub_duration(other) }
+        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
+            Some(Instant { t: self.t.checked_sub_duration(other)? })
         }
     }
 
@@ -327,16 +315,12 @@
             self.t.sub_timespec(&other.t)
         }
 
-        pub fn add_duration(&self, other: &Duration) -> SystemTime {
-            SystemTime { t: self.t.add_duration(other) }
-        }
-
         pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-            self.t.checked_add_duration(other).map(|t| SystemTime { t })
+            Some(SystemTime { t: self.t.checked_add_duration(other)? })
         }
 
-        pub fn sub_duration(&self, other: &Duration) -> SystemTime {
-            SystemTime { t: self.t.sub_duration(other) }
+        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
         }
     }
 
diff --git a/src/libstd/sys/wasm/cmath.rs b/src/libstd/sys/wasm/cmath.rs
index 64fc14d..d4f8d66 100644
--- a/src/libstd/sys/wasm/cmath.rs
+++ b/src/libstd/sys/wasm/cmath.rs
@@ -8,85 +8,32 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[inline]
-pub unsafe fn cbrtf(n: f32) -> f32 {
-    f64::cbrt(n as f64) as f32
-}
-
-#[inline]
-pub unsafe fn expm1f(n: f32) -> f32 {
-    f64::exp_m1(n as f64) as f32
-}
-
-#[inline]
-#[allow(deprecated)]
-pub unsafe fn fdimf(a: f32, b: f32) -> f32 {
-    f64::abs_sub(a as f64, b as f64) as f32
-}
-
-#[inline]
-pub unsafe fn log1pf(n: f32) -> f32 {
-    f64::ln_1p(n as f64) as f32
-}
-
-#[inline]
-pub unsafe fn hypotf(x: f32, y: f32) -> f32 {
-    f64::hypot(x as f64, y as f64) as f32
-}
-
-#[inline]
-pub unsafe fn acosf(n: f32) -> f32 {
-    f64::acos(n as f64) as f32
-}
-
-#[inline]
-pub unsafe fn asinf(n: f32) -> f32 {
-    f64::asin(n as f64) as f32
-}
-
-#[inline]
-pub unsafe fn atan2f(n: f32, b: f32) -> f32 {
-    f64::atan2(n as f64, b as f64) as f32
-}
-
-#[inline]
-pub unsafe fn atanf(n: f32) -> f32 {
-    f64::atan(n as f64) as f32
-}
-
-#[inline]
-pub unsafe fn coshf(n: f32) -> f32 {
-    f64::cosh(n as f64) as f32
-}
-
-#[inline]
-pub unsafe fn sinhf(n: f32) -> f32 {
-    f64::sinh(n as f64) as f32
-}
-
-#[inline]
-pub unsafe fn tanf(n: f32) -> f32 {
-    f64::tan(n as f64) as f32
-}
-
-#[inline]
-pub unsafe fn tanhf(n: f32) -> f32 {
-    f64::tanh(n as f64) as f32
-}
-
 // These symbols are all defined in `compiler-builtins`
 extern {
     pub fn acos(n: f64) -> f64;
+    pub fn acosf(n: f32) -> f32;
     pub fn asin(n: f64) -> f64;
+    pub fn asinf(n: f32) -> f32;
     pub fn atan(n: f64) -> f64;
     pub fn atan2(a: f64, b: f64) -> f64;
+    pub fn atan2f(a: f32, b: f32) -> f32;
+    pub fn atanf(n: f32) -> f32;
     pub fn cbrt(n: f64) -> f64;
+    pub fn cbrtf(n: f32) -> f32;
     pub fn cosh(n: f64) -> f64;
+    pub fn coshf(n: f32) -> f32;
     pub fn expm1(n: f64) -> f64;
+    pub fn expm1f(n: f32) -> f32;
     pub fn fdim(a: f64, b: f64) -> f64;
-    pub fn log1p(n: f64) -> f64;
-    pub fn sinh(n: f64) -> f64;
-    pub fn tan(n: f64) -> f64;
-    pub fn tanh(n: f64) -> f64;
+    pub fn fdimf(a: f32, b: f32) -> f32;
     pub fn hypot(x: f64, y: f64) -> f64;
+    pub fn hypotf(x: f32, y: f32) -> f32;
+    pub fn log1p(n: f64) -> f64;
+    pub fn log1pf(n: f32) -> f32;
+    pub fn sinh(n: f64) -> f64;
+    pub fn sinhf(n: f32) -> f32;
+    pub fn tan(n: f64) -> f64;
+    pub fn tanf(n: f32) -> f32;
+    pub fn tanh(n: f64) -> f64;
+    pub fn tanhf(n: f32) -> f32;
 }
diff --git a/src/libstd/sys/wasm/net.rs b/src/libstd/sys/wasm/net.rs
index 03a5b2d..e1c33b0 100644
--- a/src/libstd/sys/wasm/net.rs
+++ b/src/libstd/sys/wasm/net.rs
@@ -13,11 +13,12 @@
 use net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
 use time::Duration;
 use sys::{unsupported, Void};
+use convert::TryFrom;
 
 pub struct TcpStream(Void);
 
 impl TcpStream {
-    pub fn connect(_: &SocketAddr) -> io::Result<TcpStream> {
+    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
         unsupported()
     }
 
@@ -103,7 +104,7 @@
 pub struct TcpListener(Void);
 
 impl TcpListener {
-    pub fn bind(_: &SocketAddr) -> io::Result<TcpListener> {
+    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
         unsupported()
     }
 
@@ -153,7 +154,7 @@
 pub struct UdpSocket(Void);
 
 impl UdpSocket {
-    pub fn bind(_: &SocketAddr) -> io::Result<UdpSocket> {
+    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
         unsupported()
     }
 
@@ -273,7 +274,7 @@
         match self.0 {}
     }
 
-    pub fn connect(&self, _: &SocketAddr) -> io::Result<()> {
+    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
         match self.0 {}
     }
 }
@@ -286,6 +287,12 @@
 
 pub struct LookupHost(Void);
 
+impl LookupHost {
+    pub fn port(&self) -> u16 {
+        match self.0 {}
+    }
+}
+
 impl Iterator for LookupHost {
     type Item = SocketAddr;
     fn next(&mut self) -> Option<SocketAddr> {
@@ -293,8 +300,20 @@
     }
 }
 
-pub fn lookup_host(_: &str) -> io::Result<LookupHost> {
-    unsupported()
+impl<'a> TryFrom<&'a str> for LookupHost {
+    type Error = io::Error;
+
+    fn try_from(_v: &'a str) -> io::Result<LookupHost> {
+        unsupported()
+    }
+}
+
+impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
+    type Error = io::Error;
+
+    fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
+        unsupported()
+    }
 }
 
 #[allow(nonstandard_style)]
diff --git a/src/libstd/sys/wasm/stdio.rs b/src/libstd/sys/wasm/stdio.rs
index 023f295..e51aba7 100644
--- a/src/libstd/sys/wasm/stdio.rs
+++ b/src/libstd/sys/wasm/stdio.rs
@@ -70,6 +70,10 @@
     true
 }
 
-pub fn stderr_prints_nothing() -> bool {
-    !cfg!(feature = "wasm_syscall")
+pub fn panic_output() -> Option<impl io::Write> {
+    if cfg!(feature = "wasm_syscall") {
+        Stderr::new().ok()
+    } else {
+        None
+    }
 }
diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs
index 4ad89c4..3d74ffd 100644
--- a/src/libstd/sys/wasm/thread.rs
+++ b/src/libstd/sys/wasm/thread.rs
@@ -19,7 +19,8 @@
 pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
 
 impl Thread {
-    pub unsafe fn new<'a>(_stack: usize, _p: Box<dyn FnBox() + 'a>)
+    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
+    pub unsafe fn new(_stack: usize, _p: Box<dyn FnBox()>)
         -> io::Result<Thread>
     {
         unsupported()
diff --git a/src/libstd/sys/wasm/time.rs b/src/libstd/sys/wasm/time.rs
index 991e817..cc56773 100644
--- a/src/libstd/sys/wasm/time.rs
+++ b/src/libstd/sys/wasm/time.rs
@@ -28,12 +28,12 @@
         self.0 - other.0
     }
 
-    pub fn add_duration(&self, other: &Duration) -> Instant {
-        Instant(self.0 + *other)
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
+        Some(Instant(self.0.checked_add(*other)?))
     }
 
-    pub fn sub_duration(&self, other: &Duration) -> Instant {
-        Instant(self.0 - *other)
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
+        Some(Instant(self.0.checked_sub(*other)?))
     }
 }
 
@@ -47,15 +47,11 @@
         self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
     }
 
-    pub fn add_duration(&self, other: &Duration) -> SystemTime {
-        SystemTime(self.0 + *other)
-    }
-
     pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-        self.0.checked_add(*other).map(|d| SystemTime(d))
+        Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    pub fn sub_duration(&self, other: &Duration) -> SystemTime {
-        SystemTime(self.0 - *other)
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+        Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
diff --git a/src/libstd/sys/windows/args.rs b/src/libstd/sys/windows/args.rs
index 4784633..9e9198e 100644
--- a/src/libstd/sys/windows/args.rs
+++ b/src/libstd/sys/windows/args.rs
@@ -11,12 +11,14 @@
 #![allow(dead_code)] // runtime init functions not used during testing
 
 use os::windows::prelude::*;
+use sys::windows::os::current_exe;
 use sys::c;
-use slice;
-use ops::Range;
 use ffi::OsString;
-use libc::{c_int, c_void};
 use fmt;
+use vec;
+use core::iter;
+use slice;
+use path::PathBuf;
 
 pub unsafe fn init(_argc: isize, _argv: *const *const u8) { }
 
@@ -24,20 +26,146 @@
 
 pub fn args() -> Args {
     unsafe {
-        let mut nArgs: c_int = 0;
-        let lpCmdLine = c::GetCommandLineW();
-        let szArgList = c::CommandLineToArgvW(lpCmdLine, &mut nArgs);
+        let lp_cmd_line = c::GetCommandLineW();
+        let parsed_args_list = parse_lp_cmd_line(
+            lp_cmd_line as *const u16,
+            || current_exe().map(PathBuf::into_os_string).unwrap_or_else(|_| OsString::new()));
 
-        // szArcList can be NULL if CommandLinToArgvW failed,
-        // but in that case nArgs is 0 so we won't actually
-        // try to read a null pointer
-        Args { cur: szArgList, range: 0..(nArgs as isize) }
+        Args { parsed_args_list: parsed_args_list.into_iter() }
     }
 }
 
+/// Implements the Windows command-line argument parsing algorithm.
+///
+/// Microsoft's documentation for the Windows CLI argument format can be found at
+/// <https://docs.microsoft.com/en-us/previous-versions//17w5ykft(v=vs.85)>.
+///
+/// Windows includes a function to do this in shell32.dll,
+/// but linking with that DLL causes the process to be registered as a GUI application.
+/// GUI applications add a bunch of overhead, even if no windows are drawn. See
+/// <https://randomascii.wordpress.com/2018/12/03/a-not-called-function-can-cause-a-5x-slowdown/>.
+///
+/// This function was tested for equivalence to the shell32.dll implementation in
+/// Windows 10 Pro v1803, using an exhaustive test suite available at
+/// <https://gist.github.com/notriddle/dde431930c392e428055b2dc22e638f5> or
+/// <https://paste.gg/p/anonymous/47d6ed5f5bd549168b1c69c799825223>.
+unsafe fn parse_lp_cmd_line<F: Fn() -> OsString>(lp_cmd_line: *const u16, exe_name: F)
+                                                 -> Vec<OsString> {
+    const BACKSLASH: u16 = '\\' as u16;
+    const QUOTE: u16 = '"' as u16;
+    const TAB: u16 = '\t' as u16;
+    const SPACE: u16 = ' ' as u16;
+    let mut ret_val = Vec::new();
+    if lp_cmd_line.is_null() || *lp_cmd_line == 0 {
+        ret_val.push(exe_name());
+        return ret_val;
+    }
+    let mut cmd_line = {
+        let mut end = 0;
+        while *lp_cmd_line.offset(end) != 0 {
+            end += 1;
+        }
+        slice::from_raw_parts(lp_cmd_line, end as usize)
+    };
+    // The executable name at the beginning is special.
+    cmd_line = match cmd_line[0] {
+        // The executable name ends at the next quote mark,
+        // no matter what.
+        QUOTE => {
+            let args = {
+                let mut cut = cmd_line[1..].splitn(2, |&c| c == QUOTE);
+                if let Some(exe) = cut.next() {
+                    ret_val.push(OsString::from_wide(exe));
+                }
+                cut.next()
+            };
+            if let Some(args) = args {
+                args
+            } else {
+                return ret_val;
+            }
+        }
+        // Implement quirk: when they say whitespace here,
+        // they include the entire ASCII control plane:
+        // "However, if lpCmdLine starts with any amount of whitespace, CommandLineToArgvW
+        // will consider the first argument to be an empty string. Excess whitespace at the
+        // end of lpCmdLine is ignored."
+        0...SPACE => {
+            ret_val.push(OsString::new());
+            &cmd_line[1..]
+        },
+        // The executable name ends at the next whitespace,
+        // no matter what.
+        _ => {
+            let args = {
+                let mut cut = cmd_line.splitn(2, |&c| c > 0 && c <= SPACE);
+                if let Some(exe) = cut.next() {
+                    ret_val.push(OsString::from_wide(exe));
+                }
+                cut.next()
+            };
+            if let Some(args) = args {
+                args
+            } else {
+                return ret_val;
+            }
+        }
+    };
+    let mut cur = Vec::new();
+    let mut in_quotes = false;
+    let mut was_in_quotes = false;
+    let mut backslash_count: usize = 0;
+    for &c in cmd_line {
+        match c {
+            // backslash
+            BACKSLASH => {
+                backslash_count += 1;
+                was_in_quotes = false;
+            },
+            QUOTE if backslash_count % 2 == 0 => {
+                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count / 2));
+                backslash_count = 0;
+                if was_in_quotes {
+                    cur.push('"' as u16);
+                    was_in_quotes = false;
+                } else {
+                    was_in_quotes = in_quotes;
+                    in_quotes = !in_quotes;
+                }
+            }
+            QUOTE if backslash_count % 2 != 0 => {
+                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count / 2));
+                backslash_count = 0;
+                was_in_quotes = false;
+                cur.push(b'"' as u16);
+            }
+            SPACE | TAB if !in_quotes => {
+                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count));
+                if !cur.is_empty() || was_in_quotes {
+                    ret_val.push(OsString::from_wide(&cur[..]));
+                    cur.truncate(0);
+                }
+                backslash_count = 0;
+                was_in_quotes = false;
+            }
+            _ => {
+                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count));
+                backslash_count = 0;
+                was_in_quotes = false;
+                cur.push(c);
+            }
+        }
+    }
+    cur.extend(iter::repeat(b'\\' as u16).take(backslash_count));
+    // include empty quoted strings at the end of the arguments list
+    if !cur.is_empty() || was_in_quotes || in_quotes {
+        ret_val.push(OsString::from_wide(&cur[..]));
+    }
+    ret_val
+}
+
 pub struct Args {
-    range: Range<isize>,
-    cur: *mut *mut u16,
+    parsed_args_list: vec::IntoIter<OsString>,
 }
 
 pub struct ArgsInnerDebug<'a> {
@@ -46,19 +174,7 @@
 
 impl<'a> fmt::Debug for ArgsInnerDebug<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.write_str("[")?;
-        let mut first = true;
-        for i in self.args.range.clone() {
-            if !first {
-                f.write_str(", ")?;
-            }
-            first = false;
-
-            // Here we do allocation which could be avoided.
-            fmt::Debug::fmt(&unsafe { os_string_from_ptr(*self.args.cur.offset(i)) }, f)?;
-        }
-        f.write_str("]")?;
-        Ok(())
+        self.args.parsed_args_list.as_slice().fmt(f)
     }
 }
 
@@ -70,38 +186,82 @@
     }
 }
 
-unsafe fn os_string_from_ptr(ptr: *mut u16) -> OsString {
-    let mut len = 0;
-    while *ptr.offset(len) != 0 { len += 1; }
-
-    // Push it onto the list.
-    let ptr = ptr as *const u16;
-    let buf = slice::from_raw_parts(ptr, len as usize);
-    OsStringExt::from_wide(buf)
-}
-
 impl Iterator for Args {
     type Item = OsString;
-    fn next(&mut self) -> Option<OsString> {
-        self.range.next().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } )
-    }
-    fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
+    fn next(&mut self) -> Option<OsString> { self.parsed_args_list.next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.parsed_args_list.size_hint() }
 }
 
 impl DoubleEndedIterator for Args {
-    fn next_back(&mut self) -> Option<OsString> {
-        self.range.next_back().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } )
-    }
+    fn next_back(&mut self) -> Option<OsString> { self.parsed_args_list.next_back() }
 }
 
 impl ExactSizeIterator for Args {
-    fn len(&self) -> usize { self.range.len() }
+    fn len(&self) -> usize { self.parsed_args_list.len() }
 }
 
-impl Drop for Args {
-    fn drop(&mut self) {
-        // self.cur can be null if CommandLineToArgvW previously failed,
-        // but LocalFree ignores NULL pointers
-        unsafe { c::LocalFree(self.cur as *mut c_void); }
+#[cfg(test)]
+mod tests {
+    use sys::windows::args::*;
+    use ffi::OsString;
+
+    fn chk(string: &str, parts: &[&str]) {
+        let mut wide: Vec<u16> = OsString::from(string).encode_wide().collect();
+        wide.push(0);
+        let parsed = unsafe {
+            parse_lp_cmd_line(wide.as_ptr() as *const u16, || OsString::from("TEST.EXE"))
+        };
+        let expected: Vec<OsString> = parts.iter().map(|k| OsString::from(k)).collect();
+        assert_eq!(parsed.as_slice(), expected.as_slice());
+    }
+
+    #[test]
+    fn empty() {
+        chk("", &["TEST.EXE"]);
+        chk("\0", &["TEST.EXE"]);
+    }
+
+    #[test]
+    fn single_words() {
+        chk("EXE one_word", &["EXE", "one_word"]);
+        chk("EXE a", &["EXE", "a"]);
+        chk("EXE 😅", &["EXE", "😅"]);
+        chk("EXE 😅🤦", &["EXE", "😅🤦"]);
+    }
+
+    #[test]
+    fn official_examples() {
+        chk(r#"EXE "abc" d e"#, &["EXE", "abc", "d", "e"]);
+        chk(r#"EXE a\\\b d"e f"g h"#, &["EXE", r#"a\\\b"#, "de fg", "h"]);
+        chk(r#"EXE a\\\"b c d"#, &["EXE", r#"a\"b"#, "c", "d"]);
+        chk(r#"EXE a\\\\"b c" d e"#, &["EXE", r#"a\\b c"#, "d", "e"]);
+    }
+
+    #[test]
+    fn whitespace_behavior() {
+        chk(r#" test"#, &["", "test"]);
+        chk(r#"  test"#, &["", "test"]);
+        chk(r#" test test2"#, &["", "test", "test2"]);
+        chk(r#" test  test2"#, &["", "test", "test2"]);
+        chk(r#"test test2 "#, &["test", "test2"]);
+        chk(r#"test  test2 "#, &["test", "test2"]);
+        chk(r#"test "#, &["test"]);
+    }
+
+    #[test]
+    fn genius_quotes() {
+        chk(r#"EXE "" """#, &["EXE", "", ""]);
+        chk(r#"EXE "" """"#, &["EXE", "", "\""]);
+        chk(
+            r#"EXE "this is """all""" in the same argument""#,
+            &["EXE", "this is \"all\" in the same argument"]
+        );
+        chk(r#"EXE "a"""#, &["EXE", "a\""]);
+        chk(r#"EXE "a"" a"#, &["EXE", "a\"", "a"]);
+        // quotes cannot be escaped in command names
+        chk(r#""EXE" check"#, &["EXE", "check"]);
+        chk(r#""EXE check""#, &["EXE check"]);
+        chk(r#""EXE """for""" check"#, &["EXE ", r#"for""#, "check"]);
+        chk(r#""EXE \"for\" check"#, &[r#"EXE \"#, r#"for""#,  "check"]);
     }
 }
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index c84874a..fa21f45 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -1035,9 +1035,6 @@
 
     pub fn SetLastError(dwErrCode: DWORD);
     pub fn GetCommandLineW() -> *mut LPCWSTR;
-    pub fn LocalFree(ptr: *mut c_void);
-    pub fn CommandLineToArgvW(lpCmdLine: *mut LPCWSTR,
-                              pNumArgs: *mut c_int) -> *mut *mut u16;
     pub fn GetTempPathW(nBufferLength: DWORD,
                         lpBuffer: LPCWSTR) -> DWORD;
     pub fn OpenProcessToken(ProcessHandle: HANDLE,
diff --git a/src/libstd/sys/windows/ext/ffi.rs b/src/libstd/sys/windows/ext/ffi.rs
index bae0d02..0a13aea 100644
--- a/src/libstd/sys/windows/ext/ffi.rs
+++ b/src/libstd/sys/windows/ext/ffi.rs
@@ -117,7 +117,7 @@
 /// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait OsStrExt {
-    /// Re-encodes an `OsStr` as a wide character sequence, i.e. potentially
+    /// Re-encodes an `OsStr` as a wide character sequence, i.e., potentially
     /// ill-formed UTF-16.
     ///
     /// This is lossless: calling [`OsString::from_wide`] and then
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index 082d468..949060b 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -443,7 +443,7 @@
 
 impl fmt::Debug for File {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        // FIXME(#24570): add more info here (e.g. mode)
+        // FIXME(#24570): add more info here (e.g., mode)
         let mut b = f.debug_struct("File");
         b.field("handle", &self.handle.raw());
         if let Ok(path) = get_path(&self) {
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index 4d7b723..84ef62e 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -67,7 +67,7 @@
                                     buf.len() as c::DWORD,
                                     ptr::null()) as usize;
         if res == 0 {
-            // Sometimes FormatMessageW can fail e.g. system doesn't like langId,
+            // Sometimes FormatMessageW can fail e.g., system doesn't like langId,
             let fm_err = errno();
             return format!("OS Error {} (FormatMessageW() returned error {})",
                            errnum, fm_err);
@@ -76,7 +76,7 @@
         match String::from_utf16(&buf[..res]) {
             Ok(mut msg) => {
                 // Trim trailing CRLF inserted by FormatMessageW
-                let len = msg.trim_right().len();
+                let len = msg.trim_end().len();
                 msg.truncate(len);
                 msg
             },
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index 4b19519..f9eed31 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -100,23 +100,23 @@
                                              0,
                                              ptr::null_mut());
 
-            // We pass the FILE_FLAG_FIRST_PIPE_INSTANCE flag above, and we're
+            // We pass the `FILE_FLAG_FIRST_PIPE_INSTANCE` flag above, and we're
             // also just doing a best effort at selecting a unique name. If
-            // ERROR_ACCESS_DENIED is returned then it could mean that we
+            // `ERROR_ACCESS_DENIED` is returned then it could mean that we
             // accidentally conflicted with an already existing pipe, so we try
             // again.
             //
             // Don't try again too much though as this could also perhaps be a
             // legit error.
-            // If ERROR_INVALID_PARAMETER is returned, this probably means we're
-            // running on pre-Vista version where PIPE_REJECT_REMOTE_CLIENTS is
+            // If `ERROR_INVALID_PARAMETER` is returned, this probably means we're
+            // running on pre-Vista version where `PIPE_REJECT_REMOTE_CLIENTS` is
             // not supported, so we continue retrying without it. This implies
             // reduced security on Windows versions older than Vista by allowing
             // connections to this pipe from remote machines.
             // Proper fix would increase the number of FFI imports and introduce
             // significant amount of Windows XP specific code with no clean
             // testing strategy
-            // for more info see https://github.com/rust-lang/rust/pull/37677
+            // For more info, see https://github.com/rust-lang/rust/pull/37677.
             if handle == c::INVALID_HANDLE_VALUE {
                 let err = io::Error::last_os_error();
                 let raw_os_err = err.raw_os_error();
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index ff1ee0d..03c1bb5 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -487,7 +487,7 @@
             } else {
                 if x == '"' as u16 {
                     // Add n+1 backslashes to total 2n+1 before internal '"'.
-                    cmd.extend((0..(backslashes + 1)).map(|_| '\\' as u16));
+                    cmd.extend((0..=backslashes).map(|_| '\\' as u16));
                 }
                 backslashes = 0;
             }
diff --git a/src/libstd/sys/windows/stdio.rs b/src/libstd/sys/windows/stdio.rs
index c3a9469..61e0db8 100644
--- a/src/libstd/sys/windows/stdio.rs
+++ b/src/libstd/sys/windows/stdio.rs
@@ -228,6 +228,6 @@
 // been seen to be acceptable.
 pub const STDIN_BUF_SIZE: usize = 8 * 1024;
 
-pub fn stderr_prints_nothing() -> bool {
-    false
+pub fn panic_output() -> Option<impl io::Write> {
+    Stderr::new().ok()
 }
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index 85588cc..1a97dd1 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -28,7 +28,8 @@
 }
 
 impl Thread {
-    pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>)
+    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
+    pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>)
                           -> io::Result<Thread> {
         let p = box p;
 
diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs
index c809a0b..bb2c97e 100644
--- a/src/libstd/sys/windows/time.rs
+++ b/src/libstd/sys/windows/time.rs
@@ -68,30 +68,27 @@
         Duration::new(nanos / NANOS_PER_SEC, (nanos % NANOS_PER_SEC) as u32)
     }
 
-    pub fn add_duration(&self, other: &Duration) -> Instant {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
         let freq = frequency() as u64;
-        let t = other.as_secs().checked_mul(freq).and_then(|i| {
-            (self.t as u64).checked_add(i)
-        }).and_then(|i| {
-            i.checked_add(mul_div_u64(other.subsec_nanos() as u64, freq,
-                                      NANOS_PER_SEC))
-        }).expect("overflow when adding duration to time");
-        Instant {
+        let t = other.as_secs()
+            .checked_mul(freq)?
+            .checked_add(mul_div_u64(other.subsec_nanos() as u64, freq, NANOS_PER_SEC))?
+            .checked_add(self.t as u64)?;
+        Some(Instant {
             t: t as c::LARGE_INTEGER,
-        }
+        })
     }
 
-    pub fn sub_duration(&self, other: &Duration) -> Instant {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
         let freq = frequency() as u64;
         let t = other.as_secs().checked_mul(freq).and_then(|i| {
             (self.t as u64).checked_sub(i)
         }).and_then(|i| {
-            i.checked_sub(mul_div_u64(other.subsec_nanos() as u64, freq,
-                                      NANOS_PER_SEC))
-        }).expect("overflow when subtracting duration from time");
-        Instant {
+            i.checked_sub(mul_div_u64(other.subsec_nanos() as u64, freq, NANOS_PER_SEC))
+        })?;
+        Some(Instant {
             t: t as c::LARGE_INTEGER,
-        }
+        })
     }
 }
 
@@ -127,20 +124,14 @@
         }
     }
 
-    pub fn add_duration(&self, other: &Duration) -> SystemTime {
-        self.checked_add_duration(other).expect("overflow when adding duration to time")
-    }
-
     pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-        checked_dur2intervals(other)
-            .and_then(|d| self.intervals().checked_add(d))
-            .map(|i| SystemTime::from_intervals(i))
+        let intervals = self.intervals().checked_add(checked_dur2intervals(other)?)?;
+        Some(SystemTime::from_intervals(intervals))
     }
 
-    pub fn sub_duration(&self, other: &Duration) -> SystemTime {
-        let intervals = self.intervals().checked_sub(dur2intervals(other))
-                            .expect("overflow when subtracting from time");
-        SystemTime::from_intervals(intervals)
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+        let intervals = self.intervals().checked_sub(checked_dur2intervals(other)?)?;
+        Some(SystemTime::from_intervals(intervals))
     }
 }
 
@@ -184,16 +175,12 @@
     }
 }
 
-fn checked_dur2intervals(d: &Duration) -> Option<i64> {
-    d.as_secs()
-        .checked_mul(INTERVALS_PER_SEC)
-        .and_then(|i| i.checked_add(d.subsec_nanos() as u64 / 100))
-        .and_then(|i| i.try_into().ok())
-}
-
-fn dur2intervals(d: &Duration) -> i64 {
-    checked_dur2intervals(d)
-        .expect("overflow when converting duration to intervals")
+fn checked_dur2intervals(dur: &Duration) -> Option<i64> {
+    dur.as_secs()
+        .checked_mul(INTERVALS_PER_SEC)?
+        .checked_add(dur.subsec_nanos() as u64 / 100)?
+        .try_into()
+        .ok()
 }
 
 fn intervals2dur(intervals: u64) -> Duration {
diff --git a/src/libstd/sys_common/gnu/libbacktrace.rs b/src/libstd/sys_common/gnu/libbacktrace.rs
index 6ad3af6..c2589d4 100644
--- a/src/libstd/sys_common/gnu/libbacktrace.rs
+++ b/src/libstd/sys_common/gnu/libbacktrace.rs
@@ -23,7 +23,7 @@
 where F: FnMut(&[u8], u32) -> io::Result<()>
 {
     // pcinfo may return an arbitrary number of file:line pairs,
-    // in the order of stack trace (i.e. inlined calls first).
+    // in the order of stack trace (i.e., inlined calls first).
     // in order to avoid allocation, we stack-allocate a fixed size of entries.
     const FILELINE_SIZE: usize = 32;
     let mut fileline_buf = [(ptr::null(), !0); FILELINE_SIZE];
diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs
index 4b8cde3..881794d 100644
--- a/src/libstd/sys_common/mod.rs
+++ b/src/libstd/sys_common/mod.rs
@@ -57,9 +57,11 @@
 pub mod process;
 
 cfg_if! {
-    if #[cfg(any(target_os = "cloudabi", target_os = "l4re", target_os = "redox"))] {
-        pub use sys::net;
-    } else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] {
+    if #[cfg(any(target_os = "cloudabi",
+                 target_os = "l4re",
+                 target_os = "redox",
+                 all(target_arch = "wasm32", not(target_os = "emscripten")),
+                 target_env = "sgx"))] {
         pub use sys::net;
     } else {
         pub mod net;
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index d09a233e..dce2bf7 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -20,6 +20,7 @@
 use sys::net::netc as c;
 use sys_common::{AsInner, FromInner, IntoInner};
 use time::Duration;
+use convert::{TryFrom, TryInto};
 
 #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
           target_os = "ios", target_os = "macos",
@@ -129,6 +130,13 @@
 pub struct LookupHost {
     original: *mut c::addrinfo,
     cur: *mut c::addrinfo,
+    port: u16
+}
+
+impl LookupHost {
+    pub fn port(&self) -> u16 {
+        self.port
+    }
 }
 
 impl Iterator for LookupHost {
@@ -158,17 +166,45 @@
     }
 }
 
-pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
-    init();
+impl<'a> TryFrom<&'a str> for LookupHost {
+    type Error = io::Error;
 
-    let c_host = CString::new(host)?;
-    let mut hints: c::addrinfo = unsafe { mem::zeroed() };
-    hints.ai_socktype = c::SOCK_STREAM;
-    let mut res = ptr::null_mut();
-    unsafe {
-        cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)).map(|_| {
-            LookupHost { original: res, cur: res }
-        })
+    fn try_from(s: &str) -> io::Result<LookupHost> {
+        macro_rules! try_opt {
+            ($e:expr, $msg:expr) => (
+                match $e {
+                    Some(r) => r,
+                    None => return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                                      $msg)),
+                }
+            )
+        }
+
+        // split the string by ':' and convert the second part to u16
+        let mut parts_iter = s.rsplitn(2, ':');
+        let port_str = try_opt!(parts_iter.next(), "invalid socket address");
+        let host = try_opt!(parts_iter.next(), "invalid socket address");
+        let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
+
+        (host, port).try_into()
+    }
+}
+
+impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
+    type Error = io::Error;
+
+    fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
+        init();
+
+        let c_host = CString::new(host)?;
+        let mut hints: c::addrinfo = unsafe { mem::zeroed() };
+        hints.ai_socktype = c::SOCK_STREAM;
+        let mut res = ptr::null_mut();
+        unsafe {
+            cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)).map(|_| {
+                LookupHost { original: res, cur: res, port }
+            })
+        }
     }
 }
 
@@ -181,7 +217,9 @@
 }
 
 impl TcpStream {
-    pub fn connect(addr: &SocketAddr) -> io::Result<TcpStream> {
+    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
+        let addr = addr?;
+
         init();
 
         let sock = Socket::new(addr, c::SOCK_STREAM)?;
@@ -317,7 +355,9 @@
 }
 
 impl TcpListener {
-    pub fn bind(addr: &SocketAddr) -> io::Result<TcpListener> {
+    pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
+        let addr = addr?;
+
         init();
 
         let sock = Socket::new(addr, c::SOCK_STREAM)?;
@@ -418,7 +458,9 @@
 }
 
 impl UdpSocket {
-    pub fn bind(addr: &SocketAddr) -> io::Result<UdpSocket> {
+    pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
+        let addr = addr?;
+
         init();
 
         let sock = Socket::new(addr, c::SOCK_DGRAM)?;
@@ -584,8 +626,8 @@
         Ok(ret as usize)
     }
 
-    pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
-        let (addrp, len) = addr.into_inner();
+    pub fn connect(&self, addr: io::Result<&SocketAddr>) -> io::Result<()> {
+        let (addrp, len) = addr?.into_inner();
         cvt_r(|| unsafe { c::connect(*self.inner.as_inner(), addrp, len) }).map(|_| ())
     }
 }
@@ -618,7 +660,7 @@
     #[test]
     fn no_lookup_host_duplicates() {
         let mut addrs = HashMap::new();
-        let lh = match lookup_host("localhost") {
+        let lh = match LookupHost::try_from(("localhost", 0)) {
             Ok(lh) => lh,
             Err(e) => panic!("couldn't resolve `localhost': {}", e)
         };
diff --git a/src/libstd/sys_common/util.rs b/src/libstd/sys_common/util.rs
index a373e98..fc86a59 100644
--- a/src/libstd/sys_common/util.rs
+++ b/src/libstd/sys_common/util.rs
@@ -10,14 +10,13 @@
 
 use fmt;
 use io::prelude::*;
-use sys::stdio::{Stderr, stderr_prints_nothing};
+use sys::stdio::panic_output;
 use thread;
 
 pub fn dumb_print(args: fmt::Arguments) {
-    if stderr_prints_nothing() {
-        return
+    if let Some(mut out) = panic_output() {
+        let _ = out.write_fmt(args);
     }
-    let _ = Stderr::new().map(|mut stderr| stderr.write_fmt(args));
 }
 
 // Other platforms should use the appropriate platform-specific mechanism for
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index 4df4751..8bb9909 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -269,7 +269,7 @@
         //      ptr::write(ptr, Some(value))
         //
         // Due to this pattern it's possible for the destructor of the value in
-        // `ptr` (e.g. if this is being recursively initialized) to re-access
+        // `ptr` (e.g., if this is being recursively initialized) to re-access
         // TLS, in which case there will be a `&` and `&mut` pointer to the same
         // value (an aliasing violation). To avoid setting the "I'm running a
         // destructor" flag we just use `mem::replace` which should sequence the
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 3a9f3ec..b70dfc4 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -93,7 +93,7 @@
 //! Threads are represented via the [`Thread`] type, which you can get in one of
 //! two ways:
 //!
-//! * By spawning a new thread, e.g. using the [`thread::spawn`][`spawn`]
+//! * By spawning a new thread, e.g., using the [`thread::spawn`][`spawn`]
 //!   function, and calling [`thread`][`JoinHandle::thread`] on the [`JoinHandle`].
 //! * By requesting the current thread, using the [`thread::current`] function.
 //!
@@ -124,7 +124,7 @@
 //! thread, use [`Thread::name`]. A couple examples of where the name of a thread gets used:
 //!
 //! * If a panic occurs in a named thread, the thread name will be printed in the panic message.
-//! * The thread name is provided to the OS where applicable (e.g. `pthread_setname_np` in
+//! * The thread name is provided to the OS where applicable (e.g., `pthread_setname_np` in
 //!   unix-like platforms).
 //!
 //! ## Stack size
@@ -167,10 +167,12 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use any::Any;
+use boxed::FnBox;
 use cell::UnsafeCell;
 use ffi::{CStr, CString};
 use fmt;
 use io;
+use mem;
 use panic;
 use panicking;
 use str;
@@ -420,7 +422,7 @@
     ///
     /// - ensure that [`join`][`JoinHandle::join`] is called before any referenced
     /// data is dropped
-    /// - use only types with `'static` lifetime bounds, i.e. those with no or only
+    /// - use only types with `'static` lifetime bounds, i.e., those with no or only
     /// `'static` references (both [`thread::Builder::spawn`][`Builder::spawn`]
     /// and [`thread::spawn`][`spawn`] enforce this property statically)
     ///
@@ -452,8 +454,8 @@
     /// [`io::Result`]: ../../std/io/type.Result.html
     /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
     #[unstable(feature = "thread_spawn_unchecked", issue = "55132")]
-    pub unsafe fn spawn_unchecked<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
-        F: FnOnce() -> T, F: Send, T: Send
+    pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
+        F: FnOnce() -> T, F: Send + 'a, T: Send + 'a
     {
         let Builder { name, stack_size } = self;
 
@@ -482,7 +484,21 @@
         };
 
         Ok(JoinHandle(JoinInner {
-            native: Some(imp::Thread::new(stack_size, Box::new(main))?),
+            // `imp::Thread::new` takes a closure with a `'static` lifetime, since it's passed
+            // through FFI or otherwise used with low-level threading primitives that have no
+            // notion of or way to enforce lifetimes.
+            //
+            // As mentioned in the `Safety` section of this function's documentation, the caller of
+            // this function needs to guarantee that the passed-in lifetime is sufficiently long
+            // for the lifetime of the thread.
+            //
+            // Similarly, the `sys` implementation must guarantee that no references to the closure
+            // exist after the thread has terminated, which is signaled by `Thread::join`
+            // returning.
+            native: Some(imp::Thread::new(
+                stack_size,
+                mem::transmute::<Box<dyn FnBox() + 'a>, Box<dyn FnBox() + 'static>>(Box::new(main))
+            )?),
             thread: my_thread,
             packet: Packet(my_packet),
         }))
@@ -676,7 +692,7 @@
 /// already poison themselves when a thread panics while holding the lock.
 ///
 /// This can also be used in multithreaded applications, in order to send a
-/// message to other threads warning that a thread has panicked (e.g. for
+/// message to other threads warning that a thread has panicked (e.g., for
 /// monitoring purposes).
 ///
 /// # Examples
@@ -806,9 +822,14 @@
 /// In other words, each [`Thread`] acts a bit like a spinlock that can be
 /// locked and unlocked using `park` and `unpark`.
 ///
+/// Notice that being unblocked does not imply any synchronization with someone
+/// that unparked this thread, it could also be spurious.
+/// For example, it would be a valid, but inefficient, implementation to make both [`park`] and
+/// [`unpark`] return immediately without doing anything.
+///
 /// The API is typically used by acquiring a handle to the current thread,
 /// placing that handle in a shared data structure so that other threads can
-/// find it, and then `park`ing. When some desired condition is met, another
+/// find it, and then `park`ing in a loop. When some desired condition is met, another
 /// thread calls [`unpark`] on the handle.
 ///
 /// The motivation for this design is twofold:
@@ -823,21 +844,33 @@
 ///
 /// ```
 /// use std::thread;
+/// use std::sync::{Arc, atomic::{Ordering, AtomicBool}};
 /// use std::time::Duration;
 ///
-/// let parked_thread = thread::Builder::new()
-///     .spawn(|| {
+/// let flag = Arc::new(AtomicBool::new(false));
+/// let flag2 = Arc::clone(&flag);
+///
+/// let parked_thread = thread::spawn(move || {
+///     // We want to wait until the flag is set.  We *could* just spin, but using
+///     // park/unpark is more efficient.
+///     while !flag2.load(Ordering::Acquire) {
 ///         println!("Parking thread");
 ///         thread::park();
+///         // We *could* get here spuriously, i.e., way before the 10ms below are over!
+///         // But that is no problem, we are in a loop until the flag is set anyway.
 ///         println!("Thread unparked");
-///     })
-///     .unwrap();
+///     }
+///     println!("Flag received");
+/// });
 ///
 /// // Let some time pass for the thread to be spawned.
 /// thread::sleep(Duration::from_millis(10));
 ///
+/// // Set the flag, and let the thread wake up.
 /// // There is no race condition here, if `unpark`
 /// // happens first, `park` will return immediately.
+/// // Hence there is no risk of a deadlock.
+/// flag.store(true, Ordering::Release);
 /// println!("Unpark the thread");
 /// parked_thread.thread().unpark();
 ///
@@ -1062,7 +1095,7 @@
 /// Threads are represented via the `Thread` type, which you can get in one of
 /// two ways:
 ///
-/// * By spawning a new thread, e.g. using the [`thread::spawn`][`spawn`]
+/// * By spawning a new thread, e.g., using the [`thread::spawn`][`spawn`]
 ///   function, and calling [`thread`][`JoinHandle::thread`] on the
 ///   [`JoinHandle`].
 /// * By requesting the current thread, using the [`thread::current`] function.
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 5d0d501..63cede7 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -208,6 +208,22 @@
     pub fn elapsed(&self) -> Duration {
         Instant::now() - *self
     }
+
+    /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
+    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
+    /// otherwise.
+    #[unstable(feature = "time_checked_add", issue = "55940")]
+    pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
+        self.0.checked_add_duration(&duration).map(|t| Instant(t))
+    }
+
+    /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
+    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
+    /// otherwise.
+    #[unstable(feature = "time_checked_add", issue = "55940")]
+    pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
+        self.0.checked_sub_duration(&duration).map(|t| Instant(t))
+    }
 }
 
 #[stable(feature = "time2", since = "1.8.0")]
@@ -215,7 +231,8 @@
     type Output = Instant;
 
     fn add(self, other: Duration) -> Instant {
-        Instant(self.0.add_duration(&other))
+        self.checked_add(other)
+            .expect("overflow when adding duration to instant")
     }
 }
 
@@ -231,7 +248,8 @@
     type Output = Instant;
 
     fn sub(self, other: Duration) -> Instant {
-        Instant(self.0.sub_duration(&other))
+        self.checked_sub(other)
+            .expect("overflow when subtracting duration from instant")
     }
 }
 
@@ -330,7 +348,7 @@
     /// Returns the amount of time elapsed since this system time was created.
     ///
     /// This function may fail as the underlying system clock is susceptible to
-    /// drift and updates (e.g. the system clock could go backwards), so this
+    /// drift and updates (e.g., the system clock could go backwards), so this
     /// function may not always succeed. If successful, [`Ok`]`(`[`Duration`]`)` is
     /// returned where the duration represents the amount of time elapsed from
     /// this time measurement to the current time.
@@ -365,6 +383,14 @@
     pub fn checked_add(&self, duration: Duration) -> Option<SystemTime> {
         self.0.checked_add_duration(&duration).map(|t| SystemTime(t))
     }
+
+    /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
+    /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None`
+    /// otherwise.
+    #[unstable(feature = "time_checked_add", issue = "55940")]
+    pub fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
+        self.0.checked_sub_duration(&duration).map(|t| SystemTime(t))
+    }
 }
 
 #[stable(feature = "time2", since = "1.8.0")]
@@ -372,7 +398,8 @@
     type Output = SystemTime;
 
     fn add(self, dur: Duration) -> SystemTime {
-        SystemTime(self.0.add_duration(&dur))
+        self.checked_add(dur)
+            .expect("overflow when adding duration to instant")
     }
 }
 
@@ -388,7 +415,8 @@
     type Output = SystemTime;
 
     fn sub(self, dur: Duration) -> SystemTime {
-        SystemTime(self.0.sub_duration(&dur))
+        self.checked_sub(dur)
+            .expect("overflow when subtracting duration from instant")
     }
 }
 
@@ -521,6 +549,20 @@
 
         let second = Duration::new(1, 0);
         assert_almost_eq!(a - second + second, a);
+        assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a);
+
+        // checked_add_duration will not panic on overflow
+        let mut maybe_t = Some(Instant::now());
+        let max_duration = Duration::from_secs(u64::max_value());
+        // in case `Instant` can store `>= now + max_duration`.
+        for _ in 0..2 {
+            maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration));
+        }
+        assert_eq!(maybe_t, None);
+
+        // checked_add_duration calculates the right time and will work for another year
+        let year = Duration::from_secs(60 * 60 * 24 * 365);
+        assert_eq!(a + year, a.checked_add(year).unwrap());
     }
 
     #[test]
@@ -557,6 +599,7 @@
                            .duration(), second);
 
         assert_almost_eq!(a - second + second, a);
+        assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a);
 
         // A difference of 80 and 800 years cannot fit inside a 32-bit time_t
         if !(cfg!(unix) && ::mem::size_of::<::libc::time_t>() <= 4) {
diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml
index 519cc7a..fba2623 100644
--- a/src/libsyntax/Cargo.toml
+++ b/src/libsyntax/Cargo.toml
@@ -17,4 +17,4 @@
 rustc_errors = { path = "../librustc_errors" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 227017a..0792b2d 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -68,12 +68,12 @@
 /// It's represented as a sequence of identifiers,
 /// along with a bunch of supporting information.
 ///
-/// E.g. `std::cmp::PartialEq`
+/// E.g., `std::cmp::PartialEq`.
 #[derive(Clone, RustcEncodable, RustcDecodable)]
 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>,
 }
 
@@ -96,8 +96,8 @@
 }
 
 impl Path {
-    // convert a span and an identifier to the corresponding
-    // 1-segment path
+    // Convert a span and an identifier to the corresponding
+    // one-segment path.
     pub fn from_ident(ident: Ident) -> Path {
         Path {
             segments: vec![PathSegment::from_ident(ident)],
@@ -105,25 +105,14 @@
         }
     }
 
-    // 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()
     }
 }
 
 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
 ///
-/// E.g. `std`, `String` or `Box<T>`
+/// E.g., `std`, `String` or `Box<T>`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct PathSegment {
     /// The identifier portion of this path segment.
@@ -144,14 +133,14 @@
     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))
     }
 }
 
 /// Arguments of a path segment.
 ///
-/// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
+/// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum GenericArgs {
     /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
@@ -293,7 +282,7 @@
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum GenericParamKind {
-    /// A lifetime definition, e.g. `'a: 'b+'c+'d`.
+    /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
     Lifetime,
     Type {
         default: Option<P<Ty>>,
@@ -345,11 +334,11 @@
 /// A single predicate in a `where` clause
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum WherePredicate {
-    /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
+    /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate),
-    /// A lifetime predicate, e.g. `'a: 'b+'c`
+    /// A lifetime predicate (e.g., `'a: 'b + 'c`).
     RegionPredicate(WhereRegionPredicate),
-    /// An equality predicate (unsupported)
+    /// An equality predicate (unsupported).
     EqPredicate(WhereEqPredicate),
 }
 
@@ -365,7 +354,7 @@
 
 /// A type bound.
 ///
-/// E.g. `for<'c> Foo: Send+Clone+'c`
+/// E.g., `for<'c> Foo: Send + Clone + 'c`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct WhereBoundPredicate {
     pub span: Span,
@@ -379,7 +368,7 @@
 
 /// A lifetime predicate.
 ///
-/// E.g. `'a: 'b+'c`
+/// E.g., `'a: 'b + 'c`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct WhereRegionPredicate {
     pub span: Span,
@@ -389,7 +378,7 @@
 
 /// An equality predicate (unsupported).
 ///
-/// E.g. `T=int`
+/// E.g., `T = int`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct WhereEqPredicate {
     pub id: NodeId,
@@ -398,8 +387,8 @@
     pub rhs_ty: P<Ty>,
 }
 
-/// The set of MetaItems that define the compilation environment of the crate,
-/// used to drive conditional compilation
+/// The set of `MetaItem`s that define the compilation environment of the crate,
+/// used to drive conditional compilation.
 pub type CrateConfig = FxHashSet<(Name, Option<Symbol>)>;
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -414,20 +403,20 @@
 
 /// Possible values inside of compile-time attribute lists.
 ///
-/// E.g. the '..' in `#[name(..)]`.
+/// E.g., the '..' in `#[name(..)]`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum NestedMetaItemKind {
     /// A full MetaItem, for recursive meta items.
     MetaItem(MetaItem),
     /// A literal.
     ///
-    /// E.g. "foo", 64, true
+    /// E.g., `"foo"`, `64`, `true`.
     Literal(Lit),
 }
 
 /// A spanned compile-time attribute item.
 ///
-/// E.g. `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`
+/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct MetaItem {
     pub ident: Path,
@@ -437,26 +426,26 @@
 
 /// A compile-time attribute item.
 ///
-/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
+/// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum MetaItemKind {
     /// Word meta item.
     ///
-    /// E.g. `test` as in `#[test]`
+    /// E.g., `test` as in `#[test]`.
     Word,
     /// List meta item.
     ///
-    /// E.g. `derive(..)` as in `#[derive(..)]`
+    /// E.g., `derive(..)` as in `#[derive(..)]`.
     List(Vec<NestedMetaItem>),
     /// Name value meta item.
     ///
-    /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
+    /// E.g., `feature = "foo"` as in `#[feature = "foo"]`.
     NameValue(Lit),
 }
 
 /// A Block (`{ .. }`).
 ///
-/// E.g. `{ .. }` as in `fn foo() { .. }`
+/// E.g., `{ .. }` as in `fn foo() { .. }`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Block {
     /// Statements in a block
@@ -579,7 +568,7 @@
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum PatKind {
-    /// Represents a wildcard pattern (`_`)
+    /// Represents a wildcard pattern (`_`).
     Wild,
 
     /// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
@@ -588,13 +577,13 @@
     /// during name resolution.
     Ident(BindingMode, Ident, Option<P<Pat>>),
 
-    /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
+    /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
     /// The `bool` is `true` in the presence of a `..`.
     Struct(Path, Vec<Spanned<FieldPat>>, bool),
 
-    /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
+    /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
-    /// 0 <= position <= subpats.len()
+    /// `0 <= position <= subpats.len()`.
     TupleStruct(Path, Vec<P<Pat>>, Option<usize>),
 
     /// A possibly qualified path pattern.
@@ -603,24 +592,24 @@
     /// only legally refer to associated constants.
     Path(Option<QSelf>, Path),
 
-    /// A tuple pattern `(a, b)`.
+    /// A tuple pattern (`(a, b)`).
     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
-    /// 0 <= position <= subpats.len()
+    /// `0 <= position <= subpats.len()`.
     Tuple(Vec<P<Pat>>, Option<usize>),
-    /// A `box` pattern
+    /// A `box` pattern.
     Box(P<Pat>),
-    /// A reference pattern, e.g. `&mut (a, b)`
+    /// A reference pattern (e.g., `&mut (a, b)`).
     Ref(P<Pat>, Mutability),
-    /// A literal
+    /// A literal.
     Lit(P<Expr>),
-    /// A range pattern, e.g. `1...2`, `1..=2` or `1..2`
+    /// A range pattern (e.g., `1...2`, `1..=2` or `1..2`).
     Range(P<Expr>, P<Expr>, Spanned<RangeEnd>),
     /// `[a, b, ..i, y, z]` is represented as:
     ///     `PatKind::Slice(box [a, b], Some(i), box [y, z])`
     Slice(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
-    /// Parentheses in patterns used for grouping, i.e. `(PAT)`.
+    /// Parentheses in patterns used for grouping (i.e., `(PAT)`).
     Paren(P<Pat>),
-    /// A macro pattern; pre-expansion
+    /// A macro pattern; pre-expansion.
     Mac(Mac),
 }
 
@@ -818,23 +807,23 @@
 
 #[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)]
 pub enum MacStmtStyle {
-    /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
-    /// `foo!(...);`, `foo![...];`
+    /// The macro statement had a trailing semicolon (e.g., `foo! { ... };`
+    /// `foo!(...);`, `foo![...];`).
     Semicolon,
-    /// The macro statement had braces; e.g. foo! { ... }
+    /// The macro statement had braces (e.g., `foo! { ... }`).
     Braces,
-    /// The macro statement had parentheses or brackets and no semicolon; e.g.
-    /// `foo!(...)`. All of these will end up being converted into macro
+    /// The macro statement had parentheses or brackets and no semicolon (e.g.,
+    /// `foo!(...)`). All of these will end up being converted into macro
     /// expressions.
     NoBraces,
 }
 
-/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
+/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Local {
     pub pat: P<Pat>,
     pub ty: Option<P<Ty>>,
-    /// Initializer expression to set the value, if any
+    /// Initializer expression to set the value, if any.
     pub init: Option<P<Expr>>,
     pub id: NodeId,
     pub span: Span,
@@ -843,7 +832,7 @@
 
 /// An arm of a 'match'.
 ///
-/// E.g. `0..=10 => { println!("match!") }` as in
+/// E.g., `0..=10 => { println!("match!") }` as in
 ///
 /// ```
 /// match 123 {
@@ -889,8 +878,8 @@
 
 /// A constant (expression) that's not an item or associated item,
 /// but needs its own `DefId` for type-checking, const-eval, etc.
-/// These are usually found nested inside types (e.g. array lengths)
-/// or expressions (e.g. repeat counts), and also used to define
+/// These are usually found nested inside types (e.g., array lengths)
+/// or expressions (e.g., repeat counts), and also used to define
 /// explicit discriminant values for enum variants.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct AnonConst {
@@ -912,7 +901,7 @@
 static_assert!(MEM_SIZE_OF_EXPR: std::mem::size_of::<Expr>() == 88);
 
 impl Expr {
-    /// Whether this expression would be valid somewhere that expects a value, for example, an `if`
+    /// Whether this expression would be valid somewhere that expects a value; for example, an `if`
     /// condition.
     pub fn returns(&self) -> bool {
         if let ExprKind::Block(ref block, _) = self.node {
@@ -1060,24 +1049,24 @@
     ///
     /// The `PathSegment` represents the method name and its generic arguments
     /// (within the angle brackets).
-    /// The first element of the vector of `Expr`s is the expression that evaluates
+    /// The first element of the vector of an `Expr` is the expression that evaluates
     /// to the object on which the method is being called on (the receiver),
     /// and the remaining elements are the rest of the arguments.
     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
     /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
     MethodCall(PathSegment, Vec<P<Expr>>),
-    /// A tuple (`(a, b, c ,d)`)
+    /// A tuple (e.g., `(a, b, c, d)`).
     Tup(Vec<P<Expr>>),
-    /// A binary operation (For example: `a + b`, `a * b`)
+    /// A binary operation (e.g., `a + b`, `a * b`).
     Binary(BinOp, P<Expr>, P<Expr>),
-    /// A unary operation (For example: `!x`, `*x`)
+    /// A unary operation (e.g., `!x`, `*x`).
     Unary(UnOp, P<Expr>),
-    /// A literal (For example: `1`, `"foo"`)
+    /// A literal (e.g., `1`, `"foo"`).
     Lit(Lit),
-    /// A cast (`foo as f64`)
+    /// A cast (e.g., `foo as f64`).
     Cast(P<Expr>, P<Ty>),
     Type(P<Expr>, P<Ty>),
-    /// An `if` block, with an optional else block
+    /// An `if` block, with an optional `else` block.
     ///
     /// `if expr { block } else { expr }`
     If(P<Expr>, P<Block>, Option<P<Expr>>),
@@ -1091,31 +1080,31 @@
     ///
     /// `'label: while expr { block }`
     While(P<Expr>, P<Block>, Option<Label>),
-    /// A while-let loop, with an optional label
+    /// A `while let` loop, with an optional label.
     ///
     /// `'label: while let pat = expr { block }`
     ///
     /// This is desugared to a combination of `loop` and `match` expressions.
     WhileLet(Vec<P<Pat>>, P<Expr>, P<Block>, Option<Label>),
-    /// A for loop, with an optional label
+    /// A `for` loop, with an optional label.
     ///
     /// `'label: for pat in expr { block }`
     ///
     /// This is desugared to a combination of `loop` and `match` expressions.
     ForLoop(P<Pat>, P<Expr>, P<Block>, Option<Label>),
-    /// Conditionless loop (can be exited with break, continue, or return)
+    /// Conditionless loop (can be exited with `break`, `continue`, or `return`).
     ///
     /// `'label: loop { block }`
     Loop(P<Block>, Option<Label>),
     /// A `match` block.
     Match(P<Expr>, Vec<Arm>),
-    /// A closure (for example, `move |a, b, c| a + b + c`)
+    /// A closure (e.g., `move |a, b, c| a + b + c`).
     ///
-    /// The final span is the span of the argument block `|...|`
+    /// The final span is the span of the argument block `|...|`.
     Closure(CaptureBy, IsAsync, Movability, P<FnDecl>, P<Expr>, Span),
-    /// A block (`'label: { ... }`)
+    /// A block (`'label: { ... }`).
     Block(P<Block>, Option<Label>),
-    /// An async block (`async move { ... }`)
+    /// An async block (`async move { ... }`).
     ///
     /// The `NodeId` is the `NodeId` for the closure that results from
     /// desugaring an async block, just like the NodeId field in the
@@ -1124,70 +1113,69 @@
     /// created during lowering cannot be made the parent of any other
     /// preexisting defs.
     Async(CaptureBy, NodeId, P<Block>),
-    /// A try block (`try { ... }`)
+    /// A try block (`try { ... }`).
     TryBlock(P<Block>),
 
-    /// An assignment (`a = foo()`)
+    /// An assignment (`a = foo()`).
     Assign(P<Expr>, P<Expr>),
-    /// An assignment with an operator
+    /// An assignment with an operator.
     ///
-    /// For example, `a += 1`.
+    /// E.g., `a += 1`.
     AssignOp(BinOp, P<Expr>, P<Expr>),
-    /// Access of a named (`obj.foo`) or unnamed (`obj.0`) struct field
+    /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
     Field(P<Expr>, Ident),
-    /// An indexing operation (`foo[2]`)
+    /// An indexing operation (e.g., `foo[2]`).
     Index(P<Expr>, P<Expr>),
-    /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
+    /// A range (e.g., `1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`).
     Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
 
     /// Variable reference, possibly containing `::` and/or type
-    /// parameters, e.g. foo::bar::<baz>.
+    /// parameters (e.g., `foo::bar::<baz>`).
     ///
-    /// Optionally "qualified",
-    /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
+    /// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
     Path(Option<QSelf>, Path),
 
-    /// A referencing operation (`&a` or `&mut a`)
+    /// A referencing operation (`&a` or `&mut a`).
     AddrOf(Mutability, P<Expr>),
-    /// A `break`, with an optional label to break, and an optional expression
+    /// A `break`, with an optional label to break, and an optional expression.
     Break(Option<Label>, Option<P<Expr>>),
-    /// A `continue`, with an optional label
+    /// A `continue`, with an optional label.
     Continue(Option<Label>),
-    /// A `return`, with an optional value to be returned
+    /// A `return`, with an optional value to be returned.
     Ret(Option<P<Expr>>),
 
-    /// Output of the `asm!()` macro
+    /// Output of the `asm!()` macro.
     InlineAsm(P<InlineAsm>),
 
-    /// A macro invocation; pre-expansion
+    /// A macro invocation; pre-expansion.
     Mac(Mac),
 
     /// A struct literal expression.
     ///
-    /// For example, `Foo {x: 1, y: 2}`, or
-    /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
+    /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`,
+    /// where `base` is the `Option<Expr>`.
     Struct(Path, Vec<Field>, Option<P<Expr>>),
 
     /// An array literal constructed from one repeated element.
     ///
-    /// For example, `[1; 5]`. The expression is the element to be
+    /// E.g., `[1; 5]`. The expression is the element to be
     /// repeated; the constant is the number of times to repeat it.
     Repeat(P<Expr>, AnonConst),
 
-    /// No-op: used solely so we can pretty-print faithfully
+    /// No-op: used solely so we can pretty-print faithfully.
     Paren(P<Expr>),
 
-    /// `expr?`
+    /// A try expression (`expr?`).
     Try(P<Expr>),
 
-    /// A `yield`, with an optional value to be yielded
+    /// A `yield`, with an optional value to be yielded.
     Yield(Option<P<Expr>>),
 }
 
-/// The explicit Self type in a "qualified path". The actual
+/// The explicit `Self` type in a "qualified path". The actual
 /// path, including the trait and the associated item, is stored
 /// separately. `position` represents the index of the associated
-/// item qualified with this Self type.
+/// item qualified with this `Self` type.
 ///
 /// ```ignore (only-for-syntax-highlight)
 /// <Vec<T> as a::b::Trait>::AssociatedItem
@@ -1209,14 +1197,14 @@
     pub position: usize,
 }
 
-/// A capture clause
+/// A capture clause.
 #[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)]
 pub enum CaptureBy {
     Value,
     Ref,
 }
 
-/// The movability of a generator / closure literal
+/// The movability of a generator / closure literal.
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub enum Movability {
     Static,
@@ -1225,12 +1213,12 @@
 
 pub type Mac = Spanned<Mac_>;
 
-/// Represents a macro invocation. The Path indicates which macro
+/// Represents a macro invocation. The `Path` indicates which macro
 /// is being invoked, and the vector of token-trees contains the source
 /// of the macro invocation.
 ///
-/// NB: the additional ident for a macro_rules-style macro is actually
-/// stored in the enclosing item. Oog.
+/// N.B., the additional ident for a `macro_rules`-style macro is actually
+/// stored in the enclosing item.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Mac_ {
     pub path: Path,
@@ -1247,7 +1235,7 @@
 
 impl Mac_ {
     pub fn stream(&self) -> TokenStream {
-        self.tts.clone().into()
+        self.tts.stream()
     }
 }
 
@@ -1265,15 +1253,15 @@
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)]
 pub enum StrStyle {
-    /// A regular string, like `"foo"`
+    /// A regular string, like `"foo"`.
     Cooked,
-    /// A raw string, like `r##"foo"##`
+    /// A raw string, like `r##"foo"##`.
     ///
     /// The value is the number of `#` symbols used.
     Raw(u16),
 }
 
-/// A literal
+/// A literal.
 pub type Lit = Spanned<LitKind>;
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)]
@@ -1285,29 +1273,29 @@
 
 /// Literal kind.
 ///
-/// E.g. `"foo"`, `42`, `12.34` or `bool`
+/// E.g., `"foo"`, `42`, `12.34`, or `bool`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
 pub enum LitKind {
-    /// A string literal (`"foo"`)
+    /// A string literal (`"foo"`).
     Str(Symbol, StrStyle),
-    /// A byte string (`b"foo"`)
+    /// A byte string (`b"foo"`).
     ByteStr(Lrc<Vec<u8>>),
-    /// A byte char (`b'f'`)
+    /// A byte char (`b'f'`).
     Byte(u8),
-    /// A character literal (`'a'`)
+    /// A character literal (`'a'`).
     Char(char),
-    /// An integer literal (`1`)
+    /// An integer literal (`1`).
     Int(u128, LitIntType),
-    /// A float literal (`1f64` or `1E10f64`)
+    /// A float literal (`1f64` or `1E10f64`).
     Float(Symbol, FloatTy),
-    /// A float literal without a suffix (`1.0 or 1.0E10`)
+    /// A float literal without a suffix (`1.0 or 1.0E10`).
     FloatUnsuffixed(Symbol),
-    /// A boolean literal
+    /// A boolean literal.
     Bool(bool),
 }
 
 impl LitKind {
-    /// Returns true if this literal is a string and false otherwise.
+    /// Returns `true` if this literal is a string.
     pub fn is_str(&self) -> bool {
         match *self {
             LitKind::Str(..) => true,
@@ -1315,7 +1303,7 @@
         }
     }
 
-    /// Returns true if this literal is byte literal string false otherwise.
+    /// Returns `true` if this literal is byte literal string.
     pub fn is_bytestr(&self) -> bool {
         match self {
             LitKind::ByteStr(_) => true,
@@ -1323,7 +1311,7 @@
         }
     }
 
-    /// Returns true if this is a numeric literal.
+    /// Returns `true` if this is a numeric literal.
     pub fn is_numeric(&self) -> bool {
         match *self {
             LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => true,
@@ -1331,8 +1319,8 @@
         }
     }
 
-    /// Returns true if this literal has no suffix. Note: this will return true
-    /// for literals with prefixes such as raw strings and byte strings.
+    /// Returns `true` if this literal has no suffix.
+    /// Note: this will return true for literals with prefixes such as raw strings and byte strings.
     pub fn is_unsuffixed(&self) -> bool {
         match *self {
             // unsuffixed variants
@@ -1350,14 +1338,14 @@
         }
     }
 
-    /// Returns true if this literal has a suffix.
+    /// Returns `true` if this literal has a suffix.
     pub fn is_suffixed(&self) -> bool {
         !self.is_unsuffixed()
     }
 }
 
-// NB: If you change this, you'll probably want to change the corresponding
-// type structure in middle/ty.rs as well.
+// N.B., If you change this, you'll probably want to change the corresponding
+// type structure in `middle/ty.rs` as well.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct MutTy {
     pub ty: P<Ty>,
@@ -1384,7 +1372,7 @@
     pub generics: Generics,
     pub node: TraitItemKind,
     pub span: Span,
-    /// See `Item::tokens` for what this is
+    /// See `Item::tokens` for what this is.
     pub tokens: Option<TokenStream>,
 }
 
@@ -1406,7 +1394,7 @@
     pub generics: Generics,
     pub node: ImplItemKind,
     pub span: Span,
-    /// See `Item::tokens` for what this is
+    /// See `Item::tokens` for what this is.
     pub tokens: Option<TokenStream>,
 }
 
@@ -1454,8 +1442,8 @@
     }
 
     pub fn val_to_string(&self, val: i128) -> String {
-        // cast to a u128 so we can correctly print INT128_MIN. All integral types
-        // are parsed as u128, so we wouldn't want to print an extra negative
+        // Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types
+        // are parsed as `u128`, so we wouldn't want to print an extra negative
         // sign.
         format!("{}{}", val as u128, self.ty_to_string())
     }
@@ -1522,7 +1510,7 @@
     }
 }
 
-// Bind a type to an associated type: `A=Foo`.
+// Bind a type to an associated type: `A = Foo`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct TypeBinding {
     pub id: NodeId,
@@ -1552,27 +1540,27 @@
     pub decl: P<FnDecl>,
 }
 
-/// The different kinds of types recognized by the compiler
+/// The different kinds of types recognized by the compiler.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum TyKind {
-    /// A variable-length slice (`[T]`)
+    /// A variable-length slice (`[T]`).
     Slice(P<Ty>),
-    /// A fixed length array (`[T; n]`)
+    /// A fixed length array (`[T; n]`).
     Array(P<Ty>, AnonConst),
-    /// A raw pointer (`*const T` or `*mut T`)
+    /// A raw pointer (`*const T` or `*mut T`).
     Ptr(MutTy),
-    /// A reference (`&'a T` or `&'a mut T`)
+    /// A reference (`&'a T` or `&'a mut T`).
     Rptr(Option<Lifetime>, MutTy),
-    /// A bare function (e.g. `fn(usize) -> bool`)
+    /// A bare function (e.g., `fn(usize) -> bool`).
     BareFn(P<BareFnTy>),
-    /// The never type (`!`)
+    /// The never type (`!`).
     Never,
-    /// A tuple (`(A, B, C, D,...)`)
+    /// A tuple (`(A, B, C, D,...)`).
     Tup(Vec<P<Ty>>),
     /// A path (`module::module::...::Type`), optionally
-    /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
+    /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
     ///
-    /// Type parameters are stored in the Path itself
+    /// Type parameters are stored in the `Path` itself.
     Path(Option<QSelf>, Path),
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
@@ -1582,18 +1570,18 @@
     ///
     /// The `NodeId` exists to prevent lowering from having to
     /// generate `NodeId`s on the fly, which would complicate
-    /// the generation of `existential type` items significantly
+    /// the generation of `existential type` items significantly.
     ImplTrait(NodeId, GenericBounds),
-    /// No-op; kept solely so that we can pretty-print faithfully
+    /// No-op; kept solely so that we can pretty-print faithfully.
     Paren(P<Ty>),
-    /// Unused for now
+    /// Unused for now.
     Typeof(AnonConst),
-    /// TyKind::Infer means the type should be inferred instead of it having been
+    /// This means the type should be inferred instead of it having been
     /// specified. This can appear anywhere in a type.
     Infer,
     /// Inferred type of a `self` or `&self` argument in a method.
     ImplicitSelf,
-    // A macro in the type position.
+    /// A macro in the type position.
     Mac(Mac),
     /// Placeholder for a kind that has failed to be defined.
     Err,
@@ -1626,7 +1614,7 @@
 
 /// Inline assembly dialect.
 ///
-/// E.g. `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`
+/// E.g., `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub enum AsmDialect {
     Att,
@@ -1635,7 +1623,7 @@
 
 /// Inline assembly.
 ///
-/// E.g. `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`
+/// E.g., `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct InlineAsmOutput {
     pub constraint: Symbol,
@@ -1646,7 +1634,7 @@
 
 /// Inline assembly.
 ///
-/// E.g. `asm!("NOP");`
+/// E.g., `asm!("NOP");`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct InlineAsm {
     pub asm: Symbol,
@@ -1662,7 +1650,7 @@
 
 /// An argument in a function header.
 ///
-/// E.g. `bar: usize` as in `fn foo(bar: usize)`
+/// E.g., `bar: usize` as in `fn foo(bar: usize)`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Arg {
     pub ty: P<Ty>,
@@ -1672,7 +1660,7 @@
 
 /// Alternative representation for `Arg`s describing `self` parameter of methods.
 ///
-/// E.g. `&mut self` as in `fn foo(&mut self)`
+/// E.g., `&mut self` as in `fn foo(&mut self)`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum SelfKind {
     /// `self`, `mut self`
@@ -1688,7 +1676,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 +1694,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
         }
@@ -1751,7 +1739,7 @@
 
 /// Header (not the body) of a function declaration.
 ///
-/// E.g. `fn foo(bar: baz)`
+/// E.g., `fn foo(bar: baz)`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct FnDecl {
     pub inputs: Vec<Arg>,
@@ -1798,7 +1786,8 @@
             false
         }
     }
-    /// In case this is an `Async` return the `NodeId` for the generated impl Trait item
+
+    /// In ths case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
     pub fn opt_return_id(self) -> Option<NodeId> {
         match self {
             IsAsync::Async {
@@ -1855,11 +1844,10 @@
 pub enum FunctionRetTy {
     /// Return type is not specified.
     ///
-    /// Functions default to `()` and
-    /// closures default to inference. Span points to where return
-    /// type would be inserted.
+    /// Functions default to `()` and closures default to inference.
+    /// Span points to where return type would be inserted.
     Default(Span),
-    /// Everything else
+    /// Everything else.
     Ty(P<Ty>),
 }
 
@@ -1874,7 +1862,7 @@
 
 /// Module declaration.
 ///
-/// E.g. `mod foo;` or `mod foo { .. }`
+/// E.g., `mod foo;` or `mod foo { .. }`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Mod {
     /// A span from the first token past `{` to the last token until `}`.
@@ -1882,22 +1870,22 @@
     /// to the last token in the external file.
     pub inner: Span,
     pub items: Vec<P<Item>>,
-    /// For `mod foo;` inline is false, for `mod foo { .. }` it is true.
+    /// `true` for `mod foo { .. }`; `false` for `mod foo;`.
     pub inline: bool,
 }
 
 /// Foreign module declaration.
 ///
-/// E.g. `extern { .. }` or `extern C { .. }`
+/// E.g., `extern { .. }` or `extern C { .. }`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct ForeignMod {
     pub abi: Abi,
     pub items: Vec<ForeignItem>,
 }
 
-/// Global inline assembly
+/// Global inline assembly.
 ///
-/// aka module-level assembly or file-scoped assembly
+/// Also known as "module-level assembly" or "file-scoped assembly".
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub struct GlobalAsm {
     pub asm: Symbol,
@@ -1914,7 +1902,7 @@
     pub ident: Ident,
     pub attrs: Vec<Attribute>,
     pub data: VariantData,
-    /// Explicit discriminant, e.g. `Foo = 1`
+    /// Explicit discriminant, e.g., `Foo = 1`.
     pub disr_expr: Option<AnonConst>,
 }
 
@@ -1959,7 +1947,7 @@
     }
 }
 
-/// Distinguishes between Attributes that decorate items and Attributes that
+/// Distinguishes between `Attribute`s that decorate items and Attributes that
 /// are contained as statements within items. These two cases need to be
 /// distinguished for pretty-printing.
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
@@ -1982,8 +1970,8 @@
     }
 }
 
-/// Meta-data associated with an item
-/// Doc-comments are promoted to attributes that have is_sugared_doc = true
+/// Metadata associated with an item.
+/// Doc-comments are promoted to attributes that have `is_sugared_doc = true`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Attribute {
     pub id: AttrId,
@@ -1994,12 +1982,12 @@
     pub span: Span,
 }
 
-/// TraitRef's appear in impls.
+/// `TraitRef`s appear in impls.
 ///
-/// resolve maps each TraitRef's ref_id to its defining trait; that's all
-/// that the ref_id is for. The impl_id maps to the "self type" of this impl.
-/// If this impl is an ItemKind::Impl, the impl_id is redundant (it could be the
-/// same as the impl's node id).
+/// Resolve maps each `TraitRef`'s `ref_id` to its defining trait; that's all
+/// that the `ref_id` is for. The `impl_id` maps to the "self type" of this impl.
+/// If this impl is an `ItemKind::Impl`, the `impl_id` is redundant (it could be the
+/// same as the impl's node-id).
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct TraitRef {
     pub path: Path,
@@ -2032,10 +2020,10 @@
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum CrateSugar {
-    /// Source is `pub(crate)`
+    /// Source is `pub(crate)`.
     PubCrate,
 
-    /// Source is (just) `crate`
+    /// Source is (just) `crate`.
     JustCrate,
 }
 
@@ -2061,7 +2049,7 @@
 
 /// Field of a struct.
 ///
-/// E.g. `bar: usize` as in `struct Foo { bar: usize }`
+/// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct StructField {
     pub span: Span,
@@ -2087,15 +2075,15 @@
 pub enum VariantData {
     /// Struct variant.
     ///
-    /// E.g. `Bar { .. }` as in `enum Foo { Bar { .. } }`
+    /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
     Struct(Vec<StructField>, NodeId),
     /// Tuple variant.
     ///
-    /// E.g. `Bar(..)` as in `enum Foo { Bar(..) }`
+    /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
     Tuple(Vec<StructField>, NodeId),
     /// Unit variant.
     ///
-    /// E.g. `Bar = ..` as in `enum Foo { Bar = .. }`
+    /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
     Unit(NodeId),
 }
 
@@ -2134,9 +2122,9 @@
     }
 }
 
-/// An item
+/// An item.
 ///
-/// The name might be a dummy name in case of anonymous items
+/// The name might be a dummy name in case of anonymous items.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Item {
     pub ident: Ident,
@@ -2156,10 +2144,10 @@
     pub tokens: Option<TokenStream>,
 }
 
-/// A function header
+/// A function header.
 ///
-/// All the information between the visibility & the name of the function is
-/// included in this struct (e.g. `async unsafe fn` or `const extern "C" fn`)
+/// All the information between the visibility and the name of the function is
+/// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
 pub struct FnHeader {
     pub unsafety: Unsafety,
@@ -2183,65 +2171,65 @@
 pub enum ItemKind {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
     ///
-    /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
+    /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
     ExternCrate(Option<Name>),
     /// A use declaration (`use` or `pub use`) item.
     ///
-    /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
+    /// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
     Use(P<UseTree>),
     /// A static item (`static` or `pub static`).
     ///
-    /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
+    /// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
     Static(P<Ty>, Mutability, P<Expr>),
     /// A constant item (`const` or `pub const`).
     ///
-    /// E.g. `const FOO: i32 = 42;`
+    /// E.g., `const FOO: i32 = 42;`.
     Const(P<Ty>, P<Expr>),
     /// A function declaration (`fn` or `pub fn`).
     ///
-    /// E.g. `fn foo(bar: usize) -> usize { .. }`
+    /// E.g., `fn foo(bar: usize) -> usize { .. }`.
     Fn(P<FnDecl>, FnHeader, Generics, P<Block>),
     /// A module declaration (`mod` or `pub mod`).
     ///
-    /// E.g. `mod foo;` or `mod foo { .. }`
+    /// E.g., `mod foo;` or `mod foo { .. }`.
     Mod(Mod),
     /// An external module (`extern` or `pub extern`).
     ///
-    /// E.g. `extern {}` or `extern "C" {}`
+    /// E.g., `extern {}` or `extern "C" {}`.
     ForeignMod(ForeignMod),
-    /// Module-level inline assembly (from `global_asm!()`)
+    /// Module-level inline assembly (from `global_asm!()`).
     GlobalAsm(P<GlobalAsm>),
     /// A type alias (`type` or `pub type`).
     ///
-    /// E.g. `type Foo = Bar<u8>;`
+    /// E.g., `type Foo = Bar<u8>;`.
     Ty(P<Ty>, Generics),
     /// An existential type declaration (`existential type`).
     ///
-    /// E.g. `existential type Foo: Bar + Boo;`
+    /// E.g., `existential type Foo: Bar + Boo;`.
     Existential(GenericBounds, Generics),
     /// An enum definition (`enum` or `pub enum`).
     ///
-    /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
+    /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
     Enum(EnumDef, Generics),
     /// A struct definition (`struct` or `pub struct`).
     ///
-    /// E.g. `struct Foo<A> { x: A }`
+    /// E.g., `struct Foo<A> { x: A }`.
     Struct(VariantData, Generics),
     /// A union definition (`union` or `pub union`).
     ///
-    /// E.g. `union Foo<A, B> { x: A, y: B }`
+    /// E.g., `union Foo<A, B> { x: A, y: B }`.
     Union(VariantData, Generics),
     /// A Trait declaration (`trait` or `pub trait`).
     ///
-    /// E.g. `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`
+    /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
     Trait(IsAuto, Unsafety, Generics, GenericBounds, Vec<TraitItem>),
     /// Trait alias
     ///
-    /// E.g. `trait Foo = Bar + Quux;`
+    /// E.g., `trait Foo = Bar + Quux;`.
     TraitAlias(Generics, GenericBounds),
     /// An implementation.
     ///
-    /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
+    /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
     Impl(
         Unsafety,
         ImplPolarity,
@@ -2253,7 +2241,7 @@
     ),
     /// A macro invocation.
     ///
-    /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
+    /// E.g., `macro_rules! foo { .. }` or `foo!(..)`.
     Mac(Mac),
 
     /// A macro definition.
@@ -2293,17 +2281,17 @@
     pub vis: Visibility,
 }
 
-/// An item within an `extern` block
+/// An item within an `extern` block.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum ForeignItemKind {
-    /// A foreign function
+    /// A foreign function.
     Fn(P<FnDecl>, Generics),
-    /// A foreign static item (`static ext: u8`), with optional mutability
-    /// (the boolean is true when mutable)
+    /// A foreign static item (`static ext: u8`), with optional mutability.
+    /// (The boolean is `true` for mutable items).
     Static(P<Ty>, bool),
-    /// A foreign type
+    /// A foreign type.
     Ty,
-    /// A macro invocation
+    /// A macro invocation.
     Macro(Mac),
 }
 
@@ -2323,7 +2311,7 @@
     use super::*;
     use serialize;
 
-    // are ASTs encodable?
+    // Are ASTs encodable?
     #[test]
     fn check_asts_encodable() {
         fn assert_encodable<T: serialize::Encodable>() {}
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 518b34e..7723c15 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -34,7 +34,7 @@
 use ptr::P;
 use symbol::Symbol;
 use ThinVec;
-use tokenstream::{TokenStream, TokenTree, Delimited, DelimSpan};
+use tokenstream::{TokenStream, TokenTree, DelimSpan};
 use GLOBALS;
 
 use std::iter;
@@ -96,7 +96,7 @@
         self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
     }
 
-    /// Returns the name of the meta item, e.g. `foo` in `#[foo]`,
+    /// Returns the name of the meta item, e.g., `foo` in `#[foo]`,
     /// `#[foo="bar"]` and `#[foo(bar)]`, if self is a MetaItem
     pub fn name(&self) -> Option<Name> {
         self.meta_item().and_then(|meta_item| Some(meta_item.name()))
@@ -180,7 +180,7 @@
     }
 
     /// Returns the **last** segment of the name of this attribute.
-    /// E.g. `foo` for `#[foo]`, `skip` for `#[rustfmt::skip]`.
+    /// e.g., `foo` for `#[foo]`, `skip` for `#[rustfmt::skip]`.
     pub fn name(&self) -> Name {
         name_from_path(&self.path)
     }
@@ -549,10 +549,11 @@
                     }
                     tokens.push(item.node.tokens());
                 }
-                TokenTree::Delimited(DelimSpan::from_single(span), Delimited {
-                    delim: token::Paren,
-                    tts: TokenStream::concat(tokens).into(),
-                }).into()
+                TokenTree::Delimited(
+                    DelimSpan::from_single(span),
+                    token::Paren,
+                    TokenStream::concat(tokens).into(),
+                ).into()
             }
         }
     }
@@ -570,9 +571,9 @@
                     None
                 };
             }
-            Some(TokenTree::Delimited(_, ref delimited)) if delimited.delim == token::Paren => {
+            Some(TokenTree::Delimited(_, delim, ref tts)) if delim == token::Paren => {
                 tokens.next();
-                delimited.stream()
+                tts.stream()
             }
             _ => return Some(MetaItemKind::Word),
         };
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index d8fb20d..4130717 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -328,7 +328,7 @@
         // Anything else is always required, and thus has to error out
         // in case of a cfg attr.
         //
-        // NB: This is intentionally not part of the fold_expr() function
+        // N.B., this is intentionally not part of the fold_expr() function
         //     in order for fold_opt_expr() to be able to avoid this check
         if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) {
             let msg = "removing an expression is not supported in this position";
@@ -421,7 +421,7 @@
     }
 
     fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
-        // Don't configure interpolated AST (c.f. #34171).
+        // Don't configure interpolated AST (cf. issue #34171).
         // Interpolated AST will get configured once the surrounding tokens are parsed.
         mac
     }
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 1229db9..3b88767 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -141,6 +141,7 @@
     ])
 }
 
+#[allow(deprecated)]
 pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
                                           span: Span,
                                           token_tree: &[TokenTree])
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index bb927b6..310cf27 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -670,7 +670,7 @@
     /// An attribute-like procedural macro that derives a builtin trait.
     BuiltinDerive(BuiltinDeriveFn),
 
-    /// A declarative macro, e.g. `macro m() {}`.
+    /// A declarative macro, e.g., `macro m() {}`.
     DeclMacro {
         expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
         def_info: Option<(ast::NodeId, Span)>,
@@ -733,16 +733,12 @@
     fn next_node_id(&mut self) -> ast::NodeId;
     fn get_module_scope(&mut self, id: ast::NodeId) -> Mark;
     fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item>;
-    fn is_whitelisted_legacy_custom_derive(&self, name: Name) -> bool;
 
     fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
                                             derives: &[Mark]);
     fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
 
     fn resolve_imports(&mut self);
-    // Resolves attribute and derive legacy macros from `#![plugin(..)]`.
-    fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<Attribute>, allow_derive: bool)
-                              -> Option<Attribute>;
 
     fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool)
                                 -> Result<Option<Lrc<SyntaxExtension>>, Determinacy>;
@@ -771,15 +767,12 @@
     fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID }
     fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }
     fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item> { item }
-    fn is_whitelisted_legacy_custom_derive(&self, _name: Name) -> bool { false }
 
     fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment,
                                             _derives: &[Mark]) {}
     fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {}
 
     fn resolve_imports(&mut self) {}
-    fn find_legacy_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>, _allow_derive: bool)
-                              -> Option<Attribute> { None }
     fn resolve_macro_invocation(&mut self, _invoc: &Invocation, _invoc_id: Mark, _force: bool)
                                 -> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
         Err(Determinacy::Determined)
@@ -915,7 +908,7 @@
     /// `span_err` should be strongly preferred where-ever possible:
     /// this should *only* be used when:
     ///
-    /// - continuing has a high risk of flow-on errors (e.g. errors in
+    /// - continuing has a high risk of flow-on errors (e.g., errors in
     ///   declaring a macro would cause all uses of that macro to
     ///   complain about "undefined macro"), or
     /// - there is literally nothing else that can be done (however,
@@ -1002,7 +995,7 @@
         expr
     });
 
-    // we want to be able to handle e.g. `concat!("foo", "bar")`
+    // we want to be able to handle e.g., `concat!("foo", "bar")`
     let expr = cx.expander().fold_expr(expr);
     Err(match expr.node {
         ast::ExprKind::Lit(ref l) => match l.node {
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 68a9629..03c7aa9 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{self, Block, Ident, NodeId, PatKind, Path};
+use ast::{self, Block, Ident, LitKind, NodeId, PatKind, Path};
 use ast::{MacStmtStyle, StmtKind, ItemKind};
 use attr::{self, HasAttrs};
 use source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan};
@@ -34,8 +34,8 @@
 use visit::{self, Visitor};
 
 use rustc_data_structures::fx::FxHashMap;
-use std::fs::File;
-use std::io::Read;
+use std::fs;
+use std::io::ErrorKind;
 use std::{iter, mem};
 use std::rc::Rc;
 use std::path::PathBuf;
@@ -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())
@@ -622,9 +622,9 @@
     fn extract_proc_macro_attr_input(&self, tokens: TokenStream, span: Span) -> TokenStream {
         let mut trees = tokens.trees();
         match trees.next() {
-            Some(TokenTree::Delimited(_, delim)) => {
+            Some(TokenTree::Delimited(_, _, tts)) => {
                 if trees.next().is_none() {
-                    return delim.tts.into()
+                    return tts.into()
                 }
             }
             Some(TokenTree::Token(..)) => {}
@@ -1134,12 +1134,6 @@
         let (mut attr, mut traits, mut after_derive) = (None, Vec::new(), false);
 
         item = item.map_attrs(|mut attrs| {
-            if let Some(legacy_attr_invoc) = self.cx.resolver.find_legacy_attr_invoc(&mut attrs,
-                                                                                     true) {
-                attr = Some(legacy_attr_invoc);
-                return attrs;
-            }
-
             attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
             traits = collect_derives(&mut self.cx, &mut attrs);
             attrs
@@ -1156,12 +1150,6 @@
         let (mut attr, mut after_derive) = (None, false);
 
         item = item.map_attrs(|mut attrs| {
-            if let Some(legacy_attr_invoc) = self.cx.resolver.find_legacy_attr_invoc(&mut attrs,
-                                                                                     false) {
-                attr = Some(legacy_attr_invoc);
-                return attrs;
-            }
-
             attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
             attrs
         });
@@ -1363,7 +1351,7 @@
                 module.mod_path.push(item.ident);
 
                 // Detect if this is an inline module (`mod m { ... }` as opposed to `mod m;`).
-                // In the non-inline case, `inner` is never the dummy span (c.f. `parse_item_mod`).
+                // In the non-inline case, `inner` is never the dummy span (cf. `parse_item_mod`).
                 // Thus, if `inner` is the dummy span, we know the module is inline.
                 let inline_module = item.span.contains(inner) || inner.is_dummy();
 
@@ -1519,20 +1507,8 @@
                         return noop_fold_attribute(at, self);
                     }
 
-                    let mut buf = vec![];
                     let filename = self.cx.root_path.join(file.to_string());
-
-                    match File::open(&filename).and_then(|mut f| f.read_to_end(&mut buf)) {
-                        Ok(..) => {}
-                        Err(e) => {
-                            self.cx.span_err(at.span,
-                                             &format!("couldn't read {}: {}",
-                                                      filename.display(),
-                                                      e));
-                        }
-                    }
-
-                    match String::from_utf8(buf) {
+                    match fs::read_to_string(&filename) {
                         Ok(src) => {
                             let src_interned = Symbol::intern(&src);
 
@@ -1542,25 +1518,82 @@
 
                             let include_info = vec![
                                 dummy_spanned(ast::NestedMetaItemKind::MetaItem(
-                                        attr::mk_name_value_item_str(Ident::from_str("file"),
-                                                                     dummy_spanned(file)))),
+                                    attr::mk_name_value_item_str(
+                                        Ident::from_str("file"),
+                                        dummy_spanned(file),
+                                    ),
+                                )),
                                 dummy_spanned(ast::NestedMetaItemKind::MetaItem(
-                                        attr::mk_name_value_item_str(Ident::from_str("contents"),
-                                                            dummy_spanned(src_interned)))),
+                                    attr::mk_name_value_item_str(
+                                        Ident::from_str("contents"),
+                                        dummy_spanned(src_interned),
+                                    ),
+                                )),
                             ];
 
                             let include_ident = Ident::from_str("include");
                             let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info);
                             items.push(dummy_spanned(ast::NestedMetaItemKind::MetaItem(item)));
                         }
-                        Err(_) => {
-                            self.cx.span_err(at.span,
-                                             &format!("{} wasn't a utf-8 file",
-                                                      filename.display()));
+                        Err(e) => {
+                            let lit = it
+                                .meta_item()
+                                .and_then(|item| item.name_value_literal())
+                                .unwrap();
+
+                            if e.kind() == ErrorKind::InvalidData {
+                                self.cx
+                                    .struct_span_err(
+                                        lit.span,
+                                        &format!("{} wasn't a utf-8 file", filename.display()),
+                                    )
+                                    .span_label(lit.span, "contains invalid utf-8")
+                                    .emit();
+                            } else {
+                                let mut err = self.cx.struct_span_err(
+                                    lit.span,
+                                    &format!("couldn't read {}: {}", filename.display(), e),
+                                );
+                                err.span_label(lit.span, "couldn't read file");
+
+                                if e.kind() == ErrorKind::NotFound {
+                                    err.help("external doc paths are relative to the crate root");
+                                }
+
+                                err.emit();
+                            }
                         }
                     }
                 } else {
-                    items.push(noop_fold_meta_list_item(it, self));
+                    let mut err = self.cx.struct_span_err(
+                        it.span,
+                        &format!("expected path to external documentation"),
+                    );
+
+                    // Check if the user erroneously used `doc(include(...))` syntax.
+                    let literal = it.meta_item_list().and_then(|list| {
+                        if list.len() == 1 {
+                            list[0].literal().map(|literal| &literal.node)
+                        } else {
+                            None
+                        }
+                    });
+
+                    let (path, applicability) = match &literal {
+                        Some(LitKind::Str(path, ..)) => {
+                            (path.to_string(), Applicability::MachineApplicable)
+                        }
+                        _ => (String::from("<path>"), Applicability::HasPlaceholders),
+                    };
+
+                    err.span_suggestion_with_applicability(
+                        it.span,
+                        "provide a file path with `=`",
+                        format!("include = \"{}\"", path),
+                        applicability,
+                    );
+
+                    err.emit();
                 }
             }
 
@@ -1623,7 +1656,6 @@
     }
 
     feature_tests! {
-        fn enable_quotes = quote,
         fn enable_asm = asm,
         fn enable_custom_test_frameworks = custom_test_frameworks,
         fn enable_global_asm = global_asm,
@@ -1631,7 +1663,6 @@
         fn enable_concat_idents = concat_idents,
         fn enable_trace_macros = trace_macros,
         fn enable_allow_internal_unstable = allow_internal_unstable,
-        fn enable_custom_derive = custom_derive,
         fn enable_format_args_nl = format_args_nl,
         fn macros_in_extern_enabled = macros_in_extern,
         fn proc_macro_hygiene = proc_macro_hygiene,
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 9181899..c3497a1 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -36,7 +36,7 @@
     use symbol::Symbol;
     use ThinVec;
 
-    use tokenstream::{self, DelimSpan, TokenTree, TokenStream};
+    use tokenstream::{DelimSpan, TokenTree, TokenStream};
 
     pub use parse::new_parser_from_tts;
     pub use syntax_pos::{BytePos, Span, DUMMY_SP, FileName};
@@ -246,9 +246,9 @@
             inner.push(self.tokens.clone());
 
             let delim_span = DelimSpan::from_single(self.span);
-            r.push(TokenTree::Delimited(delim_span, tokenstream::Delimited {
-                delim: token::Bracket, tts: TokenStream::concat(inner).into()
-            }));
+            r.push(TokenTree::Delimited(
+                delim_span, token::Bracket, TokenStream::concat(inner).into()
+            ));
             r
         }
     }
@@ -262,10 +262,9 @@
 
     impl ToTokens for () {
         fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
-            vec![TokenTree::Delimited(DelimSpan::dummy(), tokenstream::Delimited {
-                delim: token::Paren,
-                tts: TokenStream::empty().into(),
-            })]
+            vec![
+                TokenTree::Delimited(DelimSpan::dummy(), token::Paren, TokenStream::empty().into())
+            ]
         }
     }
 
@@ -382,8 +381,6 @@
 
 // Replaces `Token::OpenDelim .. Token::CloseDelim` with `TokenTree::Delimited(..)`.
 pub fn unflatten(tts: Vec<TokenTree>) -> Vec<TokenTree> {
-    use tokenstream::Delimited;
-
     let mut results = Vec::new();
     let mut result = Vec::new();
     let mut open_span = DUMMY_SP;
@@ -395,10 +392,11 @@
             }
             TokenTree::Token(span, token::CloseDelim(delim)) => {
                 let delim_span = DelimSpan::from_pair(open_span, span);
-                let tree = TokenTree::Delimited(delim_span, Delimited {
+                let tree = TokenTree::Delimited(
+                    delim_span,
                     delim,
-                    tts: result.into_iter().map(TokenStream::from).collect::<TokenStream>().into(),
-                });
+                    result.into_iter().map(TokenStream::from).collect::<TokenStream>().into(),
+                );
                 result = results.pop().unwrap();
                 result.push(tree);
             }
@@ -758,10 +756,10 @@
                                     vec![e_tok]);
             vec![cx.stmt_expr(e_push)]
         },
-        TokenTree::Delimited(span, ref delimed) => {
-            let mut stmts = statements_mk_tt(cx, &delimed.open_tt(span.open), false);
-            stmts.extend(statements_mk_tts(cx, delimed.stream()));
-            stmts.extend(statements_mk_tt(cx, &delimed.close_tt(span.close), false));
+        TokenTree::Delimited(span, delim, ref tts) => {
+            let mut stmts = statements_mk_tt(cx, &TokenTree::open_tt(span.open, delim), false);
+            stmts.extend(statements_mk_tts(cx, tts.stream()));
+            stmts.extend(statements_mk_tt(cx, &TokenTree::close_tt(span.close, delim), false));
             stmts
         }
     }
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 75e2508..ec27cee 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -21,8 +21,8 @@
 use symbol::Symbol;
 use tokenstream;
 
-use std::fs::File;
-use std::io::prelude::*;
+use std::fs;
+use std::io::ErrorKind;
 use std::path::PathBuf;
 use rustc_data_structures::sync::Lrc;
 
@@ -137,18 +137,7 @@
         None => return DummyResult::expr(sp)
     };
     let file = res_rel_file(cx, sp, file);
-    let mut bytes = Vec::new();
-    match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
-        Ok(..) => {}
-        Err(e) => {
-            cx.span_err(sp,
-                        &format!("couldn't read {}: {}",
-                                file.display(),
-                                e));
-            return DummyResult::expr(sp);
-        }
-    };
-    match String::from_utf8(bytes) {
+    match fs::read_to_string(&file) {
         Ok(src) => {
             let interned_src = Symbol::intern(&src);
 
@@ -157,11 +146,13 @@
             cx.source_map().new_source_file(file.into(), src);
 
             base::MacEager::expr(cx.expr_str(sp, interned_src))
+        },
+        Err(ref e) if e.kind() == ErrorKind::InvalidData => {
+            cx.span_err(sp, &format!("{} wasn't a utf-8 file", file.display()));
+            DummyResult::expr(sp)
         }
-        Err(_) => {
-            cx.span_err(sp,
-                        &format!("{} wasn't a utf-8 file",
-                                file.display()));
+        Err(e) => {
+            cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
             DummyResult::expr(sp)
         }
     }
@@ -174,22 +165,23 @@
         None => return DummyResult::expr(sp)
     };
     let file = res_rel_file(cx, sp, file);
-    let mut bytes = Vec::new();
-    match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
-        Err(e) => {
-            cx.span_err(sp,
-                        &format!("couldn't read {}: {}", file.display(), e));
-            DummyResult::expr(sp)
-        }
-        Ok(..) => {
-            let src = match String::from_utf8(bytes.clone()) {
-                Ok(contents) => contents,
-                Err(..) => "".to_string()
+    match fs::read(&file) {
+        Ok(bytes) => {
+            // Add the contents to the source map if it contains UTF-8.
+            let (contents, bytes) = match String::from_utf8(bytes) {
+                Ok(s) => {
+                    let bytes = s.as_bytes().to_owned();
+                    (s, bytes)
+                },
+                Err(e) => (String::new(), e.into_bytes()),
             };
-
-            cx.source_map().new_source_file(file.into(), src);
+            cx.source_map().new_source_file(file.into(), contents);
 
             base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::new(bytes))))
+        },
+        Err(e) => {
+            cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
+            DummyResult::expr(sp)
         }
     }
 }
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 68d94b4..26348d5 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -214,10 +214,10 @@
     up: Option<MatcherPosHandle<'root, 'tt>>,
 
     /// Specifically used to "unzip" token trees. By "unzip", we mean to unwrap the delimiters from
-    /// a delimited token tree (e.g. something wrapped in `(` `)`) or to get the contents of a doc
+    /// a delimited token tree (e.g., something wrapped in `(` `)`) or to get the contents of a doc
     /// comment...
     ///
-    /// When matching against matchers with nested delimited submatchers (e.g. `pat ( pat ( .. )
+    /// When matching against matchers with nested delimited submatchers (e.g., `pat ( pat ( .. )
     /// pat ) pat`), we need to keep track of the matchers we are descending into. This stack does
     /// that where the bottom of the stack is the outermost matcher.
     /// Also, throughout the comments, this "descent" is often referred to as "unzipping"...
@@ -373,7 +373,7 @@
     ms: &[TokenTree],
     mut res: I,
 ) -> NamedParseResult {
-    // Recursively descend into each type of matcher (e.g. sequences, delimited, metavars) and make
+    // Recursively descend into each type of matcher (e.g., sequences, delimited, metavars) and make
     // sure that each metavar has _exactly one_ binding. If a metavar does not have exactly one
     // binding, then there is an error. If it does, then we insert the binding into the
     // `NamedParseResult`.
@@ -895,7 +895,7 @@
 ///
 /// - `p`: the "black-box" parser to use
 /// - `sp`: the `Span` we want to parse
-/// - `name`: the name of the metavar _matcher_ we want to match (e.g. `tt`, `ident`, `block`,
+/// - `name`: the name of the metavar _matcher_ we want to match (e.g., `tt`, `ident`, `block`,
 ///   etc...)
 ///
 /// # Returns
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index ff622b0..30322ff 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -77,9 +77,9 @@
             e
         }));
 
-        // We allow semicolons at the end of expressions -- e.g. the semicolon in
+        // We allow semicolons at the end of expressions -- e.g., the semicolon in
         // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
-        // but `m!()` is allowed in expression positions (c.f. issue #34706).
+        // but `m!()` is allowed in expression positions (cf. issue #34706).
         if kind == AstFragmentKind::Expr && parser.token == token::Semi {
             parser.bump();
         }
@@ -482,15 +482,15 @@
     err == sess.span_diagnostic.err_count()
 }
 
-// The FirstSets for a matcher is a mapping from subsequences in the
+// `The FirstSets` for a matcher is a mapping from subsequences in the
 // matcher to the FIRST set for that subsequence.
 //
 // This mapping is partially precomputed via a backwards scan over the
 // token trees of the matcher, which provides a mapping from each
-// repetition sequence to its FIRST set.
+// repetition sequence to its *first* set.
 //
-// (Hypothetically sequences should be uniquely identifiable via their
-// spans, though perhaps that is false e.g. for macro-generated macros
+// (Hypothetically, sequences should be uniquely identifiable via their
+// spans, though perhaps that is false, e.g., for macro-generated macros
 // that do not try to inject artificial span information. My plan is
 // to try to catch such cases ahead of time and not include them in
 // the precomputed mapping.)
diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs
index edc431b..b142f09 100644
--- a/src/libsyntax/ext/tt/quoted.rs
+++ b/src/libsyntax/ext/tt/quoted.rs
@@ -93,9 +93,9 @@
     Delimited(DelimSpan, Lrc<Delimited>),
     /// A kleene-style repetition sequence
     Sequence(DelimSpan, Lrc<SequenceRepetition>),
-    /// E.g. `$var`
+    /// e.g., `$var`
     MetaVar(Span, ast::Ident),
-    /// E.g. `$var:expr`. This is only used in the left hand side of MBE macros.
+    /// e.g., `$var:expr`. This is only used in the left hand side of MBE macros.
     MetaVarDecl(
         Span,
         ast::Ident, /* name to bind */
@@ -199,7 +199,7 @@
     let mut trees = input.trees().peekable();
     while let Some(tree) = trees.next() {
         // Given the parsed tree, if there is a metavar and we are expecting matchers, actually
-        // parse out the matcher (i.e. in `$id:ident` this would parse the `:` and `ident`).
+        // parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`).
         let tree = parse_tree(
             tree,
             &mut trees,
@@ -281,16 +281,16 @@
         tokenstream::TokenTree::Token(span, token::Dollar) => match trees.next() {
             // `tree` is followed by a delimited set of token trees. This indicates the beginning
             // of a repetition sequence in the macro (e.g. `$(pat)*`).
-            Some(tokenstream::TokenTree::Delimited(span, delimited)) => {
+            Some(tokenstream::TokenTree::Delimited(span, delim, tts)) => {
                 // Must have `(` not `{` or `[`
-                if delimited.delim != token::Paren {
-                    let tok = pprust::token_to_string(&token::OpenDelim(delimited.delim));
+                if delim != token::Paren {
+                    let tok = pprust::token_to_string(&token::OpenDelim(delim));
                     let msg = format!("expected `(`, found `{}`", tok);
                     sess.span_diagnostic.span_err(span.entire(), &msg);
                 }
                 // Parse the contents of the sequence itself
                 let sequence = parse(
-                    delimited.tts.into(),
+                    tts.into(),
                     expect_matchers,
                     sess,
                     features,
@@ -309,7 +309,7 @@
                         edition,
                         macro_node_id,
                     );
-                // Count the number of captured "names" (i.e. named metavars)
+                // Count the number of captured "names" (i.e., named metavars)
                 let name_captures = macro_parser::count_names(&sequence);
                 TokenTree::Sequence(
                     span,
@@ -352,14 +352,14 @@
         // `tree` is an arbitrary token. Keep it.
         tokenstream::TokenTree::Token(span, tok) => TokenTree::Token(span, tok),
 
-        // `tree` is the beginning of a delimited set of tokens (e.g. `(` or `{`). We need to
+        // `tree` is the beginning of a delimited set of tokens (e.g., `(` or `{`). We need to
         // descend into the delimited set and further parse it.
-        tokenstream::TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
+        tokenstream::TokenTree::Delimited(span, delim, tts) => TokenTree::Delimited(
             span,
             Lrc::new(Delimited {
-                delim: delimited.delim,
+                delim: delim,
                 tts: parse(
-                    delimited.tts.into(),
+                    tts.into(),
                     expect_matchers,
                     sess,
                     features,
@@ -444,7 +444,6 @@
             macro_node_id,
         ),
         Edition::Edition2018 => parse_sep_and_kleene_op_2018(input, span, sess, features, attrs),
-        _ => unimplemented!(),
     }
 }
 
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 3d897d17..a76779f 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -17,7 +17,7 @@
 use parse::token::{self, Token, NtTT};
 use smallvec::SmallVec;
 use syntax_pos::DUMMY_SP;
-use tokenstream::{TokenStream, TokenTree, Delimited, DelimSpan};
+use tokenstream::{TokenStream, TokenTree, DelimSpan};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
@@ -105,10 +105,11 @@
                     if result_stack.is_empty() {
                         return TokenStream::concat(result);
                     }
-                    let tree = TokenTree::Delimited(span, Delimited {
-                        delim: forest.delim,
-                        tts: TokenStream::concat(result).into(),
-                    });
+                    let tree = TokenTree::Delimited(
+                        span,
+                        forest.delim,
+                        TokenStream::concat(result).into(),
+                    );
                     result = result_stack.pop().unwrap();
                     result.push(tree.into());
                 }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index bfdc753..1a4de59 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Feature gating
+//! # Feature gating
 //!
 //! This module implements the gating necessary for preventing certain compiler
 //! features from being used by default. This module will crawl a pre-expanded
@@ -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.
@@ -106,7 +105,7 @@
     }
 }
 
-// If you change this, please modify src/doc/unstable-book as well.
+// If you change this, please modify `src/doc/unstable-book` as well.
 //
 // Don't ever remove anything from this list; set them to 'Removed'.
 //
@@ -114,7 +113,7 @@
 // was set. This is most important for knowing when a particular feature became
 // stable (active).
 //
-// NB: tools/tidy/src/features.rs parses this information directly out of the
+// N.B., `tools/tidy/src/features.rs` parses this information directly out of the
 // source, so take care when modifying it.
 
 declare_features! (
@@ -153,66 +152,61 @@
     (active, panic_runtime, "1.10.0", Some(32837), None),
     (active, needs_panic_runtime, "1.10.0", Some(32837), None),
 
-    // OIBIT specific features
+    // Features specific to OIBIT (auto traits)
     (active, optin_builtin_traits, "1.0.0", Some(13231), None),
 
-    // Allows use of #[staged_api]
+    // Allows `#[staged_api]`.
     //
     // rustc internal
     (active, staged_api, "1.0.0", None, None),
 
-    // Allows using #![no_core]
+    // Allows `#![no_core]`.
     (active, no_core, "1.3.0", Some(29639), None),
 
-    // Allows using `box` in patterns; RFC 469
+    // Allows the use of `box` in patterns (RFC 469).
     (active, box_patterns, "1.0.0", Some(29641), None),
 
-    // Allows using the unsafe_destructor_blind_to_params attribute;
-    // RFC 1238
+    // Allows the use of the `unsafe_destructor_blind_to_params` attribute (RFC 1238).
     (active, dropck_parametricity, "1.3.0", Some(28498), None),
 
-    // Allows using the may_dangle attribute; RFC 1327
+    // Allows using the `may_dangle` attribute (RFC 1327).
     (active, dropck_eyepatch, "1.10.0", Some(34761), None),
 
-    // Allows the use of custom attributes; RFC 572
+    // Allows the use of custom attributes (RFC 572).
     (active, custom_attribute, "1.0.0", Some(29642), None),
 
-    // Allows the use of #[derive(Anything)] as sugar for
-    // #[derive_Anything].
-    (active, custom_derive, "1.0.0", Some(29644), None),
-
-    // Allows the use of rustc_* attributes; RFC 572
+    // Allows the use of `rustc_*` attributes (RFC 572).
     (active, rustc_attrs, "1.0.0", Some(29642), None),
 
-    // Allows the use of non lexical lifetimes; RFC 2094
+    // Allows the use of non lexical lifetimes (RFC 2094).
     (active, nll, "1.0.0", Some(43234), None),
 
-    // Allows the use of #[allow_internal_unstable]. This is an
-    // attribute on macro_rules! and can't use the attribute handling
+    // Allows the use of `#[allow_internal_unstable]`. This is an
+    // attribute on `macro_rules!` and can't use the attribute handling
     // below (it has to be checked before expansion possibly makes
     // macros disappear).
     //
     // rustc internal
     (active, allow_internal_unstable, "1.0.0", None, None),
 
-    // Allows the use of #[allow_internal_unsafe]. This is an
-    // attribute on macro_rules! and can't use the attribute handling
+    // Allows the use of `#[allow_internal_unsafe]`. This is an
+    // attribute on `macro_rules!` and can't use the attribute handling
     // below (it has to be checked before expansion possibly makes
     // macros disappear).
     //
     // rustc internal
     (active, allow_internal_unsafe, "1.0.0", None, None),
 
-    // #23121. Array patterns have some hazards yet.
+    // Allows the use of slice patterns (issue #23121).
     (active, slice_patterns, "1.0.0", Some(23121), None),
 
-    // Allows the definition of `const fn` functions with some advanced features.
+    // Allows the definition of `const` functions with some advanced features.
     (active, const_fn, "1.2.0", Some(24111), None),
 
-    // Allows let bindings and destructuring in `const fn` functions and constants.
+    // Allows let bindings and destructuring in `const` functions and constants.
     (active, const_let, "1.22.1", Some(48821), None),
 
-    // Allows accessing fields of unions inside const fn.
+    // Allows accessing fields of unions inside `const` functions.
     (active, const_fn_union, "1.27.0", Some(51909), None),
 
     // Allows casting raw pointers to `usize` during const eval.
@@ -227,10 +221,10 @@
     // Allows comparing raw pointers during const eval.
     (active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
 
-    // Allows panicking during const eval (produces compile-time errors)
+    // Allows panicking during const eval (producing compile-time errors).
     (active, const_panic, "1.30.0", Some(51999), None),
 
-    // Allows using #[prelude_import] on glob `use` items.
+    // Allows using `#[prelude_import]` on glob `use` items.
     //
     // rustc internal
     (active, prelude_import, "1.2.0", None, None),
@@ -238,117 +232,121 @@
     // Allows default type parameters to influence type inference.
     (active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
 
-    // Allows associated type defaults
+    // Allows associated type defaults.
     (active, associated_type_defaults, "1.2.0", Some(29661), None),
 
-    // Allows `repr(simd)`, and importing the various simd intrinsics
+    // Allows `repr(simd)` and importing the various simd intrinsics.
     (active, repr_simd, "1.4.0", Some(27731), None),
 
-    // Allows `extern "platform-intrinsic" { ... }`
+    // Allows `extern "platform-intrinsic" { ... }`.
     (active, platform_intrinsics, "1.4.0", Some(27731), None),
 
-    // Allows `#[unwind(..)]`
+    // Allows `#[unwind(..)]`.
+    //
     // rustc internal for rust runtime
     (active, unwind_attributes, "1.4.0", None, None),
 
     // Allows the use of `#[naked]` on functions.
     (active, naked_functions, "1.9.0", Some(32408), None),
 
-    // Allows `#[no_debug]`
+    // Allows `#[no_debug]`.
     (active, no_debug, "1.5.0", Some(29721), None),
 
-    // Allows `#[omit_gdb_pretty_printer_section]`
+    // Allows `#[omit_gdb_pretty_printer_section]`.
     //
     // rustc internal
     (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
 
-    // Allows cfg(target_vendor = "...").
+    // Allows `cfg(target_vendor = "...")`.
     (active, cfg_target_vendor, "1.5.0", Some(29718), None),
 
-    // Allow attributes on expressions and non-item statements
+    // Allows attributes on expressions and non-item statements.
     (active, stmt_expr_attributes, "1.6.0", Some(15701), None),
 
-    // allow using type ascription in expressions
+    // Allows the use of type ascription in expressions.
     (active, type_ascription, "1.6.0", Some(23416), None),
 
-    // Allows cfg(target_thread_local)
+    // Allows `cfg(target_thread_local)`.
     (active, cfg_target_thread_local, "1.7.0", Some(29594), None),
 
     // rustc internal
     (active, abi_vectorcall, "1.7.0", None, None),
 
-    // X..Y patterns
+    // Allows `X..Y` patterns.
     (active, exclusive_range_pattern, "1.11.0", Some(37854), None),
 
     // impl specialization (RFC 1210)
     (active, specialization, "1.7.0", Some(31844), None),
 
-    // Allows cfg(target_has_atomic = "...").
+    // Allows `cfg(target_has_atomic = "...")`.
     (active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
 
-    // The `!` type. Does not imply exhaustive_patterns (below) any more.
+    // The `!` type. Does not imply 'exhaustive_patterns' (below) any more.
     (active, never_type, "1.13.0", Some(35121), None),
 
-    // Allows exhaustive pattern matching on types that contain uninhabited types
+    // Allows exhaustive pattern matching on types that contain uninhabited types.
     (active, exhaustive_patterns, "1.13.0", Some(51085), None),
 
-    // Allows untagged unions `union U { ... }`
+    // Allows untagged unions `union U { ... }`.
     (active, untagged_unions, "1.13.0", Some(32836), None),
 
-    // Used to identify the `compiler_builtins` crate
-    // rustc internal
+    // Used to identify the `compiler_builtins` crate.
+    //
+    // rustc internal.
     (active, compiler_builtins, "1.13.0", None, None),
 
-    // Allows #[link(..., cfg(..))]
+    // Allows `#[link(..., cfg(..))]`.
     (active, link_cfg, "1.14.0", Some(37406), None),
 
-    // `extern "ptx-*" fn()`
+    // Allows `extern "ptx-*" fn()`.
     (active, abi_ptx, "1.15.0", Some(38788), None),
 
-    // The `repr(i128)` annotation for enums
+    // The `repr(i128)` annotation for enums.
     (active, repr128, "1.16.0", Some(35118), None),
 
-    // The `unadjusted` ABI. Perma unstable.
+    // The `unadjusted` ABI; perma-unstable.
+    //
     // rustc internal
     (active, abi_unadjusted, "1.16.0", None, None),
 
     // Declarative macros 2.0 (`macro`).
     (active, decl_macro, "1.17.0", Some(39412), None),
 
-    // Allows #[link(kind="static-nobundle"...)]
+    // Allows `#[link(kind="static-nobundle"...)]`.
     (active, static_nobundle, "1.16.0", Some(37403), None),
 
-    // `extern "msp430-interrupt" fn()`
+    // Allows `extern "msp430-interrupt" fn()`.
     (active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
 
-    // Used to identify crates that contain sanitizer runtimes
+    // Used to identify crates that contain sanitizer runtimes.
+    //
     // rustc internal
     (active, sanitizer_runtime, "1.17.0", None, None),
 
-    // Used to identify crates that contain the profiler runtime
+    // Used to identify crates that contain the profiler runtime.
     //
     // rustc internal
     (active, profiler_runtime, "1.18.0", None, None),
 
-    // `extern "x86-interrupt" fn()`
+    // Allows `extern "x86-interrupt" fn()`.
     (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
 
-    // Allows the `try {...}` expression
+    // Allows the `try {...}` expression.
     (active, try_blocks, "1.29.0", Some(31436), None),
 
-    // Allows module-level inline assembly by way of global_asm!()
+    // Allows module-level inline assembly by way of `global_asm!()`.
     (active, global_asm, "1.18.0", Some(35119), None),
 
-    // Allows overlapping impls of marker traits
+    // Allows overlapping impls of marker traits.
     (active, overlapping_marker_traits, "1.18.0", Some(29864), None),
 
-    // Trait attribute to allow overlapping impls
+    // Trait attribute to allow overlapping impls.
     (active, marker_trait_attr, "1.30.0", Some(29864), None),
 
     // rustc internal
     (active, abi_thiscall, "1.19.0", None, None),
 
-    // Allows a test to fail without failing the whole suite
+    // Allows a test to fail without failing the whole suite.
     (active, allow_fail, "1.19.0", Some(46488), None),
 
     // Allows unsized tuple coercion.
@@ -363,28 +361,28 @@
     // rustc internal
     (active, allocator_internals, "1.20.0", None, None),
 
-    // #[doc(cfg(...))]
+    // `#[doc(cfg(...))]`
     (active, doc_cfg, "1.21.0", Some(43781), None),
-    // #[doc(masked)]
+    // `#[doc(masked)]`
     (active, doc_masked, "1.21.0", Some(44027), None),
-    // #[doc(spotlight)]
+    // `#[doc(spotlight)]`
     (active, doc_spotlight, "1.22.0", Some(45040), None),
-    // #[doc(include="some-file")]
+    // `#[doc(include = "some-file")]`
     (active, external_doc, "1.22.0", Some(44732), None),
 
-    // Future-proofing enums/structs with #[non_exhaustive] attribute (RFC 2008)
+    // Future-proofing enums/structs with `#[non_exhaustive]` attribute (RFC 2008).
     (active, non_exhaustive, "1.22.0", Some(44109), None),
 
-    // `crate` as visibility modifier, synonymous to `pub(crate)`
+    // Adds `crate` as visibility modifier, synonymous with `pub(crate)`.
     (active, crate_visibility_modifier, "1.23.0", Some(53120), None),
 
     // extern types
     (active, extern_types, "1.23.0", Some(43467), None),
 
-    // Allows trait methods with arbitrary self types
+    // Allows trait methods with arbitrary self types.
     (active, arbitrary_self_types, "1.23.0", Some(44874), None),
 
-    // In-band lifetime bindings (e.g. `fn foo(x: &'a u8) -> &'a u8`)
+    // In-band lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
     (active, in_band_lifetimes, "1.23.0", Some(44524), None),
 
     // Generic associated types (RFC 1598)
@@ -393,25 +391,25 @@
     // `extern` in paths
     (active, extern_in_paths, "1.23.0", Some(55600), None),
 
-    // Infer static outlives requirements; RFC 2093
+    // Infer static outlives requirements (RFC 2093).
     (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
 
-    // Multiple patterns with `|` in `if let` and `while let`
+    // Multiple patterns with `|` in `if let` and `while let`.
     (active, if_while_or_patterns, "1.26.0", Some(48215), None),
 
-    // Allows `#[repr(packed)]` attribute on structs
+    // Allows `#[repr(packed)]` attribute on structs.
     (active, repr_packed, "1.26.0", Some(33158), None),
 
-    // `use path as _;` and `extern crate c as _;`
+    // Allows `use path as _;` and `extern crate c as _;`.
     (active, underscore_imports, "1.26.0", Some(48216), None),
 
-    // Allows macro invocations in `extern {}` blocks
+    // Allows macro invocations in `extern {}` blocks.
     (active, macros_in_extern, "1.27.0", Some(49476), None),
 
     // `existential type`
     (active, existential_type, "1.28.0", Some(34511), None),
 
-    // unstable #[target_feature] directives
+    // unstable `#[target_feature]` directives
     (active, arm_target_feature, "1.27.0", Some(44839), None),
     (active, aarch64_target_feature, "1.27.0", Some(44839), None),
     (active, hexagon_target_feature, "1.27.0", Some(44839), None),
@@ -427,64 +425,64 @@
     // procedural macros to expand to non-items.
     (active, proc_macro_hygiene, "1.30.0", Some(54727), None),
 
-    // #[doc(alias = "...")]
+    // `#[doc(alias = "...")]`
     (active, doc_alias, "1.27.0", Some(50146), None),
 
-    // Allows irrefutable patterns in if-let and while-let statements (RFC 2086)
+    // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
     (active, irrefutable_let_patterns, "1.27.0", Some(44495), None),
 
     // inconsistent bounds in where clauses
     (active, trivial_bounds, "1.28.0", Some(48214), None),
 
-    // 'a: { break 'a; }
+    // `'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 = "...")]
+    // `#[doc(keyword = "...")]`
     (active, doc_keyword, "1.28.0", Some(51315), None),
 
-    // Allows async and await syntax
+    // Allows async and await syntax.
     (active, async_await, "1.28.0", Some(50547), None),
 
-    // #[alloc_error_handler]
+    // `#[alloc_error_handler]`
     (active, alloc_error_handler, "1.29.0", Some(51540), None),
 
     (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None),
 
-    // Perma-unstable; added for testing E0705
+    // Added for testing E0705; perma-unstable.
     (active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)),
 
-    // Support for arbitrary delimited token streams in non-macro attributes
+    // support for arbitrary delimited token streams in non-macro attributes
     (active, unrestricted_attribute_tokens, "1.30.0", Some(55208), None),
 
-    // Allows `use x::y;` to resolve through `self::x`, not just `::x`
+    // Allows `use x::y;` to resolve through `self::x`, not just `::x`.
     (active, uniform_paths, "1.30.0", Some(53130), None),
 
-    // Allows unsized rvalues at arguments and parameters
+    // Allows unsized rvalues at arguments and parameters.
     (active, unsized_locals, "1.30.0", Some(48055), None),
 
-    // #![test_runner]
-    // #[test_case]
+    // `#![test_runner]`
+    // `#[test_case]`
     (active, custom_test_frameworks, "1.30.0", Some(50297), None),
 
-    // Non-builtin attributes in inner attribute position
+    // non-builtin attributes in inner attribute position
     (active, custom_inner_attributes, "1.30.0", Some(54726), None),
 
-    // allow mixing of bind-by-move in patterns and references to
+    // 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
-    // edition:2018 or later.
+    // (aka NLL). Essentially this means you need to be using the
+    // 2018 edition or later.
     (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
 
-    // Allows `impl Trait` in bindings (`let`, `const`, `static`)
+    // Allows `impl Trait` in bindings (`let`, `const`, `static`).
     (active, impl_trait_in_bindings, "1.30.0", Some(34511), None),
 
-    // #[cfg_attr(predicate, multiple, attributes, here)]
+    // `#[cfg_attr(predicate, multiple, attributes, here)]`
     (active, cfg_attr_multi, "1.31.0", Some(54881), None),
 
-    // Allows `const _: TYPE = VALUE`
+    // Allows `const _: TYPE = VALUE`.
     (active, underscore_const_names, "1.31.0", Some(54912), None),
 
     // `reason = ` in lint attributes and `expect` lint attribute
@@ -500,7 +498,7 @@
 declare_features! (
     (removed, import_shadowing, "1.0.0", None, None, None),
     (removed, managed_boxes, "1.0.0", None, None, None),
-    // Allows use of unary negate on unsigned integers, e.g. -e for e: u8
+    // Allows use of unary negate on unsigned integers, e.g., -e for e: u8
     (removed, negate_unsigned, "1.0.0", Some(29645), None, None),
     (removed, reflect, "1.0.0", Some(27749), None, None),
     // A way to temporarily opt out of opt in copy. This will *never* be accepted.
@@ -531,6 +529,9 @@
      Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
     (removed, panic_implementation, "1.28.0", Some(44489), None,
      Some("subsumed by `#[panic_handler]`")),
+    // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
+    (removed, custom_derive, "1.0.0", Some(29644), None,
+     Some("subsumed by `#[proc_macro_derive]`")),
 );
 
 declare_features! (
@@ -539,9 +540,9 @@
 
 declare_features! (
     (accepted, associated_types, "1.0.0", None, None),
-    // allow overloading augmented assignment operations like `a += b`
+    // Allows overloading augmented assignment operations like `a += b`.
     (accepted, augmented_assignments, "1.8.0", Some(28235), None),
-    // allow empty structs and enum variants with braces
+    // Allows empty structs and enum variants with braces.
     (accepted, braced_empty_structs, "1.8.0", Some(29720), None),
     // Allows indexing into constant arrays.
     (accepted, const_indexing, "1.26.0", Some(29947), None),
@@ -552,69 +553,68 @@
     // to bootstrap fix for #5723.
     (accepted, issue_5723_bootstrap, "1.0.0", None, None),
     (accepted, macro_rules, "1.0.0", None, None),
-    // Allows using #![no_std]
+    // Allows using `#![no_std]`.
     (accepted, no_std, "1.6.0", None, None),
     (accepted, slicing_syntax, "1.0.0", None, None),
     (accepted, struct_variant, "1.0.0", None, None),
     // These are used to test this portion of the compiler, they don't actually
-    // mean anything
+    // mean anything.
     (accepted, test_accepted_feature, "1.0.0", None, None),
     (accepted, tuple_indexing, "1.0.0", None, None),
     // Allows macros to appear in the type position.
     (accepted, type_macros, "1.13.0", Some(27245), None),
     (accepted, while_let, "1.0.0", None, None),
-    // Allows `#[deprecated]` attribute
+    // Allows `#[deprecated]` attribute.
     (accepted, deprecated, "1.9.0", Some(29935), None),
     // `expr?`
     (accepted, question_mark, "1.13.0", Some(31436), None),
-    // Allows `..` in tuple (struct) patterns
+    // Allows `..` in tuple (struct) patterns.
     (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None),
     (accepted, item_like_imports, "1.15.0", Some(35120), None),
     // Allows using `Self` and associated types in struct expressions and patterns.
     (accepted, more_struct_aliases, "1.16.0", Some(37544), None),
-    // elide `'static` lifetimes in `static`s and `const`s
+    // elide `'static` lifetimes in `static`s and `const`s.
     (accepted, static_in_const, "1.17.0", Some(35897), None),
     // Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
     (accepted, field_init_shorthand, "1.17.0", Some(37340), None),
     // Allows the definition recursive static items.
     (accepted, static_recursion, "1.17.0", Some(29719), None),
-    // pub(restricted) visibilities (RFC 1422)
+    // `pub(restricted)` visibilities (RFC 1422)
     (accepted, pub_restricted, "1.18.0", Some(32409), None),
-    // The #![windows_subsystem] attribute
+    // `#![windows_subsystem]`
     (accepted, windows_subsystem, "1.18.0", Some(37499), None),
     // Allows `break {expr}` with a value inside `loop`s.
     (accepted, loop_break_value, "1.19.0", Some(37339), None),
     // Permits numeric fields in struct expressions and patterns.
     (accepted, relaxed_adts, "1.19.0", Some(35626), None),
-    // Coerces non capturing closures to function pointers
+    // Coerces non capturing closures to function pointers.
     (accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None),
     // Allows attributes on struct literal fields.
     (accepted, struct_field_attributes, "1.20.0", Some(38814), None),
-    // Allows the definition of associated constants in `trait` or `impl`
-    // blocks.
+    // Allows the definition of associated constants in `trait` or `impl` blocks.
     (accepted, associated_consts, "1.20.0", Some(29646), None),
-    // Usage of the `compile_error!` macro
+    // Usage of the `compile_error!` macro.
     (accepted, compile_error, "1.20.0", Some(40872), None),
     // See rust-lang/rfcs#1414. Allows code like `let x: &'static u32 = &42` to work.
     (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
-    // Allow Drop types in constants (RFC 1440)
+    // Allows `Drop` types in constants (RFC 1440).
     (accepted, drop_types_in_const, "1.22.0", Some(33156), None),
     // Allows the sysV64 ABI to be specified on all platforms
-    // instead of just the platforms on which it is the C ABI
+    // instead of just the platforms on which it is the C ABI.
     (accepted, abi_sysv64, "1.24.0", Some(36167), None),
-    // Allows `repr(align(16))` struct attribute (RFC 1358)
+    // Allows `repr(align(16))` struct attribute (RFC 1358).
     (accepted, repr_align, "1.25.0", Some(33626), None),
-    // allow '|' at beginning of match arms (RFC 1925)
+    // Allows '|' at beginning of match arms (RFC 1925).
     (accepted, match_beginning_vert, "1.25.0", Some(44101), None),
     // Nested groups in `use` (RFC 2128)
     (accepted, use_nested_groups, "1.25.0", Some(44494), None),
-    // a..=b and ..=b
+    // `a..=b` and `..=b`
     (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
-    // allow `..=` in patterns (RFC 1192)
+    // Allows `..=` in patterns (RFC 1192).
     (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None),
     // Termination trait in main (RFC 1937)
     (accepted, termination_trait, "1.26.0", Some(43301), None),
-    // Copy/Clone closures (RFC 2132)
+    // `Copy`/`Clone` closures (RFC 2132).
     (accepted, clone_closures, "1.26.0", Some(44490), None),
     (accepted, copy_closures, "1.26.0", Some(44490), None),
     // Allows `impl Trait` in function arguments.
@@ -625,68 +625,70 @@
     (accepted, i128_type, "1.26.0", Some(35118), None),
     // Default match binding modes (RFC 2005)
     (accepted, match_default_bindings, "1.26.0", Some(42640), None),
-    // allow `'_` placeholder lifetimes
+    // Allows `'_` placeholder lifetimes.
     (accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
-    // Allows attributes on lifetime/type formal parameters in generics (RFC 1327)
+    // Allows attributes on lifetime/type formal parameters in generics (RFC 1327).
     (accepted, generic_param_attrs, "1.27.0", Some(48848), None),
-    // Allows cfg(target_feature = "...").
+    // Allows `cfg(target_feature = "...")`.
     (accepted, cfg_target_feature, "1.27.0", Some(29717), None),
-    // Allows #[target_feature(...)]
+    // Allows `#[target_feature(...)]`.
     (accepted, target_feature, "1.27.0", None, None),
     // Trait object syntax with `dyn` prefix
     (accepted, dyn_trait, "1.27.0", Some(44662), None),
-    // allow `#[must_use]` on functions; and, must-use operators (RFC 1940)
+    // Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940).
     (accepted, fn_must_use, "1.27.0", Some(43302), None),
-    // Allows use of the :lifetime macro fragment specifier
+    // Allows use of the `:lifetime` macro fragment specifier.
     (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None),
     // Termination trait in tests (RFC 1937)
     (accepted, termination_trait_test, "1.27.0", Some(48854), None),
-    // The #[global_allocator] attribute
+    // The `#[global_allocator]` attribute
     (accepted, global_allocator, "1.28.0", Some(27389), None),
-    // Allows `#[repr(transparent)]` attribute on newtype structs
+    // Allows `#[repr(transparent)]` attribute on newtype structs.
     (accepted, repr_transparent, "1.28.0", Some(43036), None),
-    // Defining procedural macros in `proc-macro` crates
+    // Procedural macros in `proc-macro` crates
     (accepted, proc_macro, "1.29.0", Some(38356), None),
     // `foo.rs` as an alternative to `foo/mod.rs`
     (accepted, non_modrs_mods, "1.30.0", Some(44660), None),
-    // Allows use of the :vis macro fragment specifier
+    // Allows use of the `:vis` macro fragment specifier
     (accepted, macro_vis_matcher, "1.30.0", Some(41022), None),
     // Allows importing and reexporting macros with `use`,
     // enables macro modularization in general.
     (accepted, use_extern_macros, "1.30.0", Some(35896), None),
-    // Allows keywords to be escaped for use as identifiers
+    // Allows keywords to be escaped for use as identifiers.
     (accepted, raw_identifiers, "1.30.0", Some(48589), None),
-    // Attributes scoped to tools
+    // Attributes scoped to tools.
     (accepted, tool_attributes, "1.30.0", Some(44690), None),
-    // Allows multi-segment paths in attributes and derives
+    // Allows multi-segment paths in attributes and derives.
     (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None),
     // Allows all literals in attribute lists and values of key-value pairs.
     (accepted, attr_literals, "1.30.0", Some(34981), None),
-    // Infer outlives requirements; RFC 2093
+    // Infer outlives requirements (RFC 2093).
     (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None),
     (accepted, panic_handler, "1.30.0", Some(44489), None),
-    // Used to preserve symbols (see llvm.used)
+    // Used to preserve symbols (see llvm.used).
     (accepted, used, "1.30.0", Some(40289), None),
     // `crate` in paths
     (accepted, crate_in_paths, "1.30.0", Some(45477), None),
-    // Resolve absolute paths as paths from other crates
+    // Resolve absolute paths as paths from other crates.
     (accepted, extern_absolute_paths, "1.30.0", Some(44660), None),
-    // Access to crate names passed via `--extern` through prelude
+    // Access to crate names passed via `--extern` through prelude.
     (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<'_>
+    // `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)
+    // Allows use of the `:literal` macro fragment specifier (RFC 1576).
     (accepted, macro_literal_matcher, "1.31.0", Some(35625), None),
-    // Use `?` as the Kleene "at most one" operator
+    // 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),
@@ -772,7 +774,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),
@@ -1276,7 +1278,7 @@
             if attr.path == &**n {
                 // Plugins can't gate attributes, so we don't check for it
                 // unlike the code above; we only use this loop to
-                // short-circuit to avoid the checks below
+                // short-circuit to avoid the checks below.
                 debug!("check_attribute: {:?} is registered by a plugin, {:?}", attr.path, ty);
                 return;
             }
@@ -1286,13 +1288,10 @@
                           "unless otherwise specified, attributes \
                            with the prefix `rustc_` \
                            are reserved for internal compiler diagnostics");
-        } else if name.starts_with("derive_") {
-            gate_feature!(self, custom_derive, attr.span, EXPLAIN_DERIVE_UNDERSCORE);
         } else if !attr::is_known(attr) {
-            // Only run the custom attribute lint during regular
-            // feature gate checking. Macro gating runs
-            // before the plugin attributes are registered
-            // so we skip this then
+            // Only run the custom attribute lint during regular feature gate
+            // checking. Macro gating runs before the plugin attributes are
+            // registered, so we skip this in that case.
             if !is_macro {
                 let msg = format!("The attribute `{}` is currently unknown to the compiler and \
                                    may have meaning added to it in the future", attr.path);
@@ -1386,48 +1385,38 @@
 
 }
 
-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 =
-    "`#[derive]` for custom traits is deprecated and will be removed in the future.";
-
-pub const EXPLAIN_DEPR_CUSTOM_DERIVE: &'static 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 =
-    "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";
 
 struct PostExpansionVisitor<'a> {
@@ -1800,14 +1789,13 @@
                 _node_id: NodeId) {
         match fn_kind {
             FnKind::ItemFn(_, header, _, _) => {
-                // check for const fn and async fn declarations
+                // Check for const fn and async fn declarations.
                 if header.asyncness.is_async() {
                     gate_feature_post!(&self, async_await, span, "async fn is unstable");
                 }
-                // stability of const fn methods are covered in
-                // visit_trait_item and visit_impl_item below; this is
-                // because default methods don't pass through this
-                // point.
+                // Stability of const fn methods are covered in
+                // `visit_trait_item` and `visit_impl_item` below; this is
+                // because default methods don't pass through this point.
 
                 self.check_abi(header.abi, span);
             }
@@ -1884,7 +1872,7 @@
 
     fn visit_path(&mut self, path: &'a ast::Path, _id: NodeId) {
         for segment in &path.segments {
-            // Identifiers we are going to check could come from a legacy macro (e.g. `#[test]`).
+            // Identifiers we are going to check could come from a legacy macro (e.g., `#[test]`).
             // For such macros identifiers must have empty context, because this context is
             // used during name resolution and produced names must be unhygienic for compatibility.
             // On the other hand, we need the actual non-empty context for feature gate checking
@@ -1931,7 +1919,7 @@
     for &edition in ALL_EDITIONS {
         if edition <= crate_edition {
             // The `crate_edition` implies its respective umbrella feature-gate
-            // (i.e. `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
+            // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
             edition_enabled_features.insert(Symbol::intern(edition.feature_name()), edition);
         }
     }
@@ -2091,7 +2079,7 @@
 
 impl UnstableFeatures {
     pub fn from_environment() -> UnstableFeatures {
-        // Whether this is a feature-staged build, i.e. on the beta or stable channel
+        // Whether this is a feature-staged build, i.e., on the beta or stable channel
         let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
         // Whether we should enable unstable features for bootstrapping
         let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok();
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 0e6e2f9..ecb0245 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -229,7 +229,7 @@
 
     fn fold_mac(&mut self, _mac: Mac) -> Mac {
         panic!("fold_mac disabled by default");
-        // NB: see note about macros above.
+        // N.B., see note about macros above.
         // if you really want a folder that
         // works on macros, use this
         // definition in your trait impl:
@@ -605,12 +605,10 @@
     match tt {
         TokenTree::Token(span, tok) =>
             TokenTree::Token(fld.new_span(span), fld.fold_token(tok)),
-        TokenTree::Delimited(span, delimed) => TokenTree::Delimited(
+        TokenTree::Delimited(span, delim, tts) => TokenTree::Delimited(
             DelimSpan::from_pair(fld.new_span(span.open), fld.new_span(span.close)),
-            Delimited {
-                tts: fld.fold_tts(delimed.stream()).into(),
-                delim: delimed.delim,
-            }
+            delim,
+            fld.fold_tts(tts.stream()).into(),
         ),
     }
 }
@@ -637,7 +635,7 @@
 
 /// apply folder to elements of interpolated nodes
 //
-// NB: this can occur only when applying a fold to partially expanded code, where
+// N.B., this can occur only when applying a fold to partially expanded code, where
 // parsed pieces have gotten implanted ito *other* macro invocations. This is relevant
 // for macro hygiene, but possibly not elsewhere.
 //
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 3c66db0..0c24c20 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -134,7 +134,7 @@
     pub mod metadata;
 }
 
-// NB: This module needs to be declared first so diagnostics are
+// N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
 pub mod diagnostic_list;
 
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/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 80227fd..4be54e5 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1127,7 +1127,7 @@
                     "expected at least one digit in exponent"
                 );
                 if let Some(ch) = self.ch {
-                    // check for e.g. Unicode minus '−' (Issue #49746)
+                    // check for e.g., Unicode minus '−' (Issue #49746)
                     if unicode_chars::check_for_substitution(self, ch, &mut err) {
                         self.bump();
                         self.scan_digits(10, 10);
diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs
index 8047ab01..86c87cf 100644
--- a/src/libsyntax/parse/lexer/tokentrees.rs
+++ b/src/libsyntax/parse/lexer/tokentrees.rs
@@ -11,7 +11,7 @@
 use print::pprust::token_to_string;
 use parse::lexer::StringReader;
 use parse::{token, PResult};
-use tokenstream::{Delimited, DelimSpan, TokenStream, TokenTree};
+use tokenstream::{DelimSpan, TokenStream, TokenTree};
 
 impl<'a> StringReader<'a> {
     // Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`.
@@ -155,10 +155,11 @@
                     _ => {}
                 }
 
-                Ok(TokenTree::Delimited(delim_span, Delimited {
+                Ok(TokenTree::Delimited(
+                    delim_span,
                     delim,
-                    tts: tts.into(),
-                }).into())
+                    tts.into(),
+                ).into())
             },
             token::CloseDelim(_) => {
                 // An unexpected closing delimiter (i.e., there is no
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 866dba2..10c451e 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -15,7 +15,7 @@
 use early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
 use source_map::{SourceMap, FilePathMapping};
 use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
-use errors::{Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
+use errors::{FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
 use feature_gate::UnstableFeatures;
 use parse::parser::Parser;
 use ptr::P;
@@ -192,6 +192,14 @@
     source_file_to_parser(sess, file_to_source_file(sess, path, None))
 }
 
+/// Create a new parser, returning buffered diagnostics if the file doesn't
+/// exist or from lexing the initial token stream.
+pub fn maybe_new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path)
+    -> Result<Parser<'a>, Vec<Diagnostic>> {
+    let file = try_file_to_source_file(sess, path, None).map_err(|db| vec![db])?;
+    maybe_source_file_to_parser(sess, file)
+}
+
 /// Given a session, a crate config, a path, and a span, add
 /// the file at the given path to the source_map, and return a parser.
 /// On an error, use the given span as the source of the problem.
@@ -237,17 +245,30 @@
 // base abstractions
 
 /// Given a session and a path and an optional span (for error reporting),
+/// add the path to the session's source_map and return the new source_file or
+/// error when a file can't be read.
+fn try_file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
+                   -> Result<Lrc<SourceFile>, Diagnostic> {
+    sess.source_map().load_file(path)
+    .map_err(|e| {
+        let msg = format!("couldn't read {}: {}", path.display(), e);
+        let mut diag = Diagnostic::new(Level::Fatal, &msg);
+        if let Some(sp) = spanopt {
+            diag.set_span(sp);
+        }
+        diag
+    })
+}
+
+/// Given a session and a path and an optional span (for error reporting),
 /// add the path to the session's source_map and return the new source_file.
 fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
                    -> Lrc<SourceFile> {
-    match sess.source_map().load_file(path) {
+    match try_file_to_source_file(sess, path, spanopt) {
         Ok(source_file) => source_file,
-        Err(e) => {
-            let msg = format!("couldn't read {}: {}", path.display(), e);
-            match spanopt {
-                Some(sp) => sess.span_diagnostic.span_fatal(sp, &msg).raise(),
-                None => sess.span_diagnostic.fatal(&msg).raise()
-            }
+        Err(d) => {
+            DiagnosticBuilder::new_diagnostic(&sess.span_diagnostic, d).emit();
+            FatalError.raise();
         }
     }
 }
@@ -764,7 +785,7 @@
     use attr::first_attr_value_str_by_name;
     use parse;
     use print::pprust::item_to_string;
-    use tokenstream::{self, DelimSpan, TokenTree};
+    use tokenstream::{DelimSpan, TokenTree};
     use util::parser_testing::string_to_stream;
     use util::parser_testing::{string_to_expr, string_to_item};
     use with_globals;
@@ -795,42 +816,41 @@
                     Some(&TokenTree::Token(_, token::Ident(name_macro_rules, false))),
                     Some(&TokenTree::Token(_, token::Not)),
                     Some(&TokenTree::Token(_, token::Ident(name_zip, false))),
-                    Some(&TokenTree::Delimited(_, ref macro_delimed)),
+                    Some(&TokenTree::Delimited(_, macro_delim, ref macro_tts)),
                 )
                 if name_macro_rules.name == "macro_rules"
                 && name_zip.name == "zip" => {
-                    let tts = &macro_delimed.stream().trees().collect::<Vec<_>>();
+                    let tts = &macro_tts.stream().trees().collect::<Vec<_>>();
                     match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) {
                         (
                             3,
-                            Some(&TokenTree::Delimited(_, ref first_delimed)),
+                            Some(&TokenTree::Delimited(_, first_delim, ref first_tts)),
                             Some(&TokenTree::Token(_, token::FatArrow)),
-                            Some(&TokenTree::Delimited(_, ref second_delimed)),
+                            Some(&TokenTree::Delimited(_, second_delim, ref second_tts)),
                         )
-                        if macro_delimed.delim == token::Paren => {
-                            let tts = &first_delimed.stream().trees().collect::<Vec<_>>();
+                        if macro_delim == token::Paren => {
+                            let tts = &first_tts.stream().trees().collect::<Vec<_>>();
                             match (tts.len(), tts.get(0), tts.get(1)) {
                                 (
                                     2,
                                     Some(&TokenTree::Token(_, token::Dollar)),
                                     Some(&TokenTree::Token(_, token::Ident(ident, false))),
                                 )
-                                if first_delimed.delim == token::Paren && ident.name == "a" => {},
-                                _ => panic!("value 3: {:?}", *first_delimed),
+                                if first_delim == token::Paren && ident.name == "a" => {},
+                                _ => panic!("value 3: {:?} {:?}", first_delim, first_tts),
                             }
-                            let tts = &second_delimed.stream().trees().collect::<Vec<_>>();
+                            let tts = &second_tts.stream().trees().collect::<Vec<_>>();
                             match (tts.len(), tts.get(0), tts.get(1)) {
                                 (
                                     2,
                                     Some(&TokenTree::Token(_, token::Dollar)),
                                     Some(&TokenTree::Token(_, token::Ident(ident, false))),
                                 )
-                                if second_delimed.delim == token::Paren
-                                && ident.name == "a" => {},
-                                _ => panic!("value 4: {:?}", *second_delimed),
+                                if second_delim == token::Paren && ident.name == "a" => {},
+                                _ => panic!("value 4: {:?} {:?}", second_delim, second_tts),
                             }
                         },
-                        _ => panic!("value 2: {:?}", *macro_delimed),
+                        _ => panic!("value 2: {:?} {:?}", macro_delim, macro_tts),
                     }
                 },
                 _ => panic!("value: {:?}",tts),
@@ -848,26 +868,24 @@
                 TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"), false)).into(),
                 TokenTree::Delimited(
                     DelimSpan::from_pair(sp(5, 6), sp(13, 14)),
-                    tokenstream::Delimited {
-                        delim: token::DelimToken::Paren,
-                        tts: TokenStream::concat(vec![
-                            TokenTree::Token(sp(6, 7),
-                                             token::Ident(Ident::from_str("b"), false)).into(),
-                            TokenTree::Token(sp(8, 9), token::Colon).into(),
-                            TokenTree::Token(sp(10, 13),
-                                             token::Ident(Ident::from_str("i32"), false)).into(),
-                        ]).into(),
-                    }).into(),
+                    token::DelimToken::Paren,
+                    TokenStream::concat(vec![
+                        TokenTree::Token(sp(6, 7),
+                                         token::Ident(Ident::from_str("b"), false)).into(),
+                        TokenTree::Token(sp(8, 9), token::Colon).into(),
+                        TokenTree::Token(sp(10, 13),
+                                         token::Ident(Ident::from_str("i32"), false)).into(),
+                    ]).into(),
+                ).into(),
                 TokenTree::Delimited(
                     DelimSpan::from_pair(sp(15, 16), sp(20, 21)),
-                    tokenstream::Delimited {
-                        delim: token::DelimToken::Brace,
-                        tts: TokenStream::concat(vec![
-                            TokenTree::Token(sp(17, 18),
-                                             token::Ident(Ident::from_str("b"), false)).into(),
-                            TokenTree::Token(sp(18, 19), token::Semi).into(),
-                        ]).into(),
-                    }).into()
+                    token::DelimToken::Brace,
+                    TokenStream::concat(vec![
+                        TokenTree::Token(sp(17, 18),
+                                         token::Ident(Ident::from_str("b"), false)).into(),
+                        TokenTree::Token(sp(18, 19), token::Semi).into(),
+                    ]).into(),
+                ).into()
             ]);
 
             assert_eq!(tts, expected);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1cd5006..a4326d9 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -48,13 +48,14 @@
 use parse::{self, SeqSep, classify, token};
 use parse::lexer::TokenAndSpan;
 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
+use parse::token::DelimToken;
 use parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership};
 use util::parser::{AssocOp, Fixity};
 use print::pprust;
 use ptr::P;
 use parse::PResult;
 use ThinVec;
-use tokenstream::{self, Delimited, DelimSpan, ThinTokenStream, TokenTree, TokenStream};
+use tokenstream::{self, DelimSpan, ThinTokenStream, TokenTree, TokenStream};
 use symbol::{Symbol, keywords};
 
 use std::borrow::Cow;
@@ -92,12 +93,12 @@
     /// `x<y>` - comparisons, `x::<y>` - unambiguously a path.
     Expr,
     /// In other contexts, notably in types, no ambiguity exists and paths can be written
-    /// without the disambiguator, e.g. `x<y>` - unambiguously a path.
+    /// without the disambiguator, e.g., `x<y>` - unambiguously a path.
     /// Paths with disambiguators are still accepted, `x::<Y>` - unambiguously a path too.
     Type,
-    /// A path with generic arguments disallowed, e.g. `foo::bar::Baz`, used in imports,
+    /// A path with generic arguments disallowed, e.g., `foo::bar::Baz`, used in imports,
     /// visibilities or attributes.
-    /// Technically, this variant is unnecessary and e.g. `Expr` can be used instead
+    /// Technically, this variant is unnecessary and e.g., `Expr` can be used instead
     /// (paths in "mod" contexts have to be checked later for absence of generic arguments
     /// anyway, due to macros), but it is used to avoid weird suggestions about expected
     /// tokens when something goes wrong.
@@ -293,13 +294,13 @@
 }
 
 impl TokenCursorFrame {
-    fn new(sp: DelimSpan, delimited: &Delimited) -> Self {
+    fn new(sp: DelimSpan, delim: DelimToken, tts: &ThinTokenStream) -> Self {
         TokenCursorFrame {
-            delim: delimited.delim,
+            delim: delim,
             span: sp,
-            open_delim: delimited.delim == token::NoDelim,
-            tree_cursor: delimited.stream().into_trees(),
-            close_delim: delimited.delim == token::NoDelim,
+            open_delim: delim == token::NoDelim,
+            tree_cursor: tts.stream().into_trees(),
+            close_delim: delim == token::NoDelim,
             last_token: LastToken::Was(None),
         }
     }
@@ -310,14 +311,12 @@
         loop {
             let tree = if !self.frame.open_delim {
                 self.frame.open_delim = true;
-                Delimited { delim: self.frame.delim, tts: TokenStream::empty().into() }
-                    .open_tt(self.frame.span.open)
+                TokenTree::open_tt(self.frame.span.open, self.frame.delim)
             } else if let Some(tree) = self.frame.tree_cursor.next() {
                 tree
             } else if !self.frame.close_delim {
                 self.frame.close_delim = true;
-                Delimited { delim: self.frame.delim, tts: TokenStream::empty().into() }
-                    .close_tt(self.frame.span.close)
+                TokenTree::close_tt(self.frame.span.close, self.frame.delim)
             } else if let Some(frame) = self.stack.pop() {
                 self.frame = frame;
                 continue
@@ -332,8 +331,8 @@
 
             match tree {
                 TokenTree::Token(sp, tok) => return TokenAndSpan { tok: tok, sp: sp },
-                TokenTree::Delimited(sp, ref delimited) => {
-                    let frame = TokenCursorFrame::new(sp, delimited);
+                TokenTree::Delimited(sp, delim, tts) => {
+                    let frame = TokenCursorFrame::new(sp, delim, &tts);
                     self.stack.push(mem::replace(&mut self.frame, frame));
                 }
             }
@@ -362,25 +361,28 @@
         }
 
         let delim_span = DelimSpan::from_single(sp);
-        let body = TokenTree::Delimited(delim_span, Delimited {
-            delim: token::Bracket,
-            tts: [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"), false)),
-                  TokenTree::Token(sp, token::Eq),
-                  TokenTree::Token(sp, token::Literal(
-                      token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))]
-                .iter().cloned().collect::<TokenStream>().into(),
-        });
+        let body = TokenTree::Delimited(
+            delim_span,
+            token::Bracket,
+            [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"), false)),
+             TokenTree::Token(sp, token::Eq),
+             TokenTree::Token(sp, token::Literal(
+                token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))
+            ]
+            .iter().cloned().collect::<TokenStream>().into(),
+        );
 
-        self.stack.push(mem::replace(&mut self.frame, TokenCursorFrame::new(delim_span, &Delimited {
-            delim: token::NoDelim,
-            tts: if doc_comment_style(&name.as_str()) == AttrStyle::Inner {
+        self.stack.push(mem::replace(&mut self.frame, TokenCursorFrame::new(
+            delim_span,
+            token::NoDelim,
+            &if doc_comment_style(&name.as_str()) == AttrStyle::Inner {
                 [TokenTree::Token(sp, token::Pound), TokenTree::Token(sp, token::Not), body]
                     .iter().cloned().collect::<TokenStream>().into()
             } else {
                 [TokenTree::Token(sp, token::Pound), body]
                     .iter().cloned().collect::<TokenStream>().into()
             },
-        })));
+        )));
 
         self.next()
     }
@@ -561,10 +563,11 @@
             root_module_name: None,
             expected_tokens: Vec::new(),
             token_cursor: TokenCursor {
-                frame: TokenCursorFrame::new(DelimSpan::dummy(), &Delimited {
-                    delim: token::NoDelim,
-                    tts: tokens.into(),
-                }),
+                frame: TokenCursorFrame::new(
+                    DelimSpan::dummy(),
+                    token::NoDelim,
+                    &tokens.into(),
+                ),
                 stack: Vec::new(),
             },
             desugar_doc_comments,
@@ -1238,7 +1241,7 @@
         f(&match self.token_cursor.frame.tree_cursor.look_ahead(dist - 1) {
             Some(tree) => match tree {
                 TokenTree::Token(_, tok) => tok,
-                TokenTree::Delimited(_, delimited) => token::OpenDelim(delimited.delim),
+                TokenTree::Delimited(_, delim, _) => token::OpenDelim(delim),
             },
             None => token::CloseDelim(self.token_cursor.frame.delim),
         })
@@ -1251,7 +1254,7 @@
 
         match self.token_cursor.frame.tree_cursor.look_ahead(dist - 1) {
             Some(TokenTree::Token(span, _)) => span,
-            Some(TokenTree::Delimited(span, _)) => span.entire(),
+            Some(TokenTree::Delimited(span, ..)) => span.entire(),
             None => self.look_ahead_span(dist - 1),
         }
     }
@@ -1404,7 +1407,7 @@
                 // definition...
 
                 // We don't allow argument names to be left off in edition 2018.
-                p.parse_arg_general(p.span.rust_2018())
+                p.parse_arg_general(p.span.rust_2018(), true)
             })?;
             generics.where_clause = self.parse_where_clause()?;
 
@@ -1817,7 +1820,7 @@
 
     /// This version of parse arg doesn't necessarily require
     /// identifier names.
-    fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> {
+    fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool) -> PResult<'a, Arg> {
         maybe_whole!(self, NtArg, |x| x);
 
         if let Ok(Some(_)) = self.parse_self_arg() {
@@ -1849,6 +1852,17 @@
                         String::from("<identifier>: <type>"),
                         Applicability::HasPlaceholders,
                     );
+                } else if require_name && is_trait_item {
+                    if let PatKind::Ident(_, ident, _) = pat.node {
+                        err.span_suggestion_with_applicability(
+                            pat.span,
+                            "explicitly ignore parameter",
+                            format!("_: {}", ident),
+                            Applicability::MachineApplicable,
+                        );
+                    }
+
+                    err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
                 }
 
                 return Err(err);
@@ -1914,10 +1928,10 @@
 
     /// Parse a single function argument
     crate fn parse_arg(&mut self) -> PResult<'a, Arg> {
-        self.parse_arg_general(true)
+        self.parse_arg_general(true, false)
     }
 
-    /// Parse an argument in a lambda header e.g. |arg, arg|
+    /// Parse an argument in a lambda header e.g., |arg, arg|
     fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
         let pat = self.parse_pat(Some("argument name"))?;
         let t = if self.eat(&token::Colon) {
@@ -2017,6 +2031,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 +2107,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)?;
 
@@ -2306,8 +2331,8 @@
                 return Err(err)
             }
         };
-        let delimited = match self.parse_token_tree() {
-            TokenTree::Delimited(_, delimited) => delimited,
+        let tts = match self.parse_token_tree() {
+            TokenTree::Delimited(_, _, tts) => tts,
             _ => unreachable!(),
         };
         let delim = match delim {
@@ -2316,14 +2341,14 @@
             token::Brace => MacDelimiter::Brace,
             token::NoDelim => self.bug("unexpected no delimiter"),
         };
-        Ok((delim, delimited.stream().into()))
+        Ok((delim, tts.stream().into()))
     }
 
     /// At the bottom (top?) of the precedence hierarchy,
     /// parse things like parenthesized exprs,
     /// macros, return, etc.
     ///
-    /// NB: This does not parse outer attributes,
+    /// N.B., this does not parse outer attributes,
     ///     and is private because it only works
     ///     correctly if called from parse_dot_or_call_expr().
     fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
@@ -2881,10 +2906,11 @@
                                          self.token_cursor.stack.pop().unwrap());
                 self.span = frame.span.entire();
                 self.bump();
-                TokenTree::Delimited(frame.span, Delimited {
-                    delim: frame.delim,
-                    tts: frame.tree_cursor.original_stream().into(),
-                })
+                TokenTree::Delimited(
+                    frame.span,
+                    frame.delim,
+                    frame.tree_cursor.original_stream().into(),
+                )
             },
             token::CloseDelim(_) | token::Eof => unreachable!(),
             _ => {
@@ -3721,7 +3747,7 @@
         self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs))
     }
 
-    /// Parse the RHS of a local variable declaration (e.g. '= 14;')
+    /// Parse the RHS of a local variable declaration (e.g., '= 14;')
     fn parse_initializer(&mut self, skip_eq: bool) -> PResult<'a, Option<P<Expr>>> {
         if self.eat(&token::Eq) {
             Ok(Some(self.parse_expr()?))
@@ -4103,7 +4129,7 @@
         self.parse_pat_with_range_pat(true, expected)
     }
 
-    /// Parse a pattern, with a setting whether modern range patterns e.g. `a..=b`, `a..b` are
+    /// Parse a pattern, with a setting whether modern range patterns e.g., `a..=b`, `a..b` are
     /// allowed.
     fn parse_pat_with_range_pat(
         &mut self,
@@ -4445,7 +4471,7 @@
     }
 
     /// Parse a statement. This stops just before trailing semicolons on everything but items.
-    /// e.g. a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
+    /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
     pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
         Ok(self.parse_stmt_(true))
     }
@@ -4598,7 +4624,7 @@
                 let ident = self.parse_ident()?;
                 let tokens = if self.check(&token::OpenDelim(token::Brace)) {
                     match self.parse_token_tree() {
-                        TokenTree::Delimited(_, ref delimited) => delimited.stream(),
+                        TokenTree::Delimited(_, _, tts) => tts.stream(),
                         _ => unreachable!(),
                     }
                 } else if self.check(&token::OpenDelim(token::Paren)) {
@@ -5042,9 +5068,9 @@
 
     // Parse bounds of a type parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
     // BOUND = TY_BOUND | LT_BOUND
-    // LT_BOUND = LIFETIME (e.g. `'a`)
+    // LT_BOUND = LIFETIME (e.g., `'a`)
     // TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
-    // TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g. `?for<'a: 'b> m::Trait<'a>`)
+    // TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g., `?for<'a: 'b> m::Trait<'a>`)
     fn parse_generic_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, GenericBounds> {
         let mut bounds = Vec::new();
         loop {
@@ -5099,7 +5125,7 @@
     }
 
     // Parse bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
-    // BOUND = LT_BOUND (e.g. `'a`)
+    // BOUND = LT_BOUND (e.g., `'a`)
     fn parse_lt_param_bounds(&mut self) -> GenericBounds {
         let mut lifetimes = Vec::new();
         while self.check_lifetime() {
@@ -5458,7 +5484,7 @@
                             }
                         }
                     } else {
-                        match p.parse_arg_general(named_args) {
+                        match p.parse_arg_general(named_args, false) {
                             Ok(arg) => Ok(Some(arg)),
                             Err(mut e) => {
                                 e.emit();
@@ -5508,7 +5534,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)
         };
 
@@ -5800,20 +5826,14 @@
     }
 
     fn complain_if_pub_macro(&mut self, vis: &VisibilityKind, sp: Span) {
-        if let Err(mut err) = self.complain_if_pub_macro_diag(vis, sp) {
-            err.emit();
-        }
-    }
-
-    fn complain_if_pub_macro_diag(&mut self, vis: &VisibilityKind, sp: Span) -> PResult<'a, ()> {
         match *vis {
-            VisibilityKind::Inherited => Ok(()),
+            VisibilityKind::Inherited => {}
             _ => {
                 let is_macro_rules: bool = match self.token {
                     token::Ident(sid, _) => sid.name == Symbol::intern("macro_rules"),
                     _ => false,
                 };
-                if is_macro_rules {
+                let mut err = if is_macro_rules {
                     let mut err = self.diagnostic()
                         .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
                     err.span_suggestion_with_applicability(
@@ -5822,13 +5842,14 @@
                         "#[macro_export]".to_owned(),
                         Applicability::MaybeIncorrect // speculative
                     );
-                    Err(err)
+                    err
                 } else {
                     let mut err = self.diagnostic()
                         .struct_span_err(sp, "can't qualify macro invocation with `pub`");
                     err.help("try adjusting the macro to put `pub` inside the invocation");
-                    Err(err)
-                }
+                    err
+                };
+                err.emit();
             }
         }
     }
@@ -6137,9 +6158,6 @@
 
     fn consume_block(&mut self, delim: token::DelimToken) {
         let mut brace_depth = 0;
-        if !self.eat(&token::OpenDelim(delim)) {
-            return;
-        }
         loop {
             if self.eat(&token::OpenDelim(delim)) {
                 brace_depth += 1;
@@ -6150,7 +6168,7 @@
                     brace_depth -= 1;
                     continue;
                 }
-            } else if self.eat(&token::Eof) || self.eat(&token::CloseDelim(token::NoDelim)) {
+            } else if self.token == token::Eof || self.eat(&token::CloseDelim(token::NoDelim)) {
                 return;
             } else {
                 self.bump();
@@ -6282,7 +6300,7 @@
 
     /// 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,
+    /// 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> {
@@ -6330,7 +6348,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(); // `(`
@@ -6434,13 +6452,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)?;
@@ -6782,7 +6794,7 @@
         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 = if self.token.is_keyword(keywords::SelfValue) {
+        let mut ident = if self.token.is_keyword(keywords::SelfLower) {
             self.parse_path_segment_ident()
         } else {
             self.parse_ident()
@@ -7405,17 +7417,27 @@
                 return Err(err);
             } else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
                 let ident = self.parse_ident().unwrap();
+                self.bump();  // `(`
+                let kw_name = if let Ok(Some(_)) = self.parse_self_arg() {
+                    "method"
+                } else {
+                    "function"
+                };
                 self.consume_block(token::Paren);
-                let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) ||
-                    self.check(&token::OpenDelim(token::Brace))
-                {
-                    ("fn", "method", false)
+                let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
+                    self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
+                    self.bump();  // `{`
+                    ("fn", kw_name, false)
+                } else if self.check(&token::OpenDelim(token::Brace)) {
+                    self.bump();  // `{`
+                    ("fn", kw_name, false)
                 } else if self.check(&token::Colon) {
                     let kw = "struct";
                     (kw, kw, false)
                 } else {
-                    ("fn` or `struct", "method or struct", true)
+                    ("fn` or `struct", "function or struct", true)
                 };
+                self.consume_block(token::Brace);
 
                 let msg = format!("missing `{}` for {} definition", kw, kw_name);
                 let mut err = self.diagnostic().struct_span_err(sp, &msg);
@@ -7442,6 +7464,32 @@
                     }
                 }
                 return Err(err);
+            } else if self.look_ahead(1, |t| *t == token::Lt) {
+                let ident = self.parse_ident().unwrap();
+                self.eat_to_tokens(&[&token::Gt]);
+                self.bump();  // `>`
+                let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
+                    if let Ok(Some(_)) = self.parse_self_arg() {
+                        ("fn", "method", false)
+                    } else {
+                        ("fn", "function", false)
+                    }
+                } else if self.check(&token::OpenDelim(token::Brace)) {
+                    ("struct", "struct", false)
+                } else {
+                    ("fn` or `struct", "function or struct", true)
+                };
+                let msg = format!("missing `{}` for {} definition", kw, kw_name);
+                let mut err = self.diagnostic().struct_span_err(sp, &msg);
+                if !ambiguous {
+                    err.span_suggestion_short_with_applicability(
+                        sp,
+                        &format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name),
+                        format!(" {} ", kw),
+                        Applicability::MachineApplicable,
+                    );
+                }
+                return Err(err);
             }
         }
         self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
@@ -7685,7 +7733,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))
                 );
             }
 
@@ -7725,13 +7773,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 04a791f..ed74665 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -207,6 +207,10 @@
     Eof,
 }
 
+// `Token` is used a lot. Make sure it doesn't unintentionally get bigger.
+#[cfg(target_arch = "x86_64")]
+static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::<Token>() == 16);
+
 impl Token {
     pub fn interpolated(nt: Nonterminal) -> Token {
         Token::Interpolated(Lrc::new((nt, LazyTokenStream::new())))
@@ -550,7 +554,7 @@
         });
 
         // During early phases of the compiler the AST could get modified
-        // directly (e.g. attributes added or removed) and the internal cache
+        // directly (e.g., attributes added or removed) and the internal cache
         // of tokens my not be invalidated or updated. Consequently if the
         // "lossless" token stream disagrees with our actual stringification
         // (which has historically been much more battle-tested) then we go
@@ -818,16 +822,13 @@
 
         brackets.push(attr.tokens.clone());
 
-        let tokens = tokenstream::Delimited {
-            delim: DelimToken::Bracket,
-            tts: brackets.build().into(),
-        };
         // The span we list here for `#` and for `[ ... ]` are both wrong in
         // that it encompasses more than each token, but it hopefully is "good
         // enough" for now at least.
         builder.push(tokenstream::TokenTree::Token(attr.span, Pound));
         let delim_span = DelimSpan::from_single(attr.span);
-        builder.push(tokenstream::TokenTree::Delimited(delim_span, tokens));
+        builder.push(tokenstream::TokenTree::Delimited(
+            delim_span, DelimToken::Bracket, brackets.build().into()));
     }
     builder.push(tokens.clone());
     Some(builder.build())
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index aaed56d..0890be7 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -109,7 +109,7 @@
 //! The buffered tokens go through a ring-buffer, 'tokens'. The 'left' and
 //! 'right' indices denote the active portion of the ring buffer as well as
 //! describing hypothetical points-in-the-infinite-stream at most 3N tokens
-//! apart (i.e. "not wrapped to ring-buffer boundaries"). The paper will switch
+//! apart (i.e., "not wrapped to ring-buffer boundaries"). The paper will switch
 //! between using 'left' and 'right' terms to denote the wrapped-to-ring-buffer
 //! and point-in-infinite-stream senses freely.
 //!
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index a9f08fd..41165c7 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -724,7 +724,7 @@
             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().get())?;
@@ -815,12 +815,12 @@
                     _ => Ok(())
                 }
             }
-            TokenTree::Delimited(_, ref delimed) => {
-                self.writer().word(token_to_string(&delimed.open_token()))?;
+            TokenTree::Delimited(_, delim, tts) => {
+                self.writer().word(token_to_string(&token::OpenDelim(delim)))?;
                 self.writer().space()?;
-                self.print_tts(delimed.stream())?;
+                self.print_tts(tts.stream())?;
                 self.writer().space()?;
-                self.writer().word(token_to_string(&delimed.close_token()))
+                self.writer().word(token_to_string(&token::CloseDelim(delim)))
             },
         }
     }
@@ -2463,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 {
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs
index 9fbc647..17e7730 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -16,11 +16,11 @@
 //! # Motivations and benefits
 //!
 //! * **Identity**: sharing AST nodes is problematic for the various analysis
-//!   passes (e.g. one may be able to bypass the borrow checker with a shared
+//!   passes (e.g., one may be able to bypass the borrow checker with a shared
 //!   `ExprKind::AddrOf` node taking a mutable borrow). The only reason `@T` in the
 //!   AST hasn't caused issues is because of inefficient folding passes which
 //!   would always deduplicate any such shared nodes. Even if the AST were to
-//!   switch to an arena, this would still hold, i.e. it couldn't use `&'a T`,
+//!   switch to an arena, this would still hold, i.e., it couldn't use `&'a T`,
 //!   but rather a wrapper like `P<'a, T>`.
 //!
 //! * **Immutability**: `P<T>` disallows mutating its inner `T`, unlike `Box<T>`
@@ -34,7 +34,7 @@
 //! * **Maintainability**: `P<T>` provides a fixed interface - `Deref`,
 //!   `and_then` and `map` - which can remain fully functional even if the
 //!   implementation changes (using a special thread-local heap, for example).
-//!   Moreover, a switch to, e.g. `P<'a, T>` would be easy and mostly automated.
+//!   Moreover, a switch to, e.g., `P<'a, T>` would be easy and mostly automated.
 
 use std::fmt::{self, Display, Debug};
 use std::iter::FromIterator;
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index ee60d2d..9a34312 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -31,7 +31,7 @@
 
 use std::env;
 use std::fs;
-use std::io::{self, Read};
+use std::io;
 use errors::SourceMapper;
 
 /// Return the span itself if it doesn't come from a macro expansion,
@@ -96,9 +96,7 @@
     }
 
     fn read_file(&self, path: &Path) -> io::Result<String> {
-        let mut src = String::new();
-        fs::File::open(path)?.read_to_string(&mut src)?;
-        Ok(src)
+        fs::read_to_string(path)
     }
 }
 
@@ -581,7 +579,7 @@
         match self.span_to_prev_source(sp) {
             Err(_) => None,
             Ok(source) => source.split('\n').last().map(|last_line| {
-                last_line.len() - last_line.trim_left().len()
+                last_line.len() - last_line.trim_start().len()
             })
         }
     }
@@ -595,7 +593,7 @@
     /// if no character could be found or if an error occurred while retrieving the code snippet.
     pub fn span_extend_to_prev_char(&self, sp: Span, c: char) -> Span {
         if let Ok(prev_source) = self.span_to_prev_source(sp) {
-            let prev_source = prev_source.rsplit(c).nth(0).unwrap_or("").trim_left();
+            let prev_source = prev_source.rsplit(c).nth(0).unwrap_or("").trim_start();
             if !prev_source.is_empty() && !prev_source.contains('\n') {
                 return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32));
             }
@@ -615,7 +613,7 @@
         for ws in &[" ", "\t", "\n"] {
             let pat = pat.to_owned() + ws;
             if let Ok(prev_source) = self.span_to_prev_source(sp) {
-                let prev_source = prev_source.rsplit(&pat).nth(0).unwrap_or("").trim_left();
+                let prev_source = prev_source.rsplit(&pat).nth(0).unwrap_or("").trim_start();
                 if !prev_source.is_empty() && (!prev_source.contains('\n') || accept_newlines) {
                     return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32));
                 }
@@ -629,7 +627,7 @@
     pub fn span_until_char(&self, sp: Span, c: char) -> Span {
         match self.span_to_snippet(sp) {
             Ok(snippet) => {
-                let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right();
+                let snippet = snippet.split(c).nth(0).unwrap_or("").trim_end();
                 if !snippet.is_empty() && !snippet.contains('\n') {
                     sp.with_hi(BytePos(sp.lo().0 + snippet.len() as u32))
                 } else {
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/test.rs b/src/libsyntax/test.rs
index 8ff4b0d..436a167 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -281,7 +281,7 @@
         path: Vec::new(),
         test_cases: Vec::new(),
         reexport_test_harness_main,
-        // NB: doesn't consider the value of `--crate-name` passed on the command line.
+        // N.B., doesn't consider the value of `--crate-name` passed on the command line.
         is_libtest: attr::find_crate_name(&krate.attrs).map(|s| s == "test").unwrap_or(false),
         toplevel_reexport: None,
         ctxt: SyntaxContext::empty().apply_mark(mark),
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 242299f..90191c5 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -34,52 +34,6 @@
 use std::borrow::Cow;
 use std::{fmt, iter, mem};
 
-/// A delimited sequence of token trees
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
-pub struct Delimited {
-    /// The type of delimiter
-    pub delim: DelimToken,
-    /// The delimited sequence of token trees
-    pub tts: ThinTokenStream,
-}
-
-impl Delimited {
-    /// Returns the opening delimiter as a token.
-    pub fn open_token(&self) -> token::Token {
-        token::OpenDelim(self.delim)
-    }
-
-    /// Returns the closing delimiter as a token.
-    pub fn close_token(&self) -> token::Token {
-        token::CloseDelim(self.delim)
-    }
-
-    /// Returns the opening delimiter as a token tree.
-    pub fn open_tt(&self, span: Span) -> TokenTree {
-        let open_span = if span.is_dummy() {
-            span
-        } else {
-            span.with_hi(span.lo() + BytePos(self.delim.len() as u32))
-        };
-        TokenTree::Token(open_span, self.open_token())
-    }
-
-    /// Returns the closing delimiter as a token tree.
-    pub fn close_tt(&self, span: Span) -> TokenTree {
-        let close_span = if span.is_dummy() {
-            span
-        } else {
-            span.with_lo(span.hi() - BytePos(self.delim.len() as u32))
-        };
-        TokenTree::Token(close_span, self.close_token())
-    }
-
-    /// Returns the token trees inside the delimiters.
-    pub fn stream(&self) -> TokenStream {
-        self.tts.clone().into()
-    }
-}
-
 /// When the main rust parser encounters a syntax-extension invocation, it
 /// parses the arguments to the invocation as a token-tree. This is a very
 /// loose structure, such that all sorts of different AST-fragments can
@@ -97,7 +51,7 @@
     /// A single token
     Token(Span, token::Token),
     /// A delimited sequence of token trees
-    Delimited(DelimSpan, Delimited),
+    Delimited(DelimSpan, DelimToken, ThinTokenStream),
 }
 
 impl TokenTree {
@@ -116,9 +70,10 @@
     pub fn eq_unspanned(&self, other: &TokenTree) -> bool {
         match (self, other) {
             (&TokenTree::Token(_, ref tk), &TokenTree::Token(_, ref tk2)) => tk == tk2,
-            (&TokenTree::Delimited(_, ref dl), &TokenTree::Delimited(_, ref dl2)) => {
-                dl.delim == dl2.delim &&
-                dl.stream().eq_unspanned(&dl2.stream())
+            (&TokenTree::Delimited(_, delim, ref tts),
+             &TokenTree::Delimited(_, delim2, ref tts2)) => {
+                delim == delim2 &&
+                tts.stream().eq_unspanned(&tts2.stream())
             }
             (_, _) => false,
         }
@@ -134,9 +89,10 @@
             (&TokenTree::Token(_, ref tk), &TokenTree::Token(_, ref tk2)) => {
                 tk.probably_equal_for_proc_macro(tk2)
             }
-            (&TokenTree::Delimited(_, ref dl), &TokenTree::Delimited(_, ref dl2)) => {
-                dl.delim == dl2.delim &&
-                dl.stream().probably_equal_for_proc_macro(&dl2.stream())
+            (&TokenTree::Delimited(_, delim, ref tts),
+             &TokenTree::Delimited(_, delim2, ref tts2)) => {
+                delim == delim2 &&
+                tts.stream().probably_equal_for_proc_macro(&tts2.stream())
             }
             (_, _) => false,
         }
@@ -146,7 +102,7 @@
     pub fn span(&self) -> Span {
         match *self {
             TokenTree::Token(sp, _) => sp,
-            TokenTree::Delimited(sp, _) => sp.entire(),
+            TokenTree::Delimited(sp, ..) => sp.entire(),
         }
     }
 
@@ -154,7 +110,7 @@
     pub fn set_span(&mut self, span: Span) {
         match *self {
             TokenTree::Token(ref mut sp, _) => *sp = span,
-            TokenTree::Delimited(ref mut sp, _) => *sp = DelimSpan::from_single(span),
+            TokenTree::Delimited(ref mut sp, ..) => *sp = DelimSpan::from_single(span),
         }
     }
 
@@ -169,6 +125,26 @@
     pub fn joint(self) -> TokenStream {
         TokenStream { kind: TokenStreamKind::JointTree(self) }
     }
+
+    /// Returns the opening delimiter as a token tree.
+    pub fn open_tt(span: Span, delim: DelimToken) -> TokenTree {
+        let open_span = if span.is_dummy() {
+            span
+        } else {
+            span.with_hi(span.lo() + BytePos(delim.len() as u32))
+        };
+        TokenTree::Token(open_span, token::OpenDelim(delim))
+    }
+
+    /// Returns the closing delimiter as a token tree.
+    pub fn close_tt(span: Span, delim: DelimToken) -> TokenTree {
+        let close_span = if span.is_dummy() {
+            span
+        } else {
+            span.with_lo(span.hi() - BytePos(delim.len() as u32))
+        };
+        TokenTree::Token(close_span, token::CloseDelim(delim))
+    }
 }
 
 /// # Token Streams
@@ -182,6 +158,10 @@
     kind: TokenStreamKind,
 }
 
+// `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger.
+#[cfg(target_arch = "x86_64")]
+static_assert!(MEM_SIZE_OF_TOKEN_STREAM: mem::size_of::<TokenStream>() == 40);
+
 impl TokenStream {
     /// Given a `TokenStream` with a `Stream` of only two arguments, return a new `TokenStream`
     /// separating the two arguments with a comma for diagnostic suggestions.
@@ -198,7 +178,7 @@
                             continue;
                         }
                         (TokenStreamKind::Tree(TokenTree::Token(sp, _)), _) => *sp,
-                        (TokenStreamKind::Tree(TokenTree::Delimited(sp, _)), _) => sp.entire(),
+                        (TokenStreamKind::Tree(TokenTree::Delimited(sp, ..)), _) => sp.entire(),
                         _ => continue,
                     };
                     let sp = sp.shrink_to_hi();
@@ -678,6 +658,12 @@
 #[derive(Debug, Clone)]
 pub struct ThinTokenStream(Option<RcVec<TokenStream>>);
 
+impl ThinTokenStream {
+    pub fn stream(&self) -> TokenStream {
+        self.clone().into()
+    }
+}
+
 impl From<TokenStream> for ThinTokenStream {
     fn from(stream: TokenStream) -> ThinTokenStream {
         ThinTokenStream(match stream.kind {
diff --git a/src/libsyntax/util/lev_distance.rs b/src/libsyntax/util/lev_distance.rs
index fb28115..e6b81a5 100644
--- a/src/libsyntax/util/lev_distance.rs
+++ b/src/libsyntax/util/lev_distance.rs
@@ -20,7 +20,7 @@
         return a.chars().count();
     }
 
-    let mut dcol: Vec<_> = (0..b.len() + 1).collect();
+    let mut dcol: Vec<_> = (0..=b.len()).collect();
     let mut t_last = 0;
 
     for (i, sc) in a.chars().enumerate() {
diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs
index 6866806..b7cd2ac 100644
--- a/src/libsyntax/util/parser.rs
+++ b/src/libsyntax/util/parser.rs
@@ -340,8 +340,8 @@
 }
 
 
-/// Expressions that syntactically contain an "exterior" struct literal i.e. not surrounded by any
-/// parens or other delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
+/// Expressions that syntactically contain an "exterior" struct literal i.e., not surrounded by any
+/// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
 /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
 pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
     match value.node {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 77311bf..6747598 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -43,7 +43,7 @@
 /// Each method of the Visitor trait is a hook to be potentially
 /// overridden.  Each method's default implementation recursively visits
 /// the substructure of the input via the corresponding `walk` method;
-/// e.g. the `visit_mod` method by default calls `visit::walk_mod`.
+/// e.g., the `visit_mod` method by default calls `visit::walk_mod`.
 ///
 /// If you want to ensure that your code handles every variant
 /// explicitly, you need to override each method.  (And you also need
@@ -110,7 +110,7 @@
     }
     fn visit_mac(&mut self, _mac: &'ast Mac) {
         panic!("visit_mac disabled by default");
-        // NB: see note about macros above.
+        // N.B., see note about macros above.
         // if you really want a visitor that
         // works on macros, use this
         // definition in your trait impl:
@@ -841,7 +841,7 @@
 pub fn walk_tt<'a, V: Visitor<'a>>(visitor: &mut V, tt: TokenTree) {
     match tt {
         TokenTree::Token(_, tok) => visitor.visit_token(tok),
-        TokenTree::Delimited(_, delimed) => visitor.visit_tts(delimed.stream()),
+        TokenTree::Delimited(_, _, tts) => visitor.visit_tts(tts.stream()),
     }
 }
 
diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml
index 4979d0b..7ad08f7 100644
--- a/src/libsyntax_ext/Cargo.toml
+++ b/src/libsyntax_ext/Cargo.toml
@@ -15,5 +15,5 @@
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 log = "0.4"
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/assert.rs b/src/libsyntax_ext/assert.rs
index e3bd2ca..a2384b5 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -24,6 +24,14 @@
     tts: &[TokenTree],
 ) -> Box<dyn MacResult + 'cx> {
     let mut parser = cx.new_parser_from_tts(tts);
+
+    if parser.token == token::Eof {
+        cx.struct_span_err(sp, "macro requires a boolean expression as an argument")
+            .span_label(sp, "boolean expression required")
+            .emit();
+        return DummyResult::expr(sp);
+    }
+
     let cond_expr = panictry!(parser.parse_expr());
     let custom_msg_args = if parser.eat(&token::Comma) {
         let ts = parser.parse_tokens();
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/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
index 32a58de..196cfa5 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
@@ -227,7 +227,7 @@
     let fold = cs_fold1(false, // need foldr
         |cx, span, subexpr, self_f, other_fs| {
             // build up a series of `partial_cmp`s from the inside
-            // out (hence foldr) to get lexical ordering, i.e. for op ==
+            // out (hence foldr) to get lexical ordering, i.e., for op ==
             // `ast::lt`
             //
             // ```
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index a5b12ce..443fd48 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -18,7 +18,7 @@
 //! - Methods taking any number of parameters of any type, and returning
 //!   any type, other than vectors, bottom and closures.
 //! - Generating `impl`s for types with type parameters and lifetimes
-//!   (e.g. `Option<T>`), the parameters are automatically given the
+//!   (e.g., `Option<T>`), the parameters are automatically given the
 //!   current trait as a bound. (This includes separate type parameters
 //!   and lifetimes for methods.)
 //! - Additional bounds on the type parameters (`TraitDef.additional_bounds`)
@@ -30,9 +30,9 @@
 //! - `Struct`, when `Self` is a struct (including tuple structs, e.g
 //!   `struct T(i32, char)`).
 //! - `EnumMatching`, when `Self` is an enum and all the arguments are the
-//!   same variant of the enum (e.g. `Some(1)`, `Some(3)` and `Some(4)`)
+//!   same variant of the enum (e.g., `Some(1)`, `Some(3)` and `Some(4)`)
 //! - `EnumNonMatchingCollapsed` when `Self` is an enum and the arguments
-//!   are not the same variant (e.g. `None`, `Some(1)` and `None`).
+//!   are not the same variant (e.g., `None`, `Some(1)` and `None`).
 //! - `StaticEnum` and `StaticStruct` for static methods, where the type
 //!   being derived upon is either an enum or struct respectively. (Any
 //!   argument with type Self is just grouped among the non-self
@@ -224,7 +224,7 @@
     /// other than the current trait
     pub additional_bounds: Vec<Ty<'a>>,
 
-    /// Any extra lifetimes and/or bounds, e.g. `D: serialize::Decoder`
+    /// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder`
     pub generics: LifetimeBounds<'a>,
 
     /// Is it an `unsafe` trait?
@@ -242,10 +242,10 @@
 pub struct MethodDef<'a> {
     /// name of the method
     pub name: &'a str,
-    /// List of generics, e.g. `R: rand::Rng`
+    /// List of generics, e.g., `R: rand::Rng`
     pub generics: LifetimeBounds<'a>,
 
-    /// Whether there is a self argument (outer Option) i.e. whether
+    /// Whether there is a self argument (outer Option) i.e., whether
     /// this is a static function, and whether it is a pointer (inner
     /// Option)
     pub explicit_self: Option<Option<PtrTy<'a>>>,
@@ -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));
@@ -1371,7 +1371,7 @@
             // that type.  Otherwise casts to `i32` (the default repr
             // type).
             //
-            // i.e. for `enum E<T> { A, B(1), C(T, T) }`, and a deriving
+            // i.e., for `enum E<T> { A, B(1), C(T, T) }`, and a deriving
             // with three Self args, builds three statements:
             //
             // ```
@@ -1489,8 +1489,8 @@
             //
             // (See also #4499 and #12609; note that some of the
             // discussions there influence what choice we make here;
-            // e.g. if we feature-gate `match x { ... }` when x refers
-            // to an uninhabited type (e.g. a zero-variant enum or a
+            // e.g., if we feature-gate `match x { ... }` when x refers
+            // to an uninhabited type (e.g., a zero-variant enum or a
             // type holding such an enum), but do not feature-gate
             // zero-variant enums themselves, then attempting to
             // derive Debug on such a type could here generate code
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index fa284f4..11689a9 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -32,7 +32,7 @@
     Raw(ast::Mutability),
 }
 
-/// A path, e.g. `::std::option::Option::<i32>` (global). Has support
+/// A path, e.g., `::std::option::Option::<i32>` (global). Has support
 /// for type parameters and a lifetime.
 #[derive(Clone)]
 pub struct Path<'a> {
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 31e608d..24108a3 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -209,7 +209,7 @@
 impl<'a, 'b> Context<'a, 'b> {
     fn resolve_name_inplace(&self, p: &mut parse::Piece) {
         // NOTE: the `unwrap_or` branch is needed in case of invalid format
-        // arguments, e.g. `format_args!("{foo}")`.
+        // arguments, e.g., `format_args!("{foo}")`.
         let lookup = |s| *self.names.get(s).unwrap_or(&0);
 
         match *p {
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 1d814a6..c49d577 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -39,10 +39,6 @@
 
 mod diagnostics;
 
-#[macro_use]
-// for custom_derive
-pub mod deriving;
-
 mod asm;
 mod assert;
 mod cfg;
@@ -54,13 +50,14 @@
 mod format_foreign;
 mod global_asm;
 mod log_syntax;
-mod trace_macros;
+mod proc_macro_server;
 mod test;
 mod test_case;
+mod trace_macros;
 
+pub mod deriving;
 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_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index c859275..f4ff098 100644
--- a/src/libsyntax_ext/proc_macro_decls.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,
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index 6c7da58..a04d6c9 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -64,11 +64,11 @@
 
         let (tree, joint) = stream.as_tree();
         let (span, token) = match tree {
-            tokenstream::TokenTree::Delimited(span, delimed) => {
-                let delimiter = Delimiter::from_internal(delimed.delim);
+            tokenstream::TokenTree::Delimited(span, delim, tts) => {
+                let delimiter = Delimiter::from_internal(delim);
                 return TokenTree::Group(Group {
                     delimiter,
-                    stream: delimed.tts.into(),
+                    stream: tts.into(),
                     span,
                 });
             }
@@ -232,10 +232,8 @@
             }) => {
                 return tokenstream::TokenTree::Delimited(
                     span,
-                    tokenstream::Delimited {
-                        delim: delimiter.to_internal(),
-                        tts: stream.into(),
-                    },
+                    delimiter.to_internal(),
+                    stream.into(),
                 )
                 .into();
             }
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index b8a171b..1f2e6fc 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -318,7 +318,7 @@
 
 fn has_bench_signature(cx: &ExtCtxt, i: &ast::Item) -> bool {
     let has_sig = if let ast::ItemKind::Fn(ref decl, _, _, _) = i.node {
-        // NB: inadequate check, but we're running
+        // N.B., inadequate check, but we're running
         // well before resolve, can't get too deep.
         decl.inputs.len() == 1
     } else {
diff --git a/src/libsyntax_pos/analyze_source_file.rs b/src/libsyntax_pos/analyze_source_file.rs
index 7bc9a1a..f9cf0a9 100644
--- a/src/libsyntax_pos/analyze_source_file.rs
+++ b/src/libsyntax_pos/analyze_source_file.rs
@@ -47,8 +47,7 @@
 }
 
 cfg_if! {
-    if #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"),
-                 not(stage0)))] {
+    if #[cfg(all(any(target_arch = "x86", target_arch = "x86_64")))] {
         fn analyze_source_file_dispatch(src: &str,
                                     source_file_start_pos: BytePos,
                                     lines: &mut Vec<BytePos>,
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..74f63b5 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,
         }
     }
 
@@ -308,11 +308,11 @@
         }
 
         // Otherwise, `mark` is a macros 1.0 definition and the call site is in a
-        // macros 2.0 expansion, i.e. a macros 1.0 invocation is in a macros 2.0 definition.
+        // macros 2.0 expansion, i.e., a macros 1.0 invocation is in a macros 2.0 definition.
         //
         // In this case, the tokens from the macros 1.0 definition inherit the hygiene
         // at their invocation. That is, we pretend that the macros 1.0 definition
-        // was defined at its invocation (i.e. inside the macros 2.0 definition)
+        // was defined at its invocation (i.e., inside the macros 2.0 definition)
         // so that the macros 2.0 definition remains hygienic.
         //
         // See the example at `test/run-pass/hygiene/legacy_interaction.rs`.
@@ -438,7 +438,7 @@
     /// }
     /// ```
     /// This returns the expansion whose definition scope we use to privacy check the resolution,
-    /// or `None` if we privacy check as usual (i.e. not w.r.t. a macro definition scope).
+    /// or `None` if we privacy check as usual (i.e., not w.r.t. a macro definition scope).
     pub fn adjust(&mut self, expansion: Mark) -> Option<Mark> {
         let mut scope = None;
         while !expansion.is_descendant_of(self.outer()) {
@@ -540,7 +540,7 @@
     /// The location of the actual macro invocation or syntax sugar , e.g.
     /// `let x = foo!();` or `if let Some(y) = x {}`
     ///
-    /// This may recursively refer to other macro invocations, e.g. if
+    /// This may recursively refer to other macro invocations, e.g., if
     /// `foo!()` invoked `bar!()` internally, and there was an
     /// expression inside `bar!`; the call_site of the expression in
     /// the expansion would point to the `bar!` invocation; that
@@ -548,7 +548,7 @@
     /// pointing to the `foo!` invocation.
     pub call_site: Span,
     /// The span of the macro definition itself. The macro may not
-    /// have a sensible definition span (e.g. something defined
+    /// have a sensible definition span (e.g., something defined
     /// completely inside libsyntax) in which case this is None.
     /// This span serves only informational purpose and is not used for resolution.
     pub def_site: Option<Span>,
@@ -571,9 +571,9 @@
 /// The source of expansion.
 #[derive(Clone, Hash, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum ExpnFormat {
-    /// e.g. #[derive(...)] <item>
+    /// e.g., #[derive(...)] <item>
     MacroAttribute(Symbol),
-    /// e.g. `format!()`
+    /// e.g., `format!()`
     MacroBang(Symbol),
     /// Desugaring done by the compiler during HIR lowering.
     CompilerDesugaring(CompilerDesugaringKind)
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 4d42b85..9aafb9f 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! The source positions and related helper functions
+//! The source positions and related helper functions.
 //!
-//! # Note
+//! ## Note
 //!
 //! This API is completely unstable and subject to change.
 
@@ -24,21 +24,13 @@
 #![feature(nll)]
 #![feature(non_exhaustive)]
 #![feature(optin_builtin_traits)]
+#![feature(rustc_attrs)]
 #![feature(specialization)]
+#![feature(step_trait)]
 #![cfg_attr(not(stage0), feature(stdsimd))]
 
-use std::borrow::Cow;
-use std::cell::Cell;
-use std::cmp::{self, Ordering};
-use std::fmt;
-use std::hash::{Hasher, Hash};
-use std::ops::{Add, Sub};
-use std::path::PathBuf;
-
-use rustc_data_structures::stable_hasher::StableHasher;
-use rustc_data_structures::sync::{Lrc, Lock};
-
 extern crate arena;
+#[macro_use]
 extern crate rustc_data_structures;
 
 #[macro_use]
@@ -65,6 +57,17 @@
 
 mod analyze_source_file;
 
+use rustc_data_structures::stable_hasher::StableHasher;
+use rustc_data_structures::sync::{Lrc, Lock};
+
+use std::borrow::Cow;
+use std::cell::Cell;
+use std::cmp::{self, Ordering};
+use std::fmt;
+use std::hash::{Hasher, Hash};
+use std::ops::{Add, Sub};
+use std::path::PathBuf;
+
 pub struct Globals {
     symbol_interner: Lock<symbol::Interner>,
     span_interner: Lock<span_encoding::SpanInterner>,
@@ -83,25 +86,25 @@
 
 scoped_thread_local!(pub static GLOBALS: Globals);
 
-/// Differentiates between real files and common virtual files
+/// Differentiates between real files and common virtual files.
 #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
 pub enum FileName {
     Real(PathBuf),
     /// A macro.  This includes the full name of the macro, so that there are no clashes.
     Macros(String),
-    /// call to `quote!`
+    /// Call to `quote!`.
     QuoteExpansion(u64),
-    /// Command line
+    /// Command line.
     Anon(u64),
-    /// Hack in src/libsyntax/parse.rs
-    /// FIXME(jseyfried)
+    /// Hack in `src/libsyntax/parse.rs`.
+    // FIXME(jseyfried)
     MacroExpansion(u64),
     ProcMacroSourceCode(u64),
-    /// Strings provided as --cfg [cfgspec] stored in a crate_cfg
+    /// Strings provided as `--cfg [cfgspec]` stored in a `crate_cfg`.
     CfgSpec(u64),
-    /// Strings provided as crate attributes in the CLI
+    /// Strings provided as crate attributes in the CLI.
     CliCrateAttr(u64),
-    /// Custom sources for explicit parser calls from plugins and drivers
+    /// Custom sources for explicit parser calls from plugins and drivers.
     Custom(String),
     DocTest(PathBuf, isize),
 }
@@ -208,11 +211,11 @@
 
 /// Spans represent a region of code, used for error reporting. Positions in spans
 /// are *absolute* positions from the beginning of the source_map, not positions
-/// relative to SourceFiles. Methods on the SourceMap can be used to relate spans back
+/// relative to `SourceFile`s. Methods on the `SourceMap` can be used to relate spans back
 /// to the original source.
 /// You must be careful if the span crosses more than one file - you will not be
 /// able to use many of the functions on spans in source_map and you cannot assume
-/// that the length of the span = hi - lo; there may be space in the BytePos
+/// that the length of the `span = hi - lo`; there may be space in the `BytePos`
 /// range between files.
 ///
 /// `SpanData` is public because `Span` uses a thread-local interner and can't be
@@ -243,7 +246,7 @@
 }
 
 // The interner is pointed to by a thread local value which is only set on the main thread
-// with parallelization is disabled. So we don't allow Span to transfer between threads
+// with parallelization is disabled. So we don't allow `Span` to transfer between threads
 // to avoid panics and other errors, even though it would be memory safe to do so.
 #[cfg(not(parallel_queries))]
 impl !Send for Span {}
@@ -263,9 +266,9 @@
 
 /// A collection of spans. Spans have two orthogonal attributes:
 ///
-/// - they can be *primary spans*. In this case they are the locus of
+/// - They can be *primary spans*. In this case they are the locus of
 ///   the error, and would be rendered with `^^^`.
-/// - they can have a *label*. In this case, the label is written next
+/// - They can have a *label*. In this case, the label is written next
 ///   to the mark in the snippet when we render.
 #[derive(Clone, Debug, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub struct MultiSpan {
@@ -312,7 +315,7 @@
         let span = self.data();
         span.with_hi(span.lo)
     }
-    /// Returns a new span representing an empty span at the end of this span
+    /// Returns a new span representing an empty span at the end of this span.
     #[inline]
     pub fn shrink_to_hi(self) -> Span {
         let span = self.data();
@@ -324,7 +327,7 @@
         if self.is_dummy() { other } else { self }
     }
 
-    /// Return true if `self` fully encloses `other`.
+    /// Return `true` if `self` fully encloses `other`.
     pub fn contains(self, other: Span) -> bool {
         let span = self.data();
         let other = other.data();
@@ -341,7 +344,7 @@
         span.lo == other.lo && span.hi == other.hi
     }
 
-    /// Returns `Some(span)`, where the start is trimmed by the end of `other`
+    /// Returns `Some(span)`, where the start is trimmed by the end of `other`.
     pub fn trim_start(self, other: Span) -> Option<Span> {
         let span = self.data();
         let other = other.data();
@@ -352,14 +355,14 @@
         }
     }
 
-    /// Return the source span - this is either the supplied span, or the span for
+    /// Return the source span -- this is either the supplied span, or the span for
     /// the macro callsite that expanded to it.
     pub fn source_callsite(self) -> Span {
         self.ctxt().outer().expn_info().map(|info| info.call_site.source_callsite()).unwrap_or(self)
     }
 
     /// The `Span` for the tokens in the previous macro expansion from which `self` was generated,
-    /// if any
+    /// if any.
     pub fn parent(self) -> Option<Span> {
         self.ctxt().outer().expn_info().map(|i| i.call_site)
     }
@@ -395,7 +398,7 @@
         self.ctxt().outer().expn_info().map(source_callee)
     }
 
-    /// Check if a span is "internal" to a macro in which #[unstable]
+    /// Check if a span is "internal" to a macro in which `#[unstable]`
     /// items can be used (that is, a macro marked with
     /// `#[allow_internal_unstable]`).
     pub fn allows_unstable(&self) -> bool {
@@ -416,7 +419,7 @@
         }
     }
 
-    /// Return the compiler desugaring that created this span, or None
+    /// Return the compiler desugaring that created this span, or `None`
     /// if this span is not from a desugaring.
     pub fn compiler_desugaring_kind(&self) -> Option<CompilerDesugaringKind> {
         match self.ctxt().outer().expn_info() {
@@ -442,7 +445,7 @@
         let mut prev_span = DUMMY_SP;
         let mut result = vec![];
         while let Some(info) = self.ctxt().outer().expn_info() {
-            // Don't print recursive invocations
+            // Don't print recursive invocations.
             if !info.call_site.source_equal(&prev_span) {
                 let (pre, post) = match info.format {
                     ExpnFormat::MacroAttribute(..) => ("#[", "]"),
@@ -466,7 +469,7 @@
     pub fn to(self, end: Span) -> Span {
         let span_data = self.data();
         let end_data = end.data();
-        // FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480)
+        // FIXME(jseyfried): `self.ctxt` should always equal `end.ctxt` here (cf. issue #23480).
         // Return the macro span on its own to avoid weird diagnostic output. It is preferable to
         // have an incomplete span than a completely nonsensical one.
         if span_data.ctxt != end_data.ctxt {
@@ -475,8 +478,8 @@
             } else if end_data.ctxt == SyntaxContext::empty() {
                 return self;
             }
-            // both span fall within a macro
-            // FIXME(estebank) check if it is the *same* macro
+            // Both spans fall within a macro.
+            // FIXME(estebank): check if it is the *same* macro.
         }
         Span::new(
             cmp::min(span_data.lo, end_data.lo),
@@ -611,7 +614,7 @@
     }
 }
 
-fn default_span_debug(span: Span, f: &mut fmt::Formatter) -> fmt::Result {
+pub fn default_span_debug(span: Span, f: &mut fmt::Formatter) -> fmt::Result {
     f.debug_struct("Span")
         .field("lo", &span.lo())
         .field("hi", &span.hi())
@@ -658,7 +661,7 @@
         self.span_labels.push((span, label));
     }
 
-    /// Selects the first primary span (if any)
+    /// Selects the first primary span (if any).
     pub fn primary_span(&self) -> Option<Span> {
         self.primary_spans.first().cloned()
     }
@@ -679,7 +682,7 @@
         is_dummy
     }
 
-    /// Replaces all occurrences of one Span with another. Used to move Spans in areas that don't
+    /// Replaces all occurrences of one Span with another. Used to move `Span`s in areas that don't
     /// display well (like std macros). Returns true if replacements occurred.
     pub fn replace(&mut self, before: Span, after: Span) -> bool {
         let mut replacements_occurred = false;
@@ -700,7 +703,7 @@
 
     /// Returns the strings to highlight. We always ensure that there
     /// is an entry for each of the primary spans -- for each primary
-    /// span P, if there is at least one label with span P, we return
+    /// span `P`, if there is at least one label with span `P`, we return
     /// those labels (marked as primary). But otherwise we return
     /// `SpanLabel` instances with empty labels.
     pub fn span_labels(&self) -> Vec<SpanLabel> {
@@ -742,23 +745,23 @@
 
 pub const NO_EXPANSION: SyntaxContext = SyntaxContext::empty();
 
-/// Identifies an offset of a multi-byte character in a SourceFile
+/// Identifies an offset of a multi-byte character in a `SourceFile`.
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)]
 pub struct MultiByteChar {
-    /// The absolute offset of the character in the SourceMap
+    /// The absolute offset of the character in the `SourceMap`.
     pub pos: BytePos,
-    /// The number of bytes, >=2
+    /// The number of bytes, `>= 2`.
     pub bytes: u8,
 }
 
-/// Identifies an offset of a non-narrow character in a SourceFile
+/// Identifies an offset of a non-narrow character in a `SourceFile`.
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)]
 pub enum NonNarrowChar {
-    /// Represents a zero-width character
+    /// Represents a zero-width character.
     ZeroWidth(BytePos),
-    /// Represents a wide (fullwidth) character
+    /// Represents a wide (full-width) character.
     Wide(BytePos),
-    /// Represents a tab character, represented visually with a width of 4 characters
+    /// Represents a tab character, represented visually with a width of 4 characters.
     Tab(BytePos),
 }
 
@@ -772,7 +775,7 @@
         }
     }
 
-    /// Returns the absolute offset of the character in the SourceMap
+    /// Returns the absolute offset of the character in the `SourceMap`.
     pub fn pos(&self) -> BytePos {
         match *self {
             NonNarrowChar::ZeroWidth(p) |
@@ -781,7 +784,7 @@
         }
     }
 
-    /// Returns the width of the character, 0 (zero-width) or 2 (wide)
+    /// Returns the width of the character, 0 (zero-width) or 2 (wide).
     pub fn width(&self) -> usize {
         match *self {
             NonNarrowChar::ZeroWidth(_) => 0,
@@ -815,7 +818,7 @@
     }
 }
 
-/// The state of the lazy external source loading mechanism of a SourceFile.
+/// The state of the lazy external source loading mechanism of a `SourceFile`.
 #[derive(PartialEq, Eq, Clone)]
 pub enum ExternalSource {
     /// The external source has been loaded already.
@@ -824,7 +827,7 @@
     AbsentOk,
     /// A failed attempt has been made to load the external source.
     AbsentErr,
-    /// No external source has to be loaded, since the SourceFile represents a local crate.
+    /// No external source has to be loaded, since the `SourceFile` represents a local crate.
     Unneeded,
 }
 
@@ -844,38 +847,38 @@
     }
 }
 
-/// A single source in the SourceMap.
+/// A single source in the `SourceMap`.
 #[derive(Clone)]
 pub struct SourceFile {
     /// The name of the file that the source came from, source that doesn't
-    /// originate from files has names between angle brackets by convention,
-    /// e.g. `<anon>`
+    /// originate from files has names between angle brackets by convention
+    /// (e.g., `<anon>`).
     pub name: FileName,
-    /// True if the `name` field above has been modified by --remap-path-prefix
+    /// True if the `name` field above has been modified by `--remap-path-prefix`.
     pub name_was_remapped: bool,
     /// The unmapped path of the file that the source came from.
-    /// Set to `None` if the SourceFile was imported from an external crate.
+    /// Set to `None` if the `SourceFile` was imported from an external crate.
     pub unmapped_path: Option<FileName>,
-    /// Indicates which crate this SourceFile was imported from.
+    /// Indicates which crate this `SourceFile` was imported from.
     pub crate_of_origin: u32,
-    /// The complete source code
+    /// The complete source code.
     pub src: Option<Lrc<String>>,
-    /// The source code's hash
+    /// The source code's hash.
     pub src_hash: u128,
     /// The external source code (used for external crates, which will have a `None`
     /// value as `self.src`.
     pub external_src: Lock<ExternalSource>,
-    /// The start position of this source in the SourceMap
+    /// The start position of this source in the `SourceMap`.
     pub start_pos: BytePos,
-    /// The end position of this source in the SourceMap
+    /// The end position of this source in the `SourceMap`.
     pub end_pos: BytePos,
-    /// Locations of lines beginnings in the source code
+    /// Locations of lines beginnings in the source code.
     pub lines: Vec<BytePos>,
-    /// Locations of multi-byte characters in the source code
+    /// Locations of multi-byte characters in the source code.
     pub multibyte_chars: Vec<MultiByteChar>,
-    /// Width of characters that are not narrow in the source code
+    /// Width of characters that are not narrow in the source code.
     pub non_narrow_chars: Vec<NonNarrowChar>,
-    /// A hash of the filename, used for speeding up the incr. comp. hashing.
+    /// A hash of the filename, used for speeding up hashing in incremental compilation.
     pub name_hash: u128,
 }
 
@@ -889,7 +892,7 @@
             s.emit_struct_field("end_pos", 5, |s| self.end_pos.encode(s))?;
             s.emit_struct_field("lines", 6, |s| {
                 let lines = &self.lines[..];
-                // store the length
+                // Store the length.
                 s.emit_u32(lines.len() as u32)?;
 
                 if !lines.is_empty() {
@@ -1060,7 +1063,7 @@
         }
     }
 
-    /// Return the BytePos of the beginning of the current line.
+    /// Return the `BytePos` of the beginning of the current line.
     pub fn line_begin_pos(&self, pos: BytePos) -> BytePos {
         let line_index = self.lookup_line(pos).unwrap();
         self.lines[line_index]
@@ -1148,9 +1151,9 @@
     }
 
     /// Find the line containing the given position. The return value is the
-    /// index into the `lines` array of this SourceFile, not the 1-based line
+    /// index into the `lines` array of this `SourceFile`, not the 1-based line
     /// number. If the source_file is empty or the position is located before the
-    /// first line, None is returned.
+    /// first line, `None` is returned.
     pub fn lookup_line(&self, pos: BytePos) -> Option<usize> {
         if self.lines.len() == 0 {
             return None;
@@ -1207,14 +1210,14 @@
 #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
 pub struct BytePos(pub u32);
 
-/// A character offset. Because of multibyte utf8 characters, a byte offset
-/// is not equivalent to a character offset. The SourceMap will convert BytePos
-/// values to CharPos values as necessary.
+/// A character offset. Because of multibyte UTF-8 characters, a byte offset
+/// is not equivalent to a character offset. The `SourceMap` will convert `BytePos`
+/// values to `CharPos` values as necessary.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
 pub struct CharPos(pub usize);
 
-// FIXME: Lots of boilerplate in these impls, but so far my attempts to fix
-// have been unsuccessful
+// FIXME: lots of boilerplate in these impls, but so far my attempts to fix
+// have been unsuccessful.
 
 impl Pos for BytePos {
     #[inline(always)]
@@ -1296,20 +1299,20 @@
 // Loc, LocWithOpt, SourceFileAndLine, SourceFileAndBytePos
 //
 
-/// A source code location used for error reporting
+/// A source code location used for error reporting.
 #[derive(Debug, Clone)]
 pub struct Loc {
-    /// Information about the original source
+    /// Information about the original source.
     pub file: Lrc<SourceFile>,
-    /// The (1-based) line number
+    /// The (1-based) line number.
     pub line: usize,
-    /// The (0-based) column offset
+    /// The (0-based) column offset.
     pub col: CharPos,
-    /// The (0-based) column offset when displayed
+    /// The (0-based) column offset when displayed.
     pub col_display: usize,
 }
 
-/// A source code location used as the result of lookup_char_pos_adj
+/// A source code location used as the result of `lookup_char_pos_adj`.
 // Actually, *none* of the clients use the filename *or* file field;
 // perhaps they should just be removed.
 #[derive(Debug)]
@@ -1320,7 +1323,7 @@
     pub file: Option<Lrc<SourceFile>>,
 }
 
-// used to be structural records. Better names, anyone?
+// Used to be structural records.
 #[derive(Debug)]
 pub struct SourceFileAndLine { pub sf: Lrc<SourceFile>, pub line: usize }
 #[derive(Debug)]
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 741877b..b720db8 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -9,20 +9,22 @@
 // except according to those terms.
 
 //! An "interner" is a data structure that associates values with usize tags and
-//! allows bidirectional lookup; i.e. given a value, one can easily find the
+//! allows bidirectional lookup; i.e., given a value, one can easily find the
 //! type, and vice versa.
 
-use hygiene::SyntaxContext;
-use {Span, DUMMY_SP, GLOBALS};
-
-use rustc_data_structures::fx::FxHashMap;
 use arena::DroplessArena;
+use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::indexed_vec::Idx;
 use serialize::{Decodable, Decoder, Encodable, Encoder};
+
 use std::fmt;
 use std::str;
 use std::cmp::{PartialEq, Ordering, PartialOrd, Ord};
 use std::hash::{Hash, Hasher};
 
+use hygiene::SyntaxContext;
+use {Span, DUMMY_SP, GLOBALS};
+
 #[derive(Copy, Clone, Eq)]
 pub struct Ident {
     pub name: Symbol,
@@ -34,6 +36,7 @@
     pub const fn new(name: Symbol, span: Span) -> Ident {
         Ident { name, span }
     }
+
     #[inline]
     pub const fn with_empty_ctxt(name: Symbol) -> Ident {
         Ident::new(name, DUMMY_SP)
@@ -55,12 +58,12 @@
     }
 
     pub fn without_first_quote(self) -> Ident {
-        Ident::new(Symbol::intern(self.as_str().trim_left_matches('\'')), self.span)
+        Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
     }
 
     /// "Normalize" ident for use in comparisons using "item hygiene".
     /// Identifiers with same string value become same if they came from the same "modern" macro
-    /// (e.g. `macro` item, but not `macro_rules` item) and stay different if they came from
+    /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
     /// different "modern" macros.
     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
     pub fn modern(self) -> Ident {
@@ -69,7 +72,7 @@
 
     /// "Normalize" ident for use in comparisons using "local variable hygiene".
     /// Identifiers with same string value become same if they came from the same non-transparent
-    /// macro (e.g. `macro` or `macro_rules!` items) and stay different if they came from different
+    /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
     /// non-transparent macros.
     /// Technically, this operation strips all transparent marks from ident's syntactic context.
     pub fn modern_and_legacy(self) -> Ident {
@@ -80,6 +83,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()
     }
@@ -118,7 +125,7 @@
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         if self.span.ctxt().modern() == SyntaxContext::empty() {
             s.emit_str(&self.as_str())
-        } else { // FIXME(jseyfried) intercrate hygiene
+        } else { // FIXME(jseyfried): intercrate hygiene
             let mut string = "#".to_owned();
             string.push_str(&self.as_str());
             s.emit_str(&string)
@@ -131,18 +138,27 @@
         let string = d.read_str()?;
         Ok(if !string.starts_with('#') {
             Ident::from_str(&string)
-        } else { // FIXME(jseyfried) intercrate hygiene
+        } else { // FIXME(jseyfried): intercrate hygiene
             Ident::with_empty_ctxt(Symbol::gensym(&string[1..]))
         })
     }
 }
 
-/// A symbol is an interned or gensymed string.
+/// A symbol is an interned or gensymed string. The use of newtype_index! means
+/// that Option<Symbol> only takes up 4 bytes, because newtype_index! reserves
+/// the last 256 values for tagging purposes.
+///
+/// Note that Symbol cannot be a newtype_index! directly because it implements
+/// fmt::Debug, Encodable, and Decodable in special ways.
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct Symbol(u32);
+pub struct Symbol(SymbolIndex);
+
+newtype_index! {
+    pub struct SymbolIndex { .. }
+}
 
 // The interner is pointed to by a thread local value which is only set on the main thread
-// with parallelization is disabled. So we don't allow Symbol to transfer between threads
+// with parallelization is disabled. So we don't allow `Symbol` to transfer between threads
 // to avoid panics and other errors, even though it would be memory safe to do so.
 #[cfg(not(parallel_queries))]
 impl !Send for Symbol { }
@@ -150,6 +166,10 @@
 impl !Sync for Symbol { }
 
 impl Symbol {
+    const fn new(n: u32) -> Self {
+        Symbol(SymbolIndex::from_u32_const(n))
+    }
+
     /// Maps a string to its interned representation.
     pub fn intern(string: &str) -> Self {
         with_interner(|interner| interner.intern(string))
@@ -159,7 +179,7 @@
         with_interner(|interner| interner.interned(self))
     }
 
-    /// gensym's a new usize, using the current interner.
+    /// Gensyms a new usize, using the current interner.
     pub fn gensym(string: &str) -> Self {
         with_interner(|interner| interner.gensym(string))
     }
@@ -183,7 +203,7 @@
     }
 
     pub fn as_u32(self) -> u32 {
-        self.0
+        self.0.as_u32()
     }
 }
 
@@ -191,7 +211,7 @@
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let is_gensymed = with_interner(|interner| interner.is_gensymed(*self));
         if is_gensymed {
-            write!(f, "{}({})", self, self.0)
+            write!(f, "{}({:?})", self, self.0)
         } else {
             write!(f, "{}", self)
         }
@@ -222,7 +242,10 @@
     }
 }
 
-// The &'static strs in this type actually point into the arena
+// The `&'static str`s in this type actually point into the arena.
+//
+// Note that normal symbols are indexed upward from 0, and gensyms are indexed
+// downward from SymbolIndex::MAX_AS_U32.
 #[derive(Default)]
 pub struct Interner {
     arena: DroplessArena,
@@ -236,8 +259,8 @@
         let mut this = Interner::default();
         for &string in init {
             if string == "" {
-                // We can't allocate empty strings in the arena, so handle this here
-                let name = Symbol(this.strings.len() as u32);
+                // We can't allocate empty strings in the arena, so handle this here.
+                let name = Symbol::new(this.strings.len() as u32);
                 this.names.insert("", name);
                 this.strings.push("");
             } else {
@@ -252,14 +275,15 @@
             return name;
         }
 
-        let name = Symbol(self.strings.len() as u32);
+        let name = Symbol::new(self.strings.len() as u32);
 
-        // from_utf8_unchecked is safe since we just allocated a &str which is known to be utf8
+        // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
+        // UTF-8.
         let string: &str = unsafe {
             str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes()))
         };
-        // It is safe to extend the arena allocation to 'static because we only access
-        // these while the arena is still alive
+        // It is safe to extend the arena allocation to `'static` because we only access
+        // these while the arena is still alive.
         let string: &'static str =  unsafe {
             &*(string as *const str)
         };
@@ -269,10 +293,10 @@
     }
 
     pub fn interned(&self, symbol: Symbol) -> Symbol {
-        if (symbol.0 as usize) < self.strings.len() {
+        if (symbol.0.as_usize()) < self.strings.len() {
             symbol
         } else {
-            self.interned(self.gensyms[(!0 - symbol.0) as usize])
+            self.interned(self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize])
         }
     }
 
@@ -283,17 +307,17 @@
 
     fn gensymed(&mut self, symbol: Symbol) -> Symbol {
         self.gensyms.push(symbol);
-        Symbol(!0 - self.gensyms.len() as u32 + 1)
+        Symbol::new(SymbolIndex::MAX_AS_U32 - self.gensyms.len() as u32 + 1)
     }
 
     fn is_gensymed(&mut self, symbol: Symbol) -> bool {
-        symbol.0 as usize >= self.strings.len()
+        symbol.0.as_usize() >= self.strings.len()
     }
 
     pub fn get(&self, symbol: Symbol) -> &str {
-        match self.strings.get(symbol.0 as usize) {
+        match self.strings.get(symbol.0.as_usize()) {
             Some(string) => string,
-            None => self.get(self.gensyms[(!0 - symbol.0) as usize]),
+            None => self.get(self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize]),
         }
     }
 }
@@ -317,7 +341,7 @@
         $(
             #[allow(non_upper_case_globals)]
             pub const $konst: Keyword = Keyword {
-                ident: Ident::with_empty_ctxt(super::Symbol($index))
+                ident: Ident::with_empty_ctxt(super::Symbol::new($index))
             };
         )*
 
@@ -340,7 +364,7 @@
     }
 }}
 
-// NB: leaving holes in the ident table is bad! a different ident will get
+// N.B., leaving holes in the ident table is bad! a different ident will get
 // interned with the id from the hole, but it will be between the min and max
 // of the reserved words, and thus tagged as "reserved".
 // After modifying this list adjust `is_special`, `is_used_keyword`/`is_unused_keyword`,
@@ -349,11 +373,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 +402,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 +415,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 +428,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,18 +443,22 @@
     (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()
     }
 }
 
 impl Ident {
-    // Returns true for reserved identifiers used internally for elided lifetimes,
+    // Returns `true` for reserved identifiers used internally for elided lifetimes,
     // unnamed method parameters, crate root module, error recovery etc.
     pub fn is_special(self) -> bool {
         self.name <= keywords::Underscore.name()
@@ -436,7 +466,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 +486,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()
     }
 }
@@ -479,8 +511,8 @@
 /// Represents a string stored in the interner. Because the interner outlives any thread
 /// which uses this type, we can safely treat `string` which points to interner data,
 /// as an immortal string, as long as this type never crosses between threads.
-// FIXME: Ensure that the interner outlives any thread which uses LocalInternedString,
-//        by creating a new thread right after constructing the interner
+// FIXME: ensure that the interner outlives any thread which uses `LocalInternedString`,
+// by creating a new thread right after constructing the interner.
 #[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)]
 pub struct LocalInternedString {
     string: &'static str,
@@ -569,7 +601,7 @@
     }
 }
 
-/// Represents a string stored in the string interner
+/// Represents a string stored in the string interner.
 #[derive(Clone, Copy, Eq)]
 pub struct InternedString {
     symbol: Symbol,
@@ -694,19 +726,19 @@
     fn interner_tests() {
         let mut i: Interner = Interner::default();
         // first one is zero:
-        assert_eq!(i.intern("dog"), Symbol(0));
+        assert_eq!(i.intern("dog"), Symbol::new(0));
         // re-use gets the same entry:
-        assert_eq!(i.intern("dog"), Symbol(0));
+        assert_eq!(i.intern("dog"), Symbol::new(0));
         // different string gets a different #:
-        assert_eq!(i.intern("cat"), Symbol(1));
-        assert_eq!(i.intern("cat"), Symbol(1));
+        assert_eq!(i.intern("cat"), Symbol::new(1));
+        assert_eq!(i.intern("cat"), Symbol::new(1));
         // dog is still at zero
-        assert_eq!(i.intern("dog"), Symbol(0));
-        assert_eq!(i.gensym("zebra"), Symbol(4294967295));
-        // gensym of same string gets new number :
-        assert_eq!(i.gensym("zebra"), Symbol(4294967294));
+        assert_eq!(i.intern("dog"), Symbol::new(0));
+        assert_eq!(i.gensym("zebra"), Symbol::new(SymbolIndex::MAX_AS_U32));
+        // gensym of same string gets new number:
+        assert_eq!(i.gensym("zebra"), Symbol::new(SymbolIndex::MAX_AS_U32 - 1));
         // gensym of *existing* string gets new number:
-        assert_eq!(i.gensym("dog"), Symbol(4294967293));
+        assert_eq!(i.gensym("dog"), Symbol::new(SymbolIndex::MAX_AS_U32 - 2));
     }
 
     #[test]
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 5ac46c2..b28e62f 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -198,7 +198,7 @@
     /// *Note: This does not flush.*
     ///
     /// That means the reset command may get buffered so, if you aren't planning on doing anything
-    /// else that might flush stdout's buffer (e.g. writing a line of text), you should flush after
+    /// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
     /// calling reset.
     fn reset(&mut self) -> io::Result<bool>;
 
diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs
index 492d26e..426dc4d 100644
--- a/src/libterm/terminfo/searcher.rs
+++ b/src/libterm/terminfo/searcher.rs
@@ -64,7 +64,7 @@
             p.pop();
 
             // on some installations the dir is named after the hex of the char
-            // (e.g. macOS)
+            // (e.g., macOS)
             p.push(&format!("{:x}", first_char as usize));
             p.push(term);
             if fs::metadata(&p).is_ok() {
@@ -79,7 +79,7 @@
 #[ignore(reason = "buildbots don't have ncurses installed and I can't mock everything I need")]
 fn test_get_dbpath_for_term() {
     // woefully inadequate test coverage
-    // note: current tests won't work with non-standard terminfo hierarchies (e.g. macOS's)
+    // note: current tests won't work with non-standard terminfo hierarchies (e.g., macOS's)
     use std::env;
     // FIXME (#9639): This needs to handle non-utf8 paths
     fn x(t: &str) -> String {
diff --git a/src/libtest/formatters/terse.rs b/src/libtest/formatters/terse.rs
index 6f7dfee..cf15c89 100644
--- a/src/libtest/formatters/terse.rs
+++ b/src/libtest/formatters/terse.rs
@@ -66,7 +66,7 @@
         self.write_pretty(result, color)?;
         if self.test_count % QUIET_MODE_MAX_COLUMN == QUIET_MODE_MAX_COLUMN - 1 {
             // we insert a new line every 100 dots in order to flush the
-            // screen when dealing with line-buffered output (e.g. piping to
+            // screen when dealing with line-buffered output (e.g., piping to
             // `stamp` in the rust CI).
             let out = format!(" {}/{}\n", self.test_count+1, self.total_test_count);
             self.write_plain(&out)?;
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 7c26d04..1c87349 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -23,7 +23,7 @@
 // running tests while providing a base that other test frameworks may
 // build off of.
 
-// NB: this is also specified in this crate's Cargo.toml, but libsyntax contains logic specific to
+// N.B., this is also specified in this crate's Cargo.toml, but libsyntax contains logic specific to
 // this crate, which relies on this attribute (rather than the value of `--crate-name` passed by
 // cargo) to detect this crate.
 
@@ -99,8 +99,12 @@
 
 use formatters::{JsonFormatter, OutputFormatter, PrettyFormatter, TerseFormatter};
 
+/// Whether to execute tests concurrently or not
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum Concurrent { Yes, No }
+
 // The name of a test. By convention this follows the rules for rust
-// paths; i.e. it should be a series of identifiers separated by double
+// paths; i.e., it should be a series of identifiers separated by double
 // colons. This way if some test runner wants to arrange the tests
 // hierarchically it may.
 
@@ -515,7 +519,7 @@
 
 // FIXME: Copied from libsyntax until linkage errors are resolved. Issue #47566
 fn is_nightly() -> bool {
-    // Whether this is a feature-staged build, i.e. on the beta or stable channel
+    // Whether this is a feature-staged build, i.e., on the beta or stable channel
     let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
     // Whether we should enable unstable features for bootstrapping
     let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok();
@@ -1018,10 +1022,12 @@
     }
 }
 
-#[cfg(any(target_os = "cloudabi", target_os = "redox",
-          all(target_arch = "wasm32", not(target_os = "emscripten"))))]
+#[cfg(any(target_os = "cloudabi",
+          target_os = "redox",
+          all(target_arch = "wasm32", not(target_os = "emscripten")),
+          target_env = "sgx"))]
 fn stdout_isatty() -> bool {
-    // FIXME: Implement isatty on Redox
+    // FIXME: Implement isatty on Redox and SGX
     false
 }
 #[cfg(unix)]
@@ -1071,8 +1077,12 @@
 where
     F: FnMut(TestEvent) -> io::Result<()>,
 {
-    use std::collections::HashMap;
+    use std::collections::{self, HashMap};
+    use std::hash::BuildHasherDefault;
     use std::sync::mpsc::RecvTimeoutError;
+    // Use a deterministic hasher
+    type TestMap =
+        HashMap<TestDesc, Instant, BuildHasherDefault<collections::hash_map::DefaultHasher>>;
 
     let tests_len = tests.len();
 
@@ -1111,9 +1121,9 @@
 
     let (tx, rx) = channel::<MonitorMsg>();
 
-    let mut running_tests: HashMap<TestDesc, Instant> = HashMap::new();
+    let mut running_tests: TestMap = HashMap::default();
 
-    fn get_timed_out_tests(running_tests: &mut HashMap<TestDesc, Instant>) -> Vec<TestDesc> {
+    fn get_timed_out_tests(running_tests: &mut TestMap) -> Vec<TestDesc> {
         let now = Instant::now();
         let timed_out = running_tests
             .iter()
@@ -1131,7 +1141,7 @@
         timed_out
     };
 
-    fn calc_timeout(running_tests: &HashMap<TestDesc, Instant>) -> Option<Duration> {
+    fn calc_timeout(running_tests: &TestMap) -> Option<Duration> {
         running_tests.values().min().map(|next_timeout| {
             let now = Instant::now();
             if *next_timeout >= now {
@@ -1146,7 +1156,7 @@
         while !remaining.is_empty() {
             let test = remaining.pop().unwrap();
             callback(TeWait(test.desc.clone()))?;
-            run_test(opts, !opts.run_tests, test, tx.clone());
+            run_test(opts, !opts.run_tests, test, tx.clone(), Concurrent::No);
             let (test, result, stdout) = rx.recv().unwrap();
             callback(TeResult(test, result, stdout))?;
         }
@@ -1157,7 +1167,7 @@
                 let timeout = Instant::now() + Duration::from_secs(TEST_WARN_TIMEOUT_S);
                 running_tests.insert(test.desc.clone(), timeout);
                 callback(TeWait(test.desc.clone()))?; //here no pad
-                run_test(opts, !opts.run_tests, test, tx.clone());
+                run_test(opts, !opts.run_tests, test, tx.clone(), Concurrent::Yes);
                 pending += 1;
             }
 
@@ -1189,7 +1199,7 @@
         // All benchmarks run at the end, in serial.
         for b in filtered_benchs {
             callback(TeWait(b.desc.clone()))?;
-            run_test(opts, false, b, tx.clone());
+            run_test(opts, false, b, tx.clone(), Concurrent::No);
             let (test, result, stdout) = rx.recv().unwrap();
             callback(TeResult(test, result, stdout))?;
         }
@@ -1246,7 +1256,7 @@
         1
     }
 
-    #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
+    #[cfg(any(all(target_arch = "wasm32", not(target_os = "emscripten")), target_env = "sgx"))]
     fn num_cpus() -> usize {
         1
     }
@@ -1391,6 +1401,7 @@
     force_ignore: bool,
     test: TestDescAndFn,
     monitor_ch: Sender<MonitorMsg>,
+    concurrency: Concurrent,
 ) {
     let TestDescAndFn { desc, testfn } = test;
 
@@ -1407,6 +1418,7 @@
         monitor_ch: Sender<MonitorMsg>,
         nocapture: bool,
         testfn: Box<dyn FnBox() + Send>,
+        concurrency: Concurrent,
     ) {
         // Buffer for capturing standard I/O
         let data = Arc::new(Mutex::new(Vec::new()));
@@ -1441,7 +1453,7 @@
         // the test synchronously, regardless of the concurrency
         // level.
         let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_arch = "wasm32");
-        if supports_threads {
+        if concurrency == Concurrent::Yes && supports_threads {
             let cfg = thread::Builder::new().name(name.as_slice().to_owned());
             cfg.spawn(runtest).unwrap();
         } else {
@@ -1462,13 +1474,14 @@
         }
         DynTestFn(f) => {
             let cb = move || __rust_begin_short_backtrace(f);
-            run_test_inner(desc, monitor_ch, opts.nocapture, Box::new(cb))
+            run_test_inner(desc, monitor_ch, opts.nocapture, Box::new(cb), concurrency)
         }
         StaticTestFn(f) => run_test_inner(
             desc,
             monitor_ch,
             opts.nocapture,
             Box::new(move || __rust_begin_short_backtrace(f)),
+            concurrency,
         ),
     }
 }
@@ -1612,7 +1625,7 @@
     // be left doing 0 iterations on every loop. The unfortunate
     // side effect of not being able to do as many runs is
     // automatically handled by the statistical analysis below
-    // (i.e. larger error bars).
+    // (i.e., larger error bars).
     n = cmp::max(1, n);
 
     let mut total_run = Duration::new(0, 0);
@@ -1751,6 +1764,7 @@
     use std::sync::mpsc::channel;
     use bench;
     use Bencher;
+    use Concurrent;
 
 
     fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
@@ -1791,7 +1805,7 @@
             testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
-        run_test(&TestOpts::new(), false, desc, tx);
+        run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
         let (_, res, _) = rx.recv().unwrap();
         assert!(res != TrOk);
     }
@@ -1809,7 +1823,7 @@
             testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
-        run_test(&TestOpts::new(), false, desc, tx);
+        run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
         let (_, res, _) = rx.recv().unwrap();
         assert!(res == TrIgnored);
     }
@@ -1829,7 +1843,7 @@
             testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
-        run_test(&TestOpts::new(), false, desc, tx);
+        run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
         let (_, res, _) = rx.recv().unwrap();
         assert!(res == TrOk);
     }
@@ -1849,7 +1863,7 @@
             testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
-        run_test(&TestOpts::new(), false, desc, tx);
+        run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
         let (_, res, _) = rx.recv().unwrap();
         assert!(res == TrOk);
     }
@@ -1871,7 +1885,7 @@
             testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
-        run_test(&TestOpts::new(), false, desc, tx);
+        run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
         let (_, res, _) = rx.recv().unwrap();
         assert!(res == TrFailedMsg(format!("{} '{}'", failed_msg, expected)));
     }
@@ -1889,7 +1903,7 @@
             testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
-        run_test(&TestOpts::new(), false, desc, tx);
+        run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
         let (_, res, _) = rx.recv().unwrap();
         assert!(res == TrFailed);
     }
diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs
index 9a87497..1fad612 100644
--- a/src/libtest/stats.rs
+++ b/src/libtest/stats.rs
@@ -224,7 +224,7 @@
                 let x = *s - mean;
                 v = v + x * x;
             }
-            // NB: this is _supposed to be_ len-1, not len. If you
+            // N.B., this is _supposed to be_ len-1, not len. If you
             // change it back to len, you will be calculating a
             // population variance, not a sample variance.
             let denom = (self.len() - 1) as f64;
diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml
index 4760461..2577d6d 100644
--- a/src/libunwind/Cargo.toml
+++ b/src/libunwind/Cargo.toml
@@ -13,5 +13,5 @@
 
 [dependencies]
 core = { path = "../libcore" }
-libc = { path = "../rustc/libc_shim" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
+libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false }
+compiler_builtins = "0.1.0"
diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs
index 954eb9d..eb53332 100644
--- a/src/libunwind/lib.rs
+++ b/src/libunwind/lib.rs
@@ -26,7 +26,10 @@
 cfg_if! {
     if #[cfg(target_env = "msvc")] {
         // no extra unwinder support needed
-    } else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] {
+    } else if #[cfg(any(
+        all(target_arch = "wasm32", not(target_os = "emscripten")),
+        target_env = "sgx"
+    ))] {
         // no unwinder on the system!
     } else {
         extern crate libc;
diff --git a/src/rtstartup/rsbegin.rs b/src/rtstartup/rsbegin.rs
index 8ff4011..4ec0857 100644
--- a/src/rtstartup/rsbegin.rs
+++ b/src/rtstartup/rsbegin.rs
@@ -96,7 +96,7 @@
     pub mod ms_init {
         // .CRT$X?? sections are roughly analogous to ELF's .init_array and .fini_array,
         // except that they exploit the fact that linker will sort them alphabitically,
-        // so e.g. sections with names between .CRT$XIA and .CRT$XIZ are guaranteed to be
+        // so e.g., sections with names between .CRT$XIA and .CRT$XIZ are guaranteed to be
         // placed between those two, without requiring any ordering of objects on the linker
         // command line.
         // Note that ordering of same-named sections from different objects is not guaranteed.
diff --git a/src/rustc/compiler_builtins_shim/Cargo.toml b/src/rustc/compiler_builtins_shim/Cargo.toml
deleted file mode 100644
index 9804177..0000000
--- a/src/rustc/compiler_builtins_shim/Cargo.toml
+++ /dev/null
@@ -1,40 +0,0 @@
-[package]
-name = "compiler_builtins"
-authors = ["The Rust Project Developers"]
-version = "0.0.0"
-build = "../../libcompiler_builtins/build.rs"
-
-[lib]
-path = "../../libcompiler_builtins/src/lib.rs"
-test = false
-doctest = false
-
-[dependencies]
-# Specify the path to libcore; at the time of writing, removing this shim in
-# favor of using compiler-builtins from git results in a compilation failure:
-#
-# Building stage0 std artifacts (x86_64-apple-darwin -> x86_64-apple-darwin)
-#    Compiling compiler_builtins v0.1.0 (https://github.com/rust-lang-nursery/compiler-builtins.git#23f14d3f)
-# error[E0463]: can't find crate for `core`
-#
-# error: aborting due to previous error
-#
-# error: Could not compile `compiler_builtins`.
-#
-# Caused by:
-#   process didn't exit successfully: `/Users/tamird/src/rust/build/bootstrap/debug/rustc --crate-name compiler_builtins /Users/tamird/.cargo/git/checkouts/compiler-builtins-ec094dc45a0179c8/23f14d3/src/lib.rs --error-format json --crate-type lib --emit=dep-info,link -C opt-level=2 --cfg feature="c" --cfg feature="compiler-builtins" --cfg feature="default" --cfg feature="gcc" -C metadata=876d429e8d7eae1f -C extra-filename=-876d429e8d7eae1f --out-dir /Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/x86_64-apple-darwin/release/deps --target x86_64-apple-darwin -L dependency=/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/x86_64-apple-darwin/release/deps -L dependency=/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/release/deps --cap-lints allow -L native=/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/x86_64-apple-darwin/release/build/compiler_builtins-f18fab55928102ad/out -l static=compiler-rt` (exit code: 101)
-# thread 'main' panicked at 'command did not execute successfully: "/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0/bin/cargo" "build" "-j" "4" "--target" "x86_64-apple-darwin" "--release" "--features" "panic-unwind jemalloc backtrace" "--manifest-path" "/Users/tamird/src/rust/src/libstd/Cargo.toml" "--message-format" "json"
-# expected success, got: exit code: 101', src/bootstrap/compile.rs:883:8
-#
-# See https://github.com/rust-lang/rfcs/pull/1133.
-core = { path = "../../libcore" }
-
-[build-dependencies]
-cc = "1.0.1"
-
-[features]
-c = []
-default = ["rustbuild", "compiler-builtins"]
-mem = []
-rustbuild = []
-compiler-builtins = []
diff --git a/src/rustc/compiler_builtins_shim/build.rs b/src/rustc/compiler_builtins_shim/build.rs
deleted file mode 100644
index b37543e..0000000
--- a/src/rustc/compiler_builtins_shim/build.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file is left intentionally empty (and not removed) to avoid an issue
-// where this crate is always considered dirty due to compiler-builtins'
-// `cargo:rerun-if-changed=build.rs` directive; since the path is relative, it
-// refers to this file when this shim crate is being built, and the absence of
-// this file is considered by cargo to be equivalent to it having changed.
diff --git a/src/rustc/dlmalloc_shim/Cargo.toml b/src/rustc/dlmalloc_shim/Cargo.toml
deleted file mode 100644
index b6f8550..0000000
--- a/src/rustc/dlmalloc_shim/Cargo.toml
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-name = "dlmalloc"
-version = "0.0.0"
-authors = ["The Rust Project Developers"]
-
-[lib]
-path = "../../dlmalloc/src/lib.rs"
-test = false
-bench = false
-doc = false
-
-[dependencies]
-core = { path = "../../libcore" }
-compiler_builtins = { path = "../../rustc/compiler_builtins_shim" }
diff --git a/src/rustc/libc_shim/Cargo.toml b/src/rustc/libc_shim/Cargo.toml
deleted file mode 100644
index ee037ac..0000000
--- a/src/rustc/libc_shim/Cargo.toml
+++ /dev/null
@@ -1,40 +0,0 @@
-[package]
-name = "libc"
-version = "0.0.0"
-authors = ["The Rust Project Developers"]
-
-[lib]
-name = "libc"
-path = "../../liblibc/src/lib.rs"
-test = false
-bench = false
-doc = false
-
-[dependencies]
-# Specify the path to libcore; at the time of writing, removing this shim in
-# favor of using libc from git results in a compilation failure:
-#
-# Building stage0 std artifacts (x86_64-apple-darwin -> x86_64-apple-darwin)
-#    Compiling libc v0.0.0 (file:///Users/tamird/src/rust/src/rustc/libc_shim)
-# error[E0463]: can't find crate for `core`
-#
-# error: aborting due to previous error
-#
-# error: Could not compile `libc`.
-#
-# Caused by:
-#   process didn't exit successfully: `/Users/tamird/src/rust/build/bootstrap/debug/rustc --crate-name libc src/rustc/libc_shim/../../liblibc/src/lib.rs --error-format json --crate-type lib --emit=dep-info,link -C opt-level=2 --cfg feature="default" --cfg feature="no_std" --cfg feature="stdbuild" -C metadata=d758f87058112d7d -C extra-filename=-d758f87058112d7d --out-dir /Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/x86_64-apple-darwin/release/deps --target x86_64-apple-darwin -L dependency=/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/x86_64-apple-darwin/release/deps -L dependency=/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/release/deps` (exit code: 101)
-# thread 'main' panicked at 'command did not execute successfully: "/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0/bin/cargo" "build" "-j" "4" "--target" "x86_64-apple-darwin" "--release" "--features" "panic-unwind jemalloc backtrace" "--manifest-path" "/Users/tamird/src/rust/src/libstd/Cargo.toml" "--message-format" "json"
-# expected success, got: exit code: 101', src/bootstrap/compile.rs:883:8
-#
-# See https://github.com/rust-lang/rfcs/pull/1133.
-core = { path = "../../libcore" }
-compiler_builtins = { path = "../compiler_builtins_shim" }
-
-
-[features]
-# Certain parts of libc are conditionally compiled differently than when used
-# outside rustc. See https://github.com/rust-lang/libc/search?l=Rust&q=stdbuild&type=&utf8=%E2%9C%93.
-stdbuild = []
-default = ["stdbuild", "align"]
-align = []
diff --git a/src/stage0.txt b/src/stage0.txt
index 9326e22..843ecae 100644
--- a/src/stage0.txt
+++ b/src/stage0.txt
@@ -12,7 +12,7 @@
 # source tarball for a stable release you'll likely see `1.x.0` for rustc and
 # `0.x.0` for Cargo where they were released on `date`.
 
-date: 2018-10-30
+date: 2018-12-09
 rustc: beta
 cargo: beta
 
diff --git a/src/stdsimd b/src/stdsimd
index 0309be1..3c0503d 160000
--- a/src/stdsimd
+++ b/src/stdsimd
@@ -1 +1 @@
-Subproject commit 0309be1ade6bf61066f2c69f77ac3567b7dc31b5
+Subproject commit 3c0503db8439928e42c1175f0009c506fc874ae9
diff --git a/src/test/codegen-units/item-collection/unreferenced-inline-function.rs b/src/test/codegen-units/item-collection/unreferenced-inline-function.rs
index 829b4fb..28c1f0a 100644
--- a/src/test/codegen-units/item-collection/unreferenced-inline-function.rs
+++ b/src/test/codegen-units/item-collection/unreferenced-inline-function.rs
@@ -11,7 +11,7 @@
 // ignore-tidy-linelength
 // compile-flags:-Zprint-mono-items=lazy
 
-// NB: We do not expect *any* monomorphization to be generated here.
+// N.B., we do not expect *any* monomorphization to be generated here.
 
 #![deny(dead_code)]
 #![crate_type = "rlib"]
diff --git a/src/test/codegen/external-no-mangle-fns.rs b/src/test/codegen/external-no-mangle-fns.rs
index 5823285..e6b952e 100644
--- a/src/test/codegen/external-no-mangle-fns.rs
+++ b/src/test/codegen/external-no-mangle-fns.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // compile-flags: -C no-prepopulate-passes
-// `#[no_mangle]`d functions always have external linkage, i.e. no `internal` in their `define`s
+// `#[no_mangle]`d functions always have external linkage, i.e., no `internal` in their `define`s
 
 #![crate_type = "lib"]
 #![no_std]
diff --git a/src/test/codegen/external-no-mangle-statics.rs b/src/test/codegen/external-no-mangle-statics.rs
index 59d8296..b1488e3 100644
--- a/src/test/codegen/external-no-mangle-statics.rs
+++ b/src/test/codegen/external-no-mangle-statics.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // compile-flags: -O
-// `#[no_mangle]`d static variables always have external linkage, i.e. no `internal` in their
+// `#[no_mangle]`d static variables always have external linkage, i.e., no `internal` in their
 // definitions
 
 #![crate_type = "lib"]
diff --git a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs b/src/test/codegen/nounwind-extern.rs
similarity index 78%
rename from src/test/ui/feature-gate-exhaustive_integer_patterns.rs
rename to src/test/codegen/nounwind-extern.rs
index 3aa1522..ed07cf1 100644
--- a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs
+++ b/src/test/codegen/nounwind-extern.rs
@@ -8,9 +8,9 @@
 // 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 => {}
-    }
-}
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// CHECK: Function Attrs: norecurse nounwind
+pub extern fn foo() {}
diff --git a/src/test/codegen/simd-intrinsic-generic-select.rs b/src/test/codegen/simd-intrinsic-generic-select.rs
index 8a64d74..24a4b2b 100644
--- a/src/test/codegen/simd-intrinsic-generic-select.rs
+++ b/src/test/codegen/simd-intrinsic-generic-select.rs
@@ -21,10 +21,15 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
+pub struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub struct b8x4(pub i8, pub i8, pub i8, pub i8);
 
 extern "platform-intrinsic" {
     fn simd_select<T, U>(x: T, a: U, b: U) -> U;
+    fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
 }
 
 // CHECK-LABEL: @select
@@ -33,3 +38,10 @@
     // CHECK: select <4 x i1>
     simd_select(m, a, b)
 }
+
+// CHECK-LABEL: @select_bitmask
+#[no_mangle]
+pub unsafe fn select_bitmask(m: i8, a: f32x8, b: f32x8) -> f32x8 {
+    // CHECK: select <8 x i1>
+    simd_select_bitmask(m, a, b)
+}
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
deleted file mode 100644
index f697642..0000000
--- a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
+++ /dev/null
@@ -1,51 +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.
-
-// force-host
-
-#![feature(plugin_registrar)]
-#![feature(box_syntax, rustc_private)]
-
-// Load rustc as a plugin to get macros
-#[macro_use]
-extern crate rustc;
-extern crate rustc_plugin;
-
-use rustc::hir;
-use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray};
-use rustc_plugin::Registry;
-
-declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
-
-declare_lint!(PLEASE_LINT, Warn, "Warn about items named 'pleaselintme'");
-
-struct Pass;
-
-impl LintPass for Pass {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(TEST_LINT, PLEASE_LINT)
-    }
-}
-
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
-    fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
-        match &*it.name.as_str() {
-            "lintme" => cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"),
-            "pleaselintme" => cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'"),
-            _ => {}
-        }
-    }
-}
-
-#[plugin_registrar]
-pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_late_lint_pass(box Pass);
-    reg.register_lint_group("lint_me", None, vec![TEST_LINT, PLEASE_LINT]);
-}
diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs
deleted file mode 100644
index 8647797..0000000
--- a/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs
+++ /dev/null
@@ -1,48 +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.
-
-// force-host
-
-#![feature(plugin_registrar)]
-#![feature(box_syntax, rustc_private)]
-
-extern crate syntax;
-
-// Load rustc as a plugin to get macros
-#[macro_use]
-extern crate rustc;
-extern crate rustc_plugin;
-
-use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass,
-                  EarlyLintPassObject, LintArray};
-use rustc_plugin::Registry;
-use syntax::ast;
-declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
-
-struct Pass;
-
-impl LintPass for Pass {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(TEST_LINT)
-    }
-}
-
-impl EarlyLintPass for Pass {
-    fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
-        if it.ident.name == "lintme" {
-            cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
-        }
-    }
-}
-
-#[plugin_registrar]
-pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_early_lint_pass(box Pass as EarlyLintPassObject);
-}
diff --git a/src/test/compile-fail-fulldeps/auxiliary/macro_reexport_1.rs b/src/test/compile-fail-fulldeps/auxiliary/macro_reexport_1.rs
deleted file mode 100644
index aaeccc6..0000000
--- a/src/test/compile-fail-fulldeps/auxiliary/macro_reexport_1.rs
+++ /dev/null
@@ -1,15 +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.
-
-#![crate_type = "dylib"]
-#[macro_export]
-macro_rules! reexported {
-    () => ( 3 )
-}
diff --git a/src/test/compile-fail/issue-10755.rs b/src/test/compile-fail/issue-10755.rs
index 57915bc..bb77748 100644
--- a/src/test/compile-fail/issue-10755.rs
+++ b/src/test/compile-fail/issue-10755.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -C linker=llllll -Z linker-flavor=ld
+// compile-flags: -C linker=llllll -C linker-flavor=ld
 // error-pattern: linker `llllll` not found
 
 fn main() {
diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/compile-fail/must_use-in-stdlib-traits.rs
new file mode 100644
index 0000000..4bb5c59
--- /dev/null
+++ b/src/test/compile-fail/must_use-in-stdlib-traits.rs
@@ -0,0 +1,47 @@
+#![deny(unused_must_use)]
+#![feature(futures_api, pin, arbitrary_self_types)]
+
+use std::iter::Iterator;
+use std::future::Future;
+
+use std::task::{Poll, LocalWaker};
+use std::pin::Pin;
+use std::unimplemented;
+
+struct MyFuture;
+
+impl Future for MyFuture {
+   type Output = u32;
+
+   fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<u32> {
+      Poll::Pending
+   }
+}
+
+fn iterator() -> impl Iterator {
+   std::iter::empty::<u32>()
+}
+
+fn future() -> impl Future {
+   MyFuture
+}
+
+fn square_fn_once() -> impl FnOnce(u32) -> u32 {
+   |x| x * x
+}
+
+fn square_fn_mut() -> impl FnMut(u32) -> u32 {
+   |x| x * x
+}
+
+fn square_fn() -> impl Fn(u32) -> u32 {
+   |x| x * x
+}
+
+fn main() {
+   iterator(); //~ ERROR unused implementer of `std::iter::Iterator` that must be used
+   future(); //~ ERROR unused implementer of `std::future::Future` that must be used
+   square_fn_once(); //~ ERROR unused implementer of `std::ops::FnOnce` that must be used
+   square_fn_mut(); //~ ERROR unused implementer of `std::ops::FnMut` that must be used
+   square_fn(); //~ ERROR unused implementer of `std::ops::Fn` that must be used
+}
diff --git a/src/test/compile-fail/nolink-with-link-args.rs b/src/test/compile-fail/nolink-with-link-args.rs
index 6dfd74f..95f827e 100644
--- a/src/test/compile-fail/nolink-with-link-args.rs
+++ b/src/test/compile-fail/nolink-with-link-args.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // error-pattern:aFdEfSeVEE
-// compile-flags: -Z linker-flavor=ld
+// compile-flags: -C linker-flavor=ld
 
 /* We're testing that link_args are indeed passed when nolink is specified.
 So we try to compile with junk link_args and make sure they are visible in
diff --git a/src/test/compile-fail/proc-macro/auxiliary/derive-clona.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-clona.rs
deleted file mode 100644
index 719fbdb..0000000
--- a/src/test/compile-fail/proc-macro/auxiliary/derive-clona.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_derive(Clona)]
-pub fn derive_clonea(input: TokenStream) -> TokenStream {
-    "".parse().unwrap()
-}
diff --git a/src/test/compile-fail/proc-macro/auxiliary/derive-foo.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-foo.rs
deleted file mode 100644
index 64dcf72..0000000
--- a/src/test/compile-fail/proc-macro/auxiliary/derive-foo.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_derive(FooWithLongName)]
-pub fn derive_foo(input: TokenStream) -> TokenStream {
-    "".parse().unwrap()
-}
diff --git a/src/test/debuginfo/function-call.rs b/src/test/debuginfo/function-call.rs
new file mode 100644
index 0000000..266e536
--- /dev/null
+++ b/src/test/debuginfo/function-call.rs
@@ -0,0 +1,52 @@
+// 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.
+
+// This test does not passed with gdb < 8.0. See #53497.
+// min-gdb-version 8.0
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+
+// gdb-command:print fun(45, true)
+// gdb-check:$1 = true
+// gdb-command:print fun(444, false)
+// gdb-check:$2 = false
+
+// gdb-command:print r.get_x()
+// gdb-check:$3 = 4
+
+#![allow(dead_code, unused_variables)]
+
+struct RegularStruct {
+    x: i32
+}
+
+impl RegularStruct {
+    fn get_x(&self) -> i32 {
+        self.x
+    }
+}
+
+fn main() {
+    let _ = fun(4, true);
+    let r = RegularStruct{x: 4};
+    let _ = r.get_x();
+
+    zzz(); // #break
+}
+
+fn fun(x: isize, y: bool) -> bool {
+    y
+}
+
+fn zzz() { () }
diff --git a/src/test/debuginfo/pretty-std-collections.rs b/src/test/debuginfo/pretty-std-collections.rs
index a51be37..350b30d 100644
--- a/src/test/debuginfo/pretty-std-collections.rs
+++ b/src/test/debuginfo/pretty-std-collections.rs
@@ -13,7 +13,11 @@
 // ignore-freebsd: gdb package too new
 // ignore-android: FIXME(#10381)
 // compile-flags:-g
-// min-gdb-version 7.7
+
+// The pretty printers being tested here require the patch from
+// https://sourceware.org/bugzilla/show_bug.cgi?id=21763
+// min-gdb-version 8.1
+
 // min-lldb-version: 310
 
 // === GDB TESTS ===================================================================================
diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs
index 3ec8b04..8b4b10a 100644
--- a/src/test/debuginfo/type-names.rs
+++ b/src/test/debuginfo/type-names.rs
@@ -280,7 +280,7 @@
 }
 
 // In many of the cases below, the type that is actually under test is wrapped
-// in a tuple, e.g. Box<T>, references, raw pointers, fixed-size vectors, ...
+// in a tuple, e.g., Box<T>, references, raw pointers, fixed-size vectors, ...
 // This is because GDB will not print the type name from DWARF debuginfo for
 // some kinds of types (pointers, arrays, functions, ...)
 // Since tuples are structs as far as GDB is concerned, their name will be
diff --git a/src/test/incremental/foreign.rs b/src/test/incremental/foreign.rs
index dbdebef..648e89b 100644
--- a/src/test/incremental/foreign.rs
+++ b/src/test/incremental/foreign.rs
@@ -13,7 +13,7 @@
 
 // revisions: rpass1
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/incremental/hashes/panic_exprs.rs b/src/test/incremental/hashes/panic_exprs.rs
index ffb66c2..f2d610c 100644
--- a/src/test/incremental/hashes/panic_exprs.rs
+++ b/src/test/incremental/hashes/panic_exprs.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // This test case tests the incremental compilation hash (ICH) implementation
-// for exprs that can panic at runtime (e.g. because of bounds checking). For
+// for exprs that can panic at runtime (e.g., because of bounds checking). For
 // these expressions an error message containing their source location is
 // generated, so their hash must always depend on their location in the source
 // code, not just when debuginfo is enabled.
diff --git a/src/test/incremental/hashes/struct_defs.rs b/src/test/incremental/hashes/struct_defs.rs
index 10b1beb..06842e3 100644
--- a/src/test/incremental/hashes/struct_defs.rs
+++ b/src/test/incremental/hashes/struct_defs.rs
@@ -340,7 +340,7 @@
 
 // Empty struct ----------------------------------------------------------------
 // Since we cannot change anything in this case, we just make sure that the
-// fingerprint is stable (i.e. that there are no random influences like memory
+// fingerprint is stable (i.e., that there are no random influences like memory
 // addresses taken into account by the hashing algorithm).
 // Note: there is no #[cfg(...)], so this is ALWAYS compiled
 #[rustc_clean(label="Hir", cfg="cfail2")]
diff --git a/src/test/pretty/block-disambig.rs b/src/test/pretty/block-disambig.rs
index c645a66..aed34bf 100644
--- a/src/test/pretty/block-disambig.rs
+++ b/src/test/pretty/block-disambig.rs
@@ -11,7 +11,7 @@
 // compile-flags: --crate-type=lib
 
 // A bunch of tests for syntactic forms involving blocks that were
-// previously ambiguous (e.g. 'if true { } *val;' gets parsed as a
+// previously ambiguous (e.g., 'if true { } *val;' gets parsed as a
 // binop)
 
 
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
index 90ad601..0254c7c 100644
--- 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
@@ -10,7 +10,7 @@
 
 #![crate_type = "staticlib"]
 #![feature(c_variadic)]
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
index 87d2026..3d3cb2c 100644
--- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
+++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
@@ -78,5 +78,5 @@
 /// This is the entrypoint for a hot plugged rustc_codegen_llvm
 #[no_mangle]
 pub fn __rustc_codegen_backend() -> Box<CodegenBackend> {
-    Box::new(TheBackend(MetadataOnlyCodegenBackend::new()))
+    Box::new(TheBackend(MetadataOnlyCodegenBackend::boxed()))
 }
diff --git a/src/test/run-make-fulldeps/issue-25581/test.rs b/src/test/run-make-fulldeps/issue-25581/test.rs
index 6717d16..b084092 100644
--- a/src/test/run-make-fulldeps/issue-25581/test.rs
+++ b/src/test/run-make-fulldeps/issue-25581/test.rs
@@ -8,14 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(libc)]
-
-extern crate libc;
-
 #[link(name = "test", kind = "static")]
 extern {
-    fn slice_len(s: &[u8]) -> libc::size_t;
-    fn slice_elem(s: &[u8], idx: libc::size_t) -> u8;
+    fn slice_len(s: &[u8]) -> usize;
+    fn slice_elem(s: &[u8], idx: usize) -> u8;
 }
 
 fn main() {
diff --git a/src/test/run-make-fulldeps/issue-26006/in/time/lib.rs b/src/test/run-make-fulldeps/issue-26006/in/time/lib.rs
index b1d07d5..1427250 100644
--- a/src/test/run-make-fulldeps/issue-26006/in/time/lib.rs
+++ b/src/test/run-make-fulldeps/issue-26006/in/time/lib.rs
@@ -7,7 +7,7 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-#![feature(libc)]
+#![feature(rustc_private)]
 extern crate libc;
 
 fn main(){}
diff --git a/src/test/run-make-fulldeps/libtest-json/output.json b/src/test/run-make-fulldeps/libtest-json/output.json
index d8169ec..2b831ea 100644
--- a/src/test/run-make-fulldeps/libtest-json/output.json
+++ b/src/test/run-make-fulldeps/libtest-json/output.json
@@ -2,7 +2,7 @@
 { "type": "test", "event": "started", "name": "a" }
 { "type": "test", "name": "a", "event": "ok" }
 { "type": "test", "event": "started", "name": "b" }
-{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'b' panicked at 'assertion failed: false', f.rs:18:5\nnote: Run with `RUST_BACKTRACE=1` for a backtrace.\n" }
+{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:18:5\nnote: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
 { "type": "test", "event": "started", "name": "c" }
 { "type": "test", "name": "c", "event": "ok" }
 { "type": "test", "event": "started", "name": "d" }
diff --git a/src/test/run-make-fulldeps/link-path-order/main.rs b/src/test/run-make-fulldeps/link-path-order/main.rs
index f3502e8..4d38dc8 100644
--- a/src/test/run-make-fulldeps/link-path-order/main.rs
+++ b/src/test/run-make-fulldeps/link-path-order/main.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-make-fulldeps/reproducible-build/reproducible-build.rs b/src/test/run-make-fulldeps/reproducible-build/reproducible-build.rs
index a040c0f..c8c8bb1 100644
--- a/src/test/run-make-fulldeps/reproducible-build/reproducible-build.rs
+++ b/src/test/run-make-fulldeps/reproducible-build/reproducible-build.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // This test case makes sure that two identical invocations of the compiler
-// (i.e. same code base, same compile-flags, same compiler-versions, etc.)
+// (i.e., same code base, same compile-flags, same compiler-versions, etc.)
 // produce the same output. In the past, symbol names of monomorphized functions
 // were not deterministic (which we want to avoid).
 //
diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk
index 3de358f..7939928 100644
--- a/src/test/run-make-fulldeps/tools.mk
+++ b/src/test/run-make-fulldeps/tools.mk
@@ -76,7 +76,7 @@
 # Extra flags needed to compile a working executable with the standard library
 ifdef IS_WINDOWS
 ifdef IS_MSVC
-	EXTRACFLAGS := ws2_32.lib userenv.lib shell32.lib advapi32.lib
+	EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib
 else
 	EXTRACFLAGS := -lws2_32 -luserenv
 endif
diff --git a/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs
index 449cd29..b8f9138 100644
--- a/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs
@@ -31,11 +31,11 @@
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_custom_derive(
+    reg.register_syntax_extension(
         Symbol::intern("derive_TotalSum"),
         MultiDecorator(box expand));
 
-    reg.register_custom_derive(
+    reg.register_syntax_extension(
         Symbol::intern("derive_Nothing"),
         MultiDecorator(box noop));
 }
diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs
index f4d3f2c..7a7dd96 100644
--- a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs
@@ -56,9 +56,9 @@
                 span: source_map::Span,
                 id: ast::NodeId) {
 
-        let item = match cx.tcx.hir.get(id) {
+        let item = match cx.tcx.hir().get(id) {
             Node::Item(item) => item,
-            _ => cx.tcx.hir.expect_item(cx.tcx.hir.get_parent(id)),
+            _ => cx.tcx.hir().expect_item(cx.tcx.hir().get_parent(id)),
         };
 
         if !attr::contains_name(&item.attrs, "whitelisted_attr") {
diff --git a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs
index 47f5f83..f986efb 100644
--- a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs
+++ b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs
@@ -10,11 +10,11 @@
 
 // aux-build:custom_derive_partial_eq.rs
 // ignore-stage1
-#![feature(plugin, custom_derive)]
+#![feature(plugin)]
 #![plugin(custom_derive_partial_eq)]
 #![allow(unused)]
 
-#[derive(CustomPartialEq)] // Check that this is not a stability error.
+#[derive_CustomPartialEq] // Check that this is not a stability error.
 enum E { V1, V2 }
 
 fn main() {}
diff --git a/src/test/run-pass-fulldeps/custom-derive-partial-eq.stderr b/src/test/run-pass-fulldeps/custom-derive-partial-eq.stderr
deleted file mode 100644
index ba956e4..0000000
--- a/src/test/run-pass-fulldeps/custom-derive-partial-eq.stderr
+++ /dev/null
@@ -1,6 +0,0 @@
-warning: `#[derive]` for custom traits is deprecated and will be removed in the future. Prefer using procedural macro custom derive.
-  --> $DIR/custom-derive-partial-eq.rs:17:10
-   |
-LL | #[derive(CustomPartialEq)] // Check that this is not a stability error.
-   |          ^^^^^^^^^^^^^^^
-
diff --git a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs
index e088f5e..374e15d 100644
--- a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs
+++ b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs
@@ -11,7 +11,7 @@
 // aux-build:custom_derive_plugin_attr.rs
 // ignore-stage1
 
-#![feature(plugin, custom_derive, rustc_attrs)]
+#![feature(plugin, rustc_attrs)]
 #![plugin(custom_derive_plugin_attr)]
 
 trait TotalSum {
diff --git a/src/test/run-pass-fulldeps/derive-totalsum.rs b/src/test/run-pass-fulldeps/derive-totalsum.rs
index 848b242..86f14ca 100644
--- a/src/test/run-pass-fulldeps/derive-totalsum.rs
+++ b/src/test/run-pass-fulldeps/derive-totalsum.rs
@@ -11,7 +11,7 @@
 // aux-build:custom_derive_plugin.rs
 // ignore-stage1
 
-#![feature(plugin, custom_derive)]
+#![feature(plugin)]
 #![plugin(custom_derive_plugin)]
 
 trait TotalSum {
@@ -32,14 +32,14 @@
     }
 }
 
-#[derive(TotalSum)]
+#[derive_TotalSum]
 struct Foo {
     seven: Seven,
     bar: Bar,
     baz: isize,
 }
 
-#[derive(TotalSum)]
+#[derive_TotalSum]
 struct Bar {
     quux: isize,
     bleh: isize,
diff --git a/src/test/run-pass-fulldeps/issue-40663.rs b/src/test/run-pass-fulldeps/issue-40663.rs
index 8633e90..a33e9cc 100644
--- a/src/test/run-pass-fulldeps/issue-40663.rs
+++ b/src/test/run-pass-fulldeps/issue-40663.rs
@@ -12,10 +12,12 @@
 // aux-build:custom_derive_plugin.rs
 // ignore-stage1
 
-#![feature(plugin, custom_derive)]
+#![feature(plugin)]
 #![plugin(custom_derive_plugin)]
 
-#[derive(Nothing, Nothing, Nothing)]
+#[derive_Nothing]
+#[derive_Nothing]
+#[derive_Nothing]
 struct S;
 
 fn main() {}
diff --git a/src/test/run-pass-valgrind/osx-frameworks.rs b/src/test/run-pass-valgrind/osx-frameworks.rs
index 468a20d..afa9374 100644
--- a/src/test/run-pass-valgrind/osx-frameworks.rs
+++ b/src/test/run-pass-valgrind/osx-frameworks.rs
@@ -11,7 +11,7 @@
 // no-prefer-dynamic
 // pretty-expanded FIXME #23616
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/abort-on-c-abi.rs b/src/test/run-pass/abort-on-c-abi.rs
index 17b2ee3..12b5b78 100644
--- a/src/test/run-pass/abort-on-c-abi.rs
+++ b/src/test/run-pass/abort-on-c-abi.rs
@@ -15,14 +15,11 @@
 // ignore-cloudabi no env and process
 // ignore-emscripten no processes
 
-#![feature(unwind_attributes)]
-
 use std::{env, panic};
 use std::io::prelude::*;
 use std::io;
 use std::process::{Command, Stdio};
 
-#[unwind(aborts)]
 extern "C" fn panic_in_ffi() {
     panic!("Test");
 }
diff --git a/src/test/run-pass/anon-extern-mod.rs b/src/test/run-pass/anon-extern-mod.rs
index 16ca7bc..daa2bd6 100644
--- a/src/test/run-pass/anon-extern-mod.rs
+++ b/src/test/run-pass/anon-extern-mod.rs
@@ -11,7 +11,7 @@
 // pretty-expanded FIXME #23616
 // ignore-wasm32-bare no libc to test ffi with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs b/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs
index 5091674..7a90a02 100644
--- a/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs
+++ b/src/test/run-pass/array-slice-vec/vec-macro-no-std.rs
@@ -12,7 +12,7 @@
 
 // ignore-emscripten no no_std executables
 
-#![feature(lang_items, start, libc, alloc)]
+#![feature(lang_items, start, rustc_private, alloc)]
 #![no_std]
 
 extern crate std as other;
diff --git a/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs
index 741ce35..6b464c5 100644
--- a/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs
+++ b/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![crate_name="anonexternmod"]
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs b/src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs
index cd36a8e..4d1acf3 100644
--- a/src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs
+++ b/src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs
@@ -10,7 +10,7 @@
 
 // Helper definition for test/run-pass/check-static-recursion-foreign.rs.
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 #![crate_name = "check_static_recursion_foreign_helper"]
 #![crate_type = "lib"]
diff --git a/src/test/run-pass/auxiliary/foreign_lib.rs b/src/test/run-pass/auxiliary/foreign_lib.rs
index cef3627..465feb8 100644
--- a/src/test/run-pass/auxiliary/foreign_lib.rs
+++ b/src/test/run-pass/auxiliary/foreign_lib.rs
@@ -10,7 +10,7 @@
 
 #![crate_name="foreign_lib"]
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 pub mod rustrt {
     extern crate libc;
diff --git a/src/test/run-pass/c-stack-as-value.rs b/src/test/run-pass/c-stack-as-value.rs
index df4989d..1f29a52 100644
--- a/src/test/run-pass/c-stack-as-value.rs
+++ b/src/test/run-pass/c-stack-as-value.rs
@@ -11,7 +11,7 @@
 // pretty-expanded FIXME #23616
 // ignore-wasm32-bare no libc to test ffi with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 mod rustrt {
     extern crate libc;
diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs
index 56a0437..7dd3b9a 100644
--- a/src/test/run-pass/c-stack-returning-int64.rs
+++ b/src/test/run-pass/c-stack-returning-int64.rs
@@ -10,7 +10,7 @@
 
 // ignore-wasm32-bare no libc to test with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/check-static-recursion-foreign.rs b/src/test/run-pass/check-static-recursion-foreign.rs
index a95870c..15f509a 100644
--- a/src/test/run-pass/check-static-recursion-foreign.rs
+++ b/src/test/run-pass/check-static-recursion-foreign.rs
@@ -16,7 +16,7 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(custom_attribute, libc)]
+#![feature(custom_attribute, rustc_private)]
 
 extern crate check_static_recursion_foreign_helper;
 extern crate libc;
diff --git a/src/test/run-pass/coerce/coerce-unify.rs b/src/test/run-pass/coerce/coerce-unify.rs
index 575d672..bfcdf5b 100644
--- a/src/test/run-pass/coerce/coerce-unify.rs
+++ b/src/test/run-pass/coerce/coerce-unify.rs
@@ -47,7 +47,7 @@
         check2!($b, $c);
         check2!($a, $c);
 
-        // Check the remaining cases, i.e. permutations of ($a, $b, $c).
+        // Check the remaining cases, i.e., permutations of ($a, $b, $c).
         check!($a, $b, $c);
         check!($a, $c, $b);
         check!($b, $a, $c);
diff --git a/src/test/run-pass/coerce/coerce-unsize-subtype.rs b/src/test/run-pass/coerce/coerce-unsize-subtype.rs
index 068b010..088d10f 100644
--- a/src/test/run-pass/coerce/coerce-unsize-subtype.rs
+++ b/src/test/run-pass/coerce/coerce-unsize-subtype.rs
@@ -32,7 +32,7 @@
 }
 
 // LUB-coercion (if-else/match/array) coerces `xs: &'b [&'static T: N]`
-// to a subtype of the LUB of `xs` and `ys` (i.e. `&'b [&'a T]`),
+// to a subtype of the LUB of `xs` and `ys` (i.e., `&'b [&'a T]`),
 // regardless of the order they appear (in if-else/match/array).
 fn long_and_short_lub1<'a, 'b, T>(xs: &'b [&'static T; 1], ys: &'b [&'a T]) {
     let _order1 = [xs, ys];
@@ -40,7 +40,7 @@
 }
 
 // LUB-coercion should also have the exact same effect when `&'b [&'a T; N]`
-// needs to be coerced, i.e. the resulting type is not &'b [&'static T], but
+// needs to be coerced, i.e., the resulting type is not &'b [&'static T], but
 // rather the `&'b [&'a T]` LUB.
 fn long_and_short_lub2<'a, 'b, T>(xs: &'b [&'static T], ys: &'b [&'a T; 1]) {
     let _order1 = [xs, ys];
diff --git a/src/test/run-pass/command-before-exec.rs b/src/test/run-pass/command-before-exec.rs
index 5d8bc31..b78fa84 100644
--- a/src/test/run-pass/command-before-exec.rs
+++ b/src/test/run-pass/command-before-exec.rs
@@ -13,7 +13,7 @@
 // ignore-cloudabi no processes
 // ignore-emscripten no processes
 
-#![feature(process_exec, libc)]
+#![feature(process_exec, rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
index 741ce35..6b464c5 100644
--- a/src/test/run-pass/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
+++ b/src/test/run-pass/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![crate_name="anonexternmod"]
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs
index aaf017c..9023326 100644
--- a/src/test/run-pass/core-run-destroy.rs
+++ b/src/test/run-pass/core-run-destroy.rs
@@ -16,11 +16,11 @@
 // ignore-cloudabi no processes
 // ignore-emscripten no processes
 
-// NB: These tests kill child processes. Valgrind sees these children as leaking
+// N.B., these tests kill child processes. Valgrind sees these children as leaking
 // memory, which makes for some *confusing* logs. That's why these are here
 // instead of in std.
 
-#![feature(libc, duration)]
+#![feature(rustc_private, duration)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
index 741ce35..6b464c5 100644
--- a/src/test/run-pass/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
+++ b/src/test/run-pass/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![crate_name="anonexternmod"]
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/ctfe/references.rs b/src/test/run-pass/ctfe/references.rs
index 946ed24..421f354 100644
--- a/src/test/run-pass/ctfe/references.rs
+++ b/src/test/run-pass/ctfe/references.rs
@@ -28,6 +28,7 @@
         _ => panic!("c"),
     }
 
+    #[allow(unreachable_patterns)]
     match &43 {
         &42 => panic!(),
         BOO => panic!(),
diff --git a/src/test/run-pass/drop/dropck-eyepatch.rs b/src/test/run-pass/drop/dropck-eyepatch.rs
index fb9af09..97820ac 100644
--- a/src/test/run-pass/drop/dropck-eyepatch.rs
+++ b/src/test/run-pass/drop/dropck-eyepatch.rs
@@ -32,7 +32,7 @@
 // - D means "I implement Drop"
 //
 // - P means "I implement Drop but guarantee my (first) parameter is
-//     pure, i.e. not accessed from the destructor"; no other parameters
+//     pure, i.e., not accessed from the destructor"; no other parameters
 //     are pure.
 //
 // - S means "I do not implement Drop"
diff --git a/src/test/run-pass/drop/dropck_legal_cycles.rs b/src/test/run-pass/drop/dropck_legal_cycles.rs
index 2c88cfd..89d70da 100644
--- a/src/test/run-pass/drop/dropck_legal_cycles.rs
+++ b/src/test/run-pass/drop/dropck_legal_cycles.rs
@@ -108,7 +108,7 @@
 //    of all-zeroes.
 //
 // 6. assert that the context confirms that it actually saw a cycle (since a traversal
-//    might have terminated, e.g. on a tree structure that contained no cycles).
+//    might have terminated, e.g., on a tree structure that contained no cycles).
 
 use std::cell::{Cell, RefCell};
 use std::cmp::Ordering;
diff --git a/src/test/run-pass/env-funky-keys.rs b/src/test/run-pass/env-funky-keys.rs
index 12e1cbe..7e7899c 100644
--- a/src/test/run-pass/env-funky-keys.rs
+++ b/src/test/run-pass/env-funky-keys.rs
@@ -16,7 +16,7 @@
 // ignore-emscripten no execve
 // no-prefer-dynamic
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/env-null-vars.rs b/src/test/run-pass/env-null-vars.rs
index 9a46199..cdbecf1 100644
--- a/src/test/run-pass/env-null-vars.rs
+++ b/src/test/run-pass/env-null-vars.rs
@@ -15,7 +15,7 @@
 
 // issue-53200
 
-#![feature(libc)]
+#![feature(rustc_private)]
 extern crate libc;
 
 use std::env;
diff --git a/src/test/run-pass/extern/auxiliary/extern-crosscrate-source.rs b/src/test/run-pass/extern/auxiliary/extern-crosscrate-source.rs
index 150dffe..d20d9db 100644
--- a/src/test/run-pass/extern/auxiliary/extern-crosscrate-source.rs
+++ b/src/test/run-pass/extern/auxiliary/extern-crosscrate-source.rs
@@ -10,7 +10,7 @@
 
 #![crate_name="externcallback"]
 #![crate_type = "lib"]
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/extern/extern-call-deep.rs b/src/test/run-pass/extern/extern-call-deep.rs
index 6e8d94b..12df0f3 100644
--- a/src/test/run-pass/extern/extern-call-deep.rs
+++ b/src/test/run-pass/extern/extern-call-deep.rs
@@ -10,8 +10,9 @@
 
 // run-pass
 // ignore-wasm32-bare no libc to test ffi with
+// ignore-emscripten blows the JS stack
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/extern/extern-call-deep2.rs b/src/test/run-pass/extern/extern-call-deep2.rs
index 28157c5..8cb0477 100644
--- a/src/test/run-pass/extern/extern-call-deep2.rs
+++ b/src/test/run-pass/extern/extern-call-deep2.rs
@@ -12,7 +12,7 @@
 #![allow(unused_must_use)]
 // ignore-emscripten no threads support
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 use std::thread;
diff --git a/src/test/run-pass/extern/extern-call-indirect.rs b/src/test/run-pass/extern/extern-call-indirect.rs
index 1badb10..d20721f 100644
--- a/src/test/run-pass/extern/extern-call-indirect.rs
+++ b/src/test/run-pass/extern/extern-call-indirect.rs
@@ -11,7 +11,7 @@
 // run-pass
 // ignore-wasm32-bare no libc to test ffi with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/extern/extern-call-scrub.rs b/src/test/run-pass/extern/extern-call-scrub.rs
index ea18069..5e158c2 100644
--- a/src/test/run-pass/extern/extern-call-scrub.rs
+++ b/src/test/run-pass/extern/extern-call-scrub.rs
@@ -16,7 +16,7 @@
 
 // ignore-emscripten no threads support
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 use std::thread;
diff --git a/src/test/run-pass/extern/extern-crosscrate.rs b/src/test/run-pass/extern/extern-crosscrate.rs
index c6fccbe..b99e27a 100644
--- a/src/test/run-pass/extern/extern-crosscrate.rs
+++ b/src/test/run-pass/extern/extern-crosscrate.rs
@@ -12,7 +12,7 @@
 // aux-build:extern-crosscrate-source.rs
 // ignore-wasm32-bare no libc to test ffi with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate externcallback;
 extern crate libc;
diff --git a/src/test/run-pass/fds-are-cloexec.rs b/src/test/run-pass/fds-are-cloexec.rs
index a5ae0ae..33e64d8 100644
--- a/src/test/run-pass/fds-are-cloexec.rs
+++ b/src/test/run-pass/fds-are-cloexec.rs
@@ -14,7 +14,7 @@
 // ignore-emscripten no processes
 // ignore-haiku
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/for-loop-while/loop-no-reinit-needed-post-bot.rs b/src/test/run-pass/for-loop-while/loop-no-reinit-needed-post-bot.rs
index 95bb8e8..7bc4dcc 100644
--- a/src/test/run-pass/for-loop-while/loop-no-reinit-needed-post-bot.rs
+++ b/src/test/run-pass/for-loop-while/loop-no-reinit-needed-post-bot.rs
@@ -15,7 +15,7 @@
 // Ensure S is moved, not copied, on assignment.
 impl Drop for S { fn drop(&mut self) { } }
 
-// user-defined function "returning" bottom (i.e. no return at all).
+// user-defined function "returning" bottom (i.e., no return at all).
 fn my_panic() -> ! { loop {} }
 
 pub fn step(f: bool) {
diff --git a/src/test/run-pass/foreign/auxiliary/foreign_lib.rs b/src/test/run-pass/foreign/auxiliary/foreign_lib.rs
index cef3627..465feb8 100644
--- a/src/test/run-pass/foreign/auxiliary/foreign_lib.rs
+++ b/src/test/run-pass/foreign/auxiliary/foreign_lib.rs
@@ -10,7 +10,7 @@
 
 #![crate_name="foreign_lib"]
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 pub mod rustrt {
     extern crate libc;
diff --git a/src/test/run-pass/foreign/foreign-call-no-runtime.rs b/src/test/run-pass/foreign/foreign-call-no-runtime.rs
index 4837f78..e35ec88 100644
--- a/src/test/run-pass/foreign/foreign-call-no-runtime.rs
+++ b/src/test/run-pass/foreign/foreign-call-no-runtime.rs
@@ -11,7 +11,7 @@
 // run-pass
 // ignore-emscripten no threads support
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/foreign/foreign-fn-linkname.rs b/src/test/run-pass/foreign/foreign-fn-linkname.rs
index 7587660..8fe90b7 100644
--- a/src/test/run-pass/foreign/foreign-fn-linkname.rs
+++ b/src/test/run-pass/foreign/foreign-fn-linkname.rs
@@ -11,7 +11,7 @@
 // run-pass
 // ignore-wasm32-bare no libc to test ffi with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 use std::ffi::CString;
diff --git a/src/test/run-pass/foreign/foreign-no-abi.rs b/src/test/run-pass/foreign/foreign-no-abi.rs
index 1d35f08..49ddd09 100644
--- a/src/test/run-pass/foreign/foreign-no-abi.rs
+++ b/src/test/run-pass/foreign/foreign-no-abi.rs
@@ -14,7 +14,7 @@
 // ignore-wasm32-bare no libc to test ffi with
 // pretty-expanded FIXME #23616
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 mod rustrt {
     extern crate libc;
diff --git a/src/test/run-pass/foreign/foreign2.rs b/src/test/run-pass/foreign/foreign2.rs
index bd6c8e6..f8942bc 100644
--- a/src/test/run-pass/foreign/foreign2.rs
+++ b/src/test/run-pass/foreign/foreign2.rs
@@ -13,7 +13,7 @@
 // ignore-wasm32-bare no libc to test ffi with
 // pretty-expanded FIXME #23616
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs
index 7373828..d622fd6 100644
--- a/src/test/run-pass/impl-trait/example-calendar.rs
+++ b/src/test/run-pass/impl-trait/example-calendar.rs
@@ -86,7 +86,7 @@
         let weeks_in_year = self.last_week_number();
 
         // Work out the final result.
-        // If the week is -1 or >= weeks_in_year, we will need to adjust the year.
+        // If the week is `-1` or `>= weeks_in_year`, we will need to adjust the year.
         let year = self.year();
         let wd = self.weekday();
 
@@ -234,7 +234,7 @@
     }
 }
 
-/// GroupBy implementation.
+/// `GroupBy` implementation.
 struct GroupBy<It: Iterator, F> {
     it: std::iter::Peekable<It>,
     f: F,
@@ -319,7 +319,7 @@
         s
     }
 
-    // HACK(eddyb) Only needed because `impl Trait` can't be
+    // HACK(eddyb): only needed because `impl Trait` can't be
     // used with trait methods: `.foo()` becomes `.__(foo)`.
     fn __<F, R>(self, f: F) -> R
     where F: FnOnce(Self) -> R {
@@ -329,9 +329,7 @@
 
 impl<It> IteratorExt for It where It: Iterator {}
 
-///
-/// Generates an iterator that yields exactly n spaces.
-///
+/// Generates an iterator that yields exactly `n` spaces.
 fn spaces(n: usize) -> std::iter::Take<std::iter::Repeat<char>> {
     std::iter::repeat(' ').take(n)
 }
@@ -341,9 +339,7 @@
     assert_eq!(spaces(10).collect::<String>(), "          ")
 }
 
-///
 /// Returns an iterator of dates in a given year.
-///
 fn dates_in_year(year: i32) -> impl Iterator<Item=NaiveDate>+Clone {
     InGroup {
         it: NaiveDate::from_ymd(year, 1, 1)..,
@@ -357,10 +353,10 @@
         let mut dates = dates_in_year(2013);
         assert_eq!(dates.next(), Some(NaiveDate::from_ymd(2013, 1, 1)));
 
-        // Check increment
+        // Check increment.
         assert_eq!(dates.next(), Some(NaiveDate::from_ymd(2013, 1, 2)));
 
-        // Check monthly rollover
+        // Check monthly roll-over.
         for _ in 3..31 {
             assert!(dates.next() != None);
         }
@@ -370,7 +366,7 @@
     }
 
     {
-        // Check length of year
+        // Check length of year.
         let mut dates = dates_in_year(2013);
         for _ in 0..365 {
             assert!(dates.next() != None);
@@ -379,7 +375,7 @@
     }
 
     {
-        // Check length of leap year
+        // Check length of leap year.
         let mut dates = dates_in_year(1984);
         for _ in 0..366 {
             assert!(dates.next() != None);
@@ -388,10 +384,8 @@
     }
 }
 
-///
 /// Convenience trait for verifying that a given type iterates over
 /// `NaiveDate`s.
-///
 trait DateIterator: Iterator<Item=NaiveDate> + Clone {}
 impl<It> DateIterator for It where It: Iterator<Item=NaiveDate> + Clone {}
 
@@ -427,11 +421,9 @@
     }
 }
 
-///
 /// Groups an iterator of dates by month.
-///
 fn by_month(it: impl Iterator<Item=NaiveDate> + Clone)
-           ->  impl Iterator<Item=(u32, impl Iterator<Item=NaiveDate> + Clone)> + Clone
+            ->  impl Iterator<Item=(u32, impl Iterator<Item=NaiveDate> + Clone)> + Clone
 {
     it.group_by(|d| d.month())
 }
@@ -444,9 +436,7 @@
     assert!(months.next().is_none());
 }
 
-///
 /// Groups an iterator of dates by week.
-///
 fn by_week(it: impl DateIterator)
           -> impl Iterator<Item=(u32, impl DateIterator)> + Clone
 {
@@ -518,9 +508,7 @@
 /// The number of columns per week in the formatted output.
 const COLS_PER_WEEK: u32 = 7 * COLS_PER_DAY;
 
-///
 /// Formats an iterator of weeks into an iterator of strings.
-///
 fn format_weeks(it: impl Iterator<Item = impl DateIterator>) -> impl Iterator<Item=String> {
     it.map(|week| {
         let mut buf = String::with_capacity((COLS_PER_DAY * COLS_PER_WEEK + 2) as usize);
@@ -541,7 +529,7 @@
         }
 
         // Insert more filler at the end to fill up the remainder of the week,
-        // if its a short week (e.g. at the end of the month).
+        // if its a short week (e.g., at the end of the month).
         buf.extend(spaces((COLS_PER_DAY * (6 - last_day)) as usize));
         buf
     })
@@ -567,9 +555,7 @@
     );
 }
 
-///
-/// Formats the name of a month, centered on COLS_PER_WEEK.
-///
+/// Formats the name of a month, centered on `COLS_PER_WEEK`.
 fn month_title(month: u32) -> String {
     const MONTH_NAMES: &'static [&'static str] = &[
         "January", "February", "March", "April", "May", "June",
@@ -584,7 +570,7 @@
     let before = (COLS_PER_WEEK as usize - name.len()) / 2;
     let after = COLS_PER_WEEK as usize - name.len() - before;
 
-    // NOTE: Being slightly more verbose to avoid extra allocations.
+    // Note: being slightly more verbose to avoid extra allocations.
     let mut result = String::with_capacity(COLS_PER_WEEK as usize);
     result.extend(spaces(before));
     result.push_str(name);
@@ -596,9 +582,7 @@
     assert_eq!(month_title(1).len(), COLS_PER_WEEK as usize);
 }
 
-///
 /// Formats a month.
-///
 fn format_month(it: impl DateIterator) -> impl Iterator<Item=String> {
     let mut month_days = it.peekable();
     let title = month_title(month_days.peek().unwrap().month());
@@ -627,22 +611,17 @@
     );
 }
 
-
-///
 /// Formats an iterator of months.
-///
 fn format_months(it: impl Iterator<Item = impl DateIterator>)
                 -> impl Iterator<Item=impl Iterator<Item=String>>
 {
     it.map(format_month)
 }
 
-///
 /// Takes an iterator of iterators of strings; the sub-iterators are consumed
 /// in lock-step, with their elements joined together.
-///
 trait PasteBlocks: Iterator + Sized
-where Self::Item: Iterator<Item=String> {
+where Self::Item: Iterator<Item = String> {
     fn paste_blocks(self, sep_width: usize) -> PasteBlocksIter<Self::Item> {
         PasteBlocksIter {
             iters: self.collect(),
@@ -721,9 +700,7 @@
     );
 }
 
-///
 /// Produces an iterator that yields `n` elements at a time.
-///
 trait Chunks: Iterator + Sized {
     fn chunks(self, n: usize) -> ChunksIter<Self> {
         assert!(n > 0);
@@ -742,7 +719,7 @@
     n: usize,
 }
 
-// NOTE: `chunks` in Rust is more-or-less impossible without overhead of some kind.
+// Note: `chunks` in Rust is more-or-less impossible without overhead of some kind.
 // Aliasing rules mean you need to add dynamic borrow checking, and the design of
 // `Iterator` means that you need to have the iterator's state kept in an allocation
 // that is jointly owned by the iterator itself and the sub-iterator.
@@ -769,9 +746,7 @@
     assert_eq!(&*c, &[vec![1, 2, 3], vec![4, 5, 6], vec![7]]);
 }
 
-///
 /// Formats a year.
-///
 fn format_year(year: i32, months_per_row: usize) -> String {
     const COL_SPACING: usize = 1;
 
@@ -784,17 +759,17 @@
         // Group the months into horizontal rows.
         .chunks(months_per_row)
 
-        // Format each row
+        // Format each row...
         .map(|r| r.into_iter()
-            // By formatting each month
+            // ... by formatting each month ...
             .__(format_months)
 
-            // Horizontally pasting each respective month's lines together.
+            // ... and horizontally pasting each respective month's lines together.
             .paste_blocks(COL_SPACING)
             .join("\n")
         )
 
-        // Insert a blank line between each row
+        // Insert a blank line between each row.
         .join("\n\n")
 }
 
diff --git a/src/test/run-pass/invalid_const_promotion.rs b/src/test/run-pass/invalid_const_promotion.rs
index 0f354e1..3b8a265 100644
--- a/src/test/run-pass/invalid_const_promotion.rs
+++ b/src/test/run-pass/invalid_const_promotion.rs
@@ -15,7 +15,7 @@
 // compile-flags: -C debug_assertions=yes
 
 #![stable(feature = "rustc", since = "1.0.0")]
-#![feature(const_fn, libc, staged_api, rustc_attrs)]
+#![feature(const_fn, rustc_private, staged_api, rustc_attrs)]
 #![allow(const_err)]
 
 extern crate libc;
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/issues/issue-13259-windows-tcb-trash.rs b/src/test/run-pass/issues/issue-13259-windows-tcb-trash.rs
index de18e09..9c983ea 100644
--- a/src/test/run-pass/issues/issue-13259-windows-tcb-trash.rs
+++ b/src/test/run-pass/issues/issue-13259-windows-tcb-trash.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // run-pass
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/issues/issue-2214.rs b/src/test/run-pass/issues/issue-2214.rs
index 8329847..f3795c2 100644
--- a/src/test/run-pass/issues/issue-2214.rs
+++ b/src/test/run-pass/issues/issue-2214.rs
@@ -11,7 +11,7 @@
 // run-pass
 // ignore-wasm32-bare no libc to test ffi with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/issues/issue-23808.rs b/src/test/run-pass/issues/issue-23808.rs
index 133da00..59c3e39 100644
--- a/src/test/run-pass/issues/issue-23808.rs
+++ b/src/test/run-pass/issues/issue-23808.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // run-pass
+
 #![deny(dead_code)]
 
 // use different types / traits to test all combinations
diff --git a/src/test/run-pass/issues/issue-24805-dropck-itemless.rs b/src/test/run-pass/issues/issue-24805-dropck-itemless.rs
index 1d1bd21..b9d2523 100644
--- a/src/test/run-pass/issues/issue-24805-dropck-itemless.rs
+++ b/src/test/run-pass/issues/issue-24805-dropck-itemless.rs
@@ -23,7 +23,7 @@
 impl UserDefined for i32 { }
 impl<'a, T> UserDefined for &'a T { }
 
-// e.g. `impl_drop!(Send, D_Send)` expands to:
+// e.g., `impl_drop!(Send, D_Send)` expands to:
 //   ```rust
 //   struct D_Send<T:Send>(T);
 //   impl<T:Send> Drop for D_Send<T> { fn drop(&mut self) { } }
diff --git a/src/test/run-pass/issues/issue-26996.rs b/src/test/run-pass/issues/issue-26996.rs
index 83445c6..61ac665 100644
--- a/src/test/run-pass/issues/issue-26996.rs
+++ b/src/test/run-pass/issues/issue-26996.rs
@@ -10,7 +10,7 @@
 
 // run-pass
 
-// This test is bogus (i.e. should be compile-fail) during the period
+// This test is bogus (i.e., should be compile-fail) during the period
 // where #54986 is implemented and #54987 is *not* implemented. For
 // now: just ignore it under nll
 //
diff --git a/src/test/run-pass/issues/issue-27021.rs b/src/test/run-pass/issues/issue-27021.rs
index dbad855..21e4568 100644
--- a/src/test/run-pass/issues/issue-27021.rs
+++ b/src/test/run-pass/issues/issue-27021.rs
@@ -10,7 +10,7 @@
 
 // run-pass
 
-// This test is bogus (i.e. should be compile-fail) during the period
+// This test is bogus (i.e., should be compile-fail) during the period
 // where #54986 is implemented and #54987 is *not* implemented. For
 // now: just ignore it under nll
 //
diff --git a/src/test/run-pass/issues/issue-30490.rs b/src/test/run-pass/issues/issue-30490.rs
index 500999c..47f60fb 100644
--- a/src/test/run-pass/issues/issue-30490.rs
+++ b/src/test/run-pass/issues/issue-30490.rs
@@ -18,7 +18,7 @@
 // where the descriptors to inherit were already stdio descriptors.
 // This test checks to avoid that regression.
 
-#![cfg_attr(unix, feature(libc))]
+#![cfg_attr(unix, feature(rustc_private))]
 #![cfg_attr(windows, allow(unused_imports))]
 
 #[cfg(unix)]
diff --git a/src/test/run-pass/issues/issue-3563-3.rs b/src/test/run-pass/issues/issue-3563-3.rs
index 13d74be..6ba1a7b 100644
--- a/src/test/run-pass/issues/issue-3563-3.rs
+++ b/src/test/run-pass/issues/issue-3563-3.rs
@@ -128,7 +128,7 @@
 }
 
 // Here we provide an implementation of the Canvas methods for AsciiArt.
-// Other implementations could also be provided (e.g. for PDF or Apple's Quartz)
+// Other implementations could also be provided (e.g., for PDF or Apple's Quartz)
 // and code can use them polymorphically via the Canvas trait.
 impl Canvas for AsciiArt {
     fn add_point(&mut self, shape: Point) {
diff --git a/src/test/run-pass/issues/issue-3656.rs b/src/test/run-pass/issues/issue-3656.rs
index 63b2740..99a7244 100644
--- a/src/test/run-pass/issues/issue-3656.rs
+++ b/src/test/run-pass/issues/issue-3656.rs
@@ -19,7 +19,7 @@
 // pretty-expanded FIXME #23616
 // ignore-wasm32-bare no libc to test with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 use libc::{c_uint, uint32_t, c_void};
diff --git a/src/test/run-pass/issues/issue-49298.rs b/src/test/run-pass/issues/issue-49298.rs
index db3c979..42cfb6f 100644
--- a/src/test/run-pass/issues/issue-49298.rs
+++ b/src/test/run-pass/issues/issue-49298.rs
@@ -12,7 +12,7 @@
 #![feature(test)]
 #![allow(unused_mut)] // under NLL we get warning about `x` below: rust-lang/rust#54499
 
-// This test is bogus (i.e. should be compile-fail) during the period
+// This test is bogus (i.e., should be compile-fail) during the period
 // where #54986 is implemented and #54987 is *not* implemented. For
 // now: just ignore it under nll
 //
diff --git a/src/test/run-pass/issues/issue-49955-2.rs b/src/test/run-pass/issues/issue-49955-2.rs
index 8888382..94aaa63 100644
--- a/src/test/run-pass/issues/issue-49955-2.rs
+++ b/src/test/run-pass/issues/issue-49955-2.rs
@@ -18,7 +18,7 @@
 #[inline(never)]
 fn tuple_field() -> &'static u32 {
     // This test is MIR-borrowck-only because the old borrowck
-    // doesn't agree that borrows of "frozen" (i.e. without any
+    // doesn't agree that borrows of "frozen" (i.e., without any
     // interior mutability) fields of non-frozen temporaries,
     // should be promoted, while MIR promotion does promote them.
     &(FIVE, 42).1
diff --git a/src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs b/src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs
index 05f1f1b..77b6ba1 100644
--- a/src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs
+++ b/src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs
@@ -12,7 +12,7 @@
 // option. This file may not be copied, modified, or distributed

 // except according to those terms.

 

-// NB: this file needs CRLF line endings. The .gitattributes file in

+// N.B., this file needs CRLF line endings. The .gitattributes file in

 // this directory should enforce it.

 

 // ignore-pretty issue #37195

diff --git a/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs
index 14ef8c1..71f39c12 100644
--- a/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs
+++ b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs
@@ -15,7 +15,7 @@
 #![forbid(non_upper_case_globals)]
 #![feature(non_ascii_idents)]
 
-// Some scripts (e.g. hiragana) don't have a concept of
+// Some scripts (e.g., hiragana) don't have a concept of
 // upper/lowercase
 
 struct ヒ;
diff --git a/src/test/run-pass/macros/macro-comma-behavior.rs b/src/test/run-pass/macros/macro-comma-behavior.rs
index 95774ca..b245fe1 100644
--- a/src/test/run-pass/macros/macro-comma-behavior.rs
+++ b/src/test/run-pass/macros/macro-comma-behavior.rs
@@ -15,7 +15,7 @@
 //
 // This checks the behavior of macros with trailing commas in key
 // places where regressions in behavior seem highly possible (due
-// to it being e.g. a place where the addition of an argument
+// to it being e.g., a place where the addition of an argument
 // causes it to go down a code path with subtly different behavior).
 //
 // There is a companion test in compile-fail.
diff --git a/src/test/run-pass/multi-panic.rs b/src/test/run-pass/multi-panic.rs
index 2e6e109..03e58fc 100644
--- a/src/test/run-pass/multi-panic.rs
+++ b/src/test/run-pass/multi-panic.rs
@@ -17,7 +17,8 @@
     let mut it = err.lines();
 
     assert_eq!(it.next().map(|l| l.starts_with("thread '<unnamed>' panicked at")), Some(true));
-    assert_eq!(it.next(), Some("note: Run with `RUST_BACKTRACE=1` for a backtrace."));
+    assert_eq!(it.next(), Some("note: Run with `RUST_BACKTRACE=1` \
+                                environment variable to display a backtrace."));
     assert_eq!(it.next().map(|l| l.starts_with("thread 'main' panicked at")), Some(true));
     assert_eq!(it.next(), None);
 }
diff --git a/src/test/run-pass/no-stdio.rs b/src/test/run-pass/no-stdio.rs
index d342417..2f5bfbb 100644
--- a/src/test/run-pass/no-stdio.rs
+++ b/src/test/run-pass/no-stdio.rs
@@ -12,7 +12,7 @@
 // ignore-cloudabi no processes
 // ignore-emscripten no processes
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/out-of-stack.rs b/src/test/run-pass/out-of-stack.rs
index cd0f7cd..1c714e7 100644
--- a/src/test/run-pass/out-of-stack.rs
+++ b/src/test/run-pass/out-of-stack.rs
@@ -16,7 +16,7 @@
 // ignore-emscripten no processes
 
 #![feature(asm)]
-#![feature(libc)]
+#![feature(rustc_private)]
 
 #[cfg(unix)]
 extern crate libc;
diff --git a/src/test/run-pass/packed/packed-struct-optimized-enum.rs b/src/test/run-pass/packed/packed-struct-optimized-enum.rs
index e22e8c2..9877277 100644
--- a/src/test/run-pass/packed/packed-struct-optimized-enum.rs
+++ b/src/test/run-pass/packed/packed-struct-optimized-enum.rs
@@ -34,12 +34,12 @@
 
     // In #46769, `Option<(Packed<&()>, bool)>` was found to have
     // pointer alignment, without actually being aligned in size.
-    // E.g. on 64-bit platforms, it had alignment `8` but size `9`.
+    // e.g., on 64-bit platforms, it had alignment `8` but size `9`.
     type PackedRefAndBool<'a> = (Packed<&'a ()>, bool);
     sanity_check_size::<Option<PackedRefAndBool>>(Some((Packed(&()), true)));
 
     // Make sure we don't pay for the enum optimization in size,
-    // e.g. we shouldn't need extra padding after the packed data.
+    // e.g., we shouldn't need extra padding after the packed data.
     assert_eq!(std::mem::align_of::<Option<PackedRefAndBool>>(), 1);
     assert_eq!(std::mem::size_of::<Option<PackedRefAndBool>>(),
                std::mem::size_of::<PackedRefAndBool>());
diff --git a/src/test/run-pass/regions/regions-early-bound-trait-param.rs b/src/test/run-pass/regions/regions-early-bound-trait-param.rs
index 220614c..70cb4bc 100644
--- a/src/test/run-pass/regions/regions-early-bound-trait-param.rs
+++ b/src/test/run-pass/regions/regions-early-bound-trait-param.rs
@@ -131,7 +131,7 @@
     // for details.
     assert_eq!(object_invoke2(&*m), 5);
 
-    // The RefMakerTrait above is pretty strange (i.e. it is strange
+    // The RefMakerTrait above is pretty strange (i.e., it is strange
     // to consume a value of type T and return a &T).  Easiest thing
     // that came to my mind: consume a cell of a linked list and
     // return a reference to the list it points to.
diff --git a/src/test/run-pass/rfcs/rfc-1014-2.rs b/src/test/run-pass/rfcs/rfc-1014-2.rs
index 7fbc0d1..257c7f5 100644
--- a/src/test/run-pass/rfcs/rfc-1014-2.rs
+++ b/src/test/run-pass/rfcs/rfc-1014-2.rs
@@ -11,7 +11,7 @@
 // run-pass
 #![allow(dead_code)]
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/rfcs/rfc-1014.rs b/src/test/run-pass/rfcs/rfc-1014.rs
index d101c3c..578a7f4 100644
--- a/src/test/run-pass/rfcs/rfc-1014.rs
+++ b/src/test/run-pass/rfcs/rfc-1014.rs
@@ -13,7 +13,7 @@
 // ignore-cloudabi stdout does not map to file descriptor 1 by default
 // ignore-wasm32-bare no libc
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/segfault-no-out-of-stack.rs b/src/test/run-pass/segfault-no-out-of-stack.rs
index a85fe67..961b802 100644
--- a/src/test/run-pass/segfault-no-out-of-stack.rs
+++ b/src/test/run-pass/segfault-no-out-of-stack.rs
@@ -12,7 +12,7 @@
 // ignore-cloudabi can't run commands
 // ignore-emscripten can't run commands
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/signal-alternate-stack-cleanup.rs b/src/test/run-pass/signal-alternate-stack-cleanup.rs
index ad099f8..a79ab20 100644
--- a/src/test/run-pass/signal-alternate-stack-cleanup.rs
+++ b/src/test/run-pass/signal-alternate-stack-cleanup.rs
@@ -16,7 +16,7 @@
 // ignore-wasm32-bare no libc
 // ignore-windows
 
-#![feature(libc)]
+#![feature(rustc_private)]
 extern crate libc;
 
 use libc::*;
diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-cast.rs b/src/test/run-pass/simd/simd-intrinsic-generic-cast.rs
index f0fb24b..df5f72e 100644
--- a/src/test/run-pass/simd/simd-intrinsic-generic-cast.rs
+++ b/src/test/run-pass/simd/simd-intrinsic-generic-cast.rs
@@ -94,9 +94,9 @@
             // there are platform differences for some out of range
             // casts, so we just normalize such things: it's OK for
             // "invalid" calculations to result in nonsense answers.
-            // (E.g. negative float to unsigned integer goes through a
+            // (e.g., negative float to unsigned integer goes through a
             // library routine on the default i686 platforms, and the
-            // implementation of that routine differs on e.g. Linux
+            // implementation of that routine differs on e.g., Linux
             // vs. macOS, resulting in different answers.)
             if $from::is_float() {
                 if !$to::in_range(A) { from.0 = 0 as $to; to.0 = 0 as $to; }
diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-select.rs b/src/test/run-pass/simd/simd-intrinsic-generic-select.rs
index 590a299..74b99ca 100644
--- a/src/test/run-pass/simd/simd-intrinsic-generic-select.rs
+++ b/src/test/run-pass/simd/simd-intrinsic-generic-select.rs
@@ -28,6 +28,10 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
+struct u32x8(u32, u32, u32, u32, u32, u32, u32, u32);
+
+#[repr(simd)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
 #[repr(simd)]
@@ -36,6 +40,7 @@
 
 extern "platform-intrinsic" {
     fn simd_select<T, U>(x: T, a: U, b: U) -> U;
+    fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
 }
 
 fn main() {
@@ -146,4 +151,29 @@
         let e = b8x4(t, f, t, t);
         assert_eq!(r, e);
     }
+
+    unsafe {
+        let a = u32x8(0, 1, 2, 3, 4, 5, 6, 7);
+        let b = u32x8(8, 9, 10, 11, 12, 13, 14, 15);
+
+        let r: u32x8 = simd_select_bitmask(0u8, a, b);
+        let e = b;
+        assert_eq!(r, e);
+
+        let r: u32x8 = simd_select_bitmask(0xffu8, a, b);
+        let e = a;
+        assert_eq!(r, e);
+
+        let r: u32x8 = simd_select_bitmask(0b01010101u8, a, b);
+        let e = u32x8(0, 9, 2, 11, 4, 13, 6, 15);
+        assert_eq!(r, e);
+
+        let r: u32x8 = simd_select_bitmask(0b10101010u8, a, b);
+        let e = u32x8(8, 1, 10, 3, 12, 5, 14, 7);
+        assert_eq!(r, e);
+
+        let r: u32x8 = simd_select_bitmask(0b11110000u8, a, b);
+        let e = u32x8(8, 9, 10, 11, 4, 5, 6, 7);
+        assert_eq!(r, e);
+    }
 }
diff --git a/src/test/run-pass/statics/static-mut-foreign.rs b/src/test/run-pass/statics/static-mut-foreign.rs
index d9e43dd..460d66a 100644
--- a/src/test/run-pass/statics/static-mut-foreign.rs
+++ b/src/test/run-pass/statics/static-mut-foreign.rs
@@ -15,7 +15,7 @@
 
 // ignore-wasm32-bare no libc to test ffi with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/try-operator-hygiene.rs b/src/test/run-pass/try-operator-hygiene.rs
index 045a8a50..2771ab4 100644
--- a/src/test/run-pass/try-operator-hygiene.rs
+++ b/src/test/run-pass/try-operator-hygiene.rs
@@ -17,7 +17,7 @@
 //     Err(err) => return Err(From::from(err)),
 // }
 //
-// This test verifies that the expansion is hygienic, i.e. it's not affected by other `val` and
+// This test verifies that the expansion is hygienic, i.e., it's not affected by other `val` and
 // `err` bindings that may be in scope.
 
 use std::num::ParseIntError;
diff --git a/src/test/run-pass/uniform-paths/basic-nested.rs b/src/test/run-pass/uniform-paths/basic-nested.rs
index a025618..c6a95ba 100644
--- a/src/test/run-pass/uniform-paths/basic-nested.rs
+++ b/src/test/run-pass/uniform-paths/basic-nested.rs
@@ -41,7 +41,7 @@
 mod bar {
     // Also test the unqualified external crate import in a nested module,
     // to show that the above import doesn't resolve through a local `std`
-    // item, e.g. the automatically injected `extern crate std;`, which in
+    // item, e.g., the automatically injected `extern crate std;`, which in
     // the Rust 2018 should no longer be visible through `crate::std`.
     pub use std::io;
 
diff --git a/src/test/run-pass/uniform-paths/macros-nested.rs b/src/test/run-pass/uniform-paths/macros-nested.rs
index 3737343..f22113d 100644
--- a/src/test/run-pass/uniform-paths/macros-nested.rs
+++ b/src/test/run-pass/uniform-paths/macros-nested.rs
@@ -50,7 +50,7 @@
 mod bar {
     // Also test the unqualified external crate import in a nested module,
     // to show that the above import doesn't resolve through a local `std`
-    // item, e.g. the automatically injected `extern crate std;`, which in
+    // item, e.g., the automatically injected `extern crate std;`, which in
     // the Rust 2018 should no longer be visible through `crate::std`.
     pub use std::io;
 }
diff --git a/src/test/run-pass/wait-forked-but-failed-child.rs b/src/test/run-pass/wait-forked-but-failed-child.rs
index dc47108..d822b67 100644
--- a/src/test/run-pass/wait-forked-but-failed-child.rs
+++ b/src/test/run-pass/wait-forked-but-failed-child.rs
@@ -11,7 +11,7 @@
 // ignore-cloudabi no processes
 // ignore-emscripten no processes
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs b/src/test/rustdoc-js/filter-crate.js
similarity index 77%
copy from src/test/ui/feature-gate-exhaustive_integer_patterns.rs
copy to src/test/rustdoc-js/filter-crate.js
index 3aa1522..97ecc60 100644
--- a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs
+++ b/src/test/rustdoc-js/filter-crate.js
@@ -8,9 +8,12 @@
 // 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 => {}
-    }
-}
+// exact-check
+
+const QUERY = 'hashmap';
+const FILTER_CRATE = 'core';
+
+const EXPECTED = {
+    'others': [
+    ],
+};
diff --git a/src/test/rustdoc-ui/.gitattributes b/src/test/rustdoc-ui/.gitattributes
new file mode 100644
index 0000000..2bcabdf
--- /dev/null
+++ b/src/test/rustdoc-ui/.gitattributes
@@ -0,0 +1 @@
+intra-links-warning-crlf.rs eol=crlf
diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout
index 52e0cdc..bd6fa1f 100644
--- a/src/test/rustdoc-ui/failed-doctest-output.stdout
+++ b/src/test/rustdoc-ui/failed-doctest-output.stdout
@@ -12,16 +12,16 @@
 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:327:13
-note: Run with `RUST_BACKTRACE=1` for a backtrace.
+thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:326:13
+note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
 
 ---- $DIR/failed-doctest-output.rs - SomeStruct (line 21) stdout ----
 thread '$DIR/failed-doctest-output.rs - SomeStruct (line 21)' panicked at 'test executable failed:
 
 thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1
-note: Run with `RUST_BACKTRACE=1` for a backtrace.
+note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
 
-', src/librustdoc/test.rs:362:17
+', src/librustdoc/test.rs:361:17
 
 
 failures:
diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.rs b/src/test/rustdoc-ui/intra-links-warning-crlf.rs
new file mode 100644
index 0000000..20f761f
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-links-warning-crlf.rs
@@ -0,0 +1,23 @@
+// ignore-tidy-cr
+
+// compile-pass
+
+// This file checks the spans of intra-link warnings in a file with CRLF line endings. The
+// .gitattributes file in this directory should enforce it.
+
+/// [error]
+pub struct A;
+
+///
+/// docs [error1]
+
+/// docs [error2]
+///
+pub struct B;
+
+/**
+ * This is a multi-line comment.
+ *
+ * It also has an [error].
+ */
+pub struct C;
diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
new file mode 100644
index 0000000..62537f2
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
@@ -0,0 +1,33 @@
+warning: `[error]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning-crlf.rs:8:6
+   |
+LL | /// [error]
+   |      ^^^^^ cannot be resolved, ignoring
+   |
+   = note: #[warn(intra_doc_link_resolution_failure)] on by default
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[error1]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning-crlf.rs:12:11
+   |
+LL | /// docs [error1]
+   |           ^^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[error2]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning-crlf.rs:14:11
+   |
+LL | /// docs [error2]
+   |           ^^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[error]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning-crlf.rs:21:20
+   |
+LL |  * It also has an [error].
+   |                    ^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
diff --git a/src/test/rustdoc-ui/intra-links-warning.rs b/src/test/rustdoc-ui/intra-links-warning.rs
index d6bc275..db2fd32 100644
--- a/src/test/rustdoc-ui/intra-links-warning.rs
+++ b/src/test/rustdoc-ui/intra-links-warning.rs
@@ -55,3 +55,33 @@
     }
 }
 f!("Foo\nbar [BarF] bar\nbaz");
+
+/** # for example,
+ *
+ * time to introduce a link [error]*/
+pub struct A;
+
+/**
+ * # for example,
+ *
+ * time to introduce a link [error]
+ */
+pub struct B;
+
+#[doc = "single line [error]"]
+pub struct C;
+
+#[doc = "single line with \"escaping\" [error]"]
+pub struct D;
+
+/// Item docs.
+#[doc="Hello there!"]
+/// [error]
+pub struct E;
+
+///
+/// docs [error1]
+
+/// docs [error2]
+///
+pub struct F;
diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr
index c05f99f..ed31421 100644
--- a/src/test/rustdoc-ui/intra-links-warning.stderr
+++ b/src/test/rustdoc-ui/intra-links-warning.stderr
@@ -55,6 +55,76 @@
    |
    = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
 
+warning: `[error]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:61:30
+   |
+LL |  * time to introduce a link [error]*/
+   |                              ^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[error]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:67:30
+   |
+LL |  * time to introduce a link [error]
+   |                              ^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[error]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:71:1
+   |
+LL | #[doc = "single line [error]"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the link appears in this line:
+           
+           single line [error]
+                        ^^^^^
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[error]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:74:1
+   |
+LL | #[doc = "single line with /"escaping/" [error]"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the link appears in this line:
+           
+           single line with "escaping" [error]
+                                        ^^^^^
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[error]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:77:1
+   |
+LL | / /// Item docs.
+LL | | #[doc="Hello there!"]
+LL | | /// [error]
+   | |___________^
+   |
+   = note: the link appears in this line:
+           
+            [error]
+             ^^^^^
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[error1]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:83:11
+   |
+LL | /// docs [error1]
+   |           ^^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[error2]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:85:11
+   |
+LL | /// docs [error2]
+   |           ^^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
 warning: `[BarA]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:24:10
    |
@@ -64,37 +134,19 @@
    = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
 
 warning: `[BarB]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:28:1
+  --> $DIR/intra-links-warning.rs:30:9
    |
-LL | / /**
-LL | |  * Foo
-LL | |  * bar [BarB] bar
-LL | |  * baz
-LL | |  */
-   | |___^
+LL |  * bar [BarB] bar
+   |         ^^^^ cannot be resolved, ignoring
    |
-   = note: the link appears in this line:
-           
-            bar [BarB] bar
-                 ^^^^
    = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
 
 warning: `[BarC]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:35:1
+  --> $DIR/intra-links-warning.rs:37:6
    |
-LL | / /** Foo
-LL | |
-LL | | bar [BarC] bar
-LL | | baz
-...  |
-LL | |
-LL | | */
-   | |__^
+LL | bar [BarC] bar
+   |      ^^^^ cannot be resolved, ignoring
    |
-   = note: the link appears in this line:
-           
-           bar [BarC] bar
-                ^^^^
    = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
 
 warning: `[BarD]` cannot be resolved, ignoring it...
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/issue-50159.rs b/src/test/rustdoc/issue-50159.rs
new file mode 100644
index 0000000..3055c72
--- /dev/null
+++ b/src/test/rustdoc/issue-50159.rs
@@ -0,0 +1,31 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+pub trait Signal {
+    type Item;
+}
+
+pub trait Signal2 {
+    type Item2;
+}
+
+impl<B, C> Signal2 for B where B: Signal<Item = C> {
+    type Item2 = C;
+}
+
+// @has issue_50159/struct.Switch.html
+// @has - '//code' 'impl<B> Send for Switch<B> where <B as Signal>::Item: Send'
+// @has - '//code' 'impl<B> Sync for Switch<B> where <B as Signal>::Item: Sync'
+// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0
+// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2
+pub struct Switch<B: Signal> {
+    pub inner: <B as Signal2>::Item2,
+}
diff --git a/src/test/rustdoc/proc-macro.rs b/src/test/rustdoc/proc-macro.rs
index 23d0d00..05d64f8 100644
--- a/src/test/rustdoc/proc-macro.rs
+++ b/src/test/rustdoc/proc-macro.rs
@@ -61,3 +61,16 @@
 pub fn some_derive(_item: TokenStream) -> TokenStream {
     TokenStream::new()
 }
+
+// @has some_macros/foo/index.html
+pub mod foo {
+    // @has - '//code' 'pub use some_proc_macro;'
+    // @has - '//a/@href' '../../some_macros/macro.some_proc_macro.html'
+    pub use some_proc_macro;
+    // @has - '//code' 'pub use some_proc_attr;'
+    // @has - '//a/@href' '../../some_macros/attr.some_proc_attr.html'
+    pub use some_proc_attr;
+    // @has - '//code' 'pub use some_derive;'
+    // @has - '//a/@href' '../../some_macros/derive.SomeDerive.html'
+    pub use some_derive;
+}
diff --git a/src/test/rustdoc/synthetic_auto/self-referential.rs b/src/test/rustdoc/synthetic_auto/self-referential.rs
new file mode 100644
index 0000000..516a3c9
--- /dev/null
+++ b/src/test/rustdoc/synthetic_auto/self-referential.rs
@@ -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.
+
+// Some unusual code minimized from
+// https://github.com/sile/handy_async/tree/7b619b762c06544fc67792c8ff8ebc24a88fdb98
+
+pub trait Pattern {
+    type Value;
+}
+
+pub struct Constrain<A, B = A, C = A>(A, B, C);
+
+impl<A, B, C> Pattern for Constrain<A, B, C>
+    where A: Pattern,
+          B: Pattern<Value = A::Value>,
+          C: Pattern<Value = A::Value>,
+{
+    type Value = A::Value;
+}
+
+pub struct Wrapper<T>(T);
+
+impl<T> Pattern for Wrapper<T> {
+    type Value = T;
+}
+
+
+// @has self_referential/struct.WriteAndThen.html
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<P1> Send for \
+// WriteAndThen<P1>  where  <P1 as Pattern>::Value: Send"
+pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
+    where P1: Pattern;
+
diff --git a/src/test/compile-fail-fulldeps/auxiliary/attr_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/attr_plugin_test.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/auxiliary/attr_plugin_test.rs
rename to src/test/ui-fulldeps/auxiliary/attr_plugin_test.rs
diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs b/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs
rename to src/test/ui-fulldeps/auxiliary/lint_for_crate.rs
diff --git a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs b/src/test/ui-fulldeps/auxiliary/macro_crate_test.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs
rename to src/test/ui-fulldeps/auxiliary/macro_crate_test.rs
diff --git a/src/test/compile-fail-fulldeps/auxiliary/rlib_crate_test.rs b/src/test/ui-fulldeps/auxiliary/rlib_crate_test.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/auxiliary/rlib_crate_test.rs
rename to src/test/ui-fulldeps/auxiliary/rlib_crate_test.rs
diff --git a/src/test/compile-fail-fulldeps/dropck_tarena_cycle_checked.rs b/src/test/ui-fulldeps/dropck_tarena_cycle_checked.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/dropck_tarena_cycle_checked.rs
rename to src/test/ui-fulldeps/dropck_tarena_cycle_checked.rs
diff --git a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr b/src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr
new file mode 100644
index 0000000..eae33ba
--- /dev/null
+++ b/src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr
@@ -0,0 +1,13 @@
+error[E0597]: `arena` does not live long enough
+  --> $DIR/dropck_tarena_cycle_checked.rs:126:8
+   |
+LL |     f(&arena);
+   |        ^^^^^ borrowed value does not live long enough
+LL | } //~^ ERROR `arena` does not live long enough
+   | - `arena` dropped here while still borrowed
+   |
+   = note: values in a scope are dropped in the opposite order they are created
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/compile-fail-fulldeps/dropck_tarena_unsound_drop.rs b/src/test/ui-fulldeps/dropck_tarena_unsound_drop.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/dropck_tarena_unsound_drop.rs
rename to src/test/ui-fulldeps/dropck_tarena_unsound_drop.rs
diff --git a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr b/src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr
new file mode 100644
index 0000000..75ceb69
--- /dev/null
+++ b/src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr
@@ -0,0 +1,13 @@
+error[E0597]: `arena` does not live long enough
+  --> $DIR/dropck_tarena_unsound_drop.rs:51:8
+   |
+LL |     f(&arena);
+   |        ^^^^^ borrowed value does not live long enough
+LL | } //~^ ERROR `arena` does not live long enough
+   | - `arena` dropped here while still borrowed
+   |
+   = note: values in a scope are dropped in the opposite order they are created
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/compile-fail-fulldeps/gated-plugin.rs b/src/test/ui-fulldeps/gated-plugin.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/gated-plugin.rs
rename to src/test/ui-fulldeps/gated-plugin.rs
diff --git a/src/test/ui-fulldeps/gated-plugin.stderr b/src/test/ui-fulldeps/gated-plugin.stderr
new file mode 100644
index 0000000..075bc79
--- /dev/null
+++ b/src/test/ui-fulldeps/gated-plugin.stderr
@@ -0,0 +1,11 @@
+error[E0658]: compiler plugins are experimental and possibly buggy (see issue #29597)
+  --> $DIR/gated-plugin.rs:13:1
+   |
+LL | #![plugin(macro_crate_test)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(plugin)] 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/compile-fail-fulldeps/gated-quote.rs b/src/test/ui-fulldeps/gated-quote.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/gated-quote.rs
rename to src/test/ui-fulldeps/gated-quote.rs
diff --git a/src/test/ui-fulldeps/gated-quote.stderr b/src/test/ui-fulldeps/gated-quote.stderr
new file mode 100644
index 0000000..db09193
--- /dev/null
+++ b/src/test/ui-fulldeps/gated-quote.stderr
@@ -0,0 +1,80 @@
+error: cannot find macro `quote_path!` in this scope
+  --> $DIR/gated-quote.rs:65:13
+   |
+LL |     let x = quote_path!(ecx, 3);
+   |             ^^^^^^^^^^
+
+error: cannot find macro `quote_meta_item!` in this scope
+  --> $DIR/gated-quote.rs:63:13
+   |
+LL |     let x = quote_meta_item!(ecx, 3);
+   |             ^^^^^^^^^^^^^^^
+
+error: cannot find macro `quote_block!` in this scope
+  --> $DIR/gated-quote.rs:61:13
+   |
+LL |     let x = quote_block!(ecx, 3);
+   |             ^^^^^^^^^^^
+
+error: cannot find macro `quote_arg!` in this scope
+  --> $DIR/gated-quote.rs:59:13
+   |
+LL |     let x = quote_arg!(ecx, 3);
+   |             ^^^^^^^^^
+
+error: cannot find macro `quote_attr!` in this scope
+  --> $DIR/gated-quote.rs:57:13
+   |
+LL |     let x = quote_attr!(ecx, 3);
+   |             ^^^^^^^^^^
+
+error: cannot find macro `quote_stmt!` in this scope
+  --> $DIR/gated-quote.rs:55:13
+   |
+LL |     let x = quote_stmt!(ecx, 3);
+   |             ^^^^^^^^^^
+
+error: cannot find macro `quote_arm!` in this scope
+  --> $DIR/gated-quote.rs:53:13
+   |
+LL |     let x = quote_arm!(ecx, 3);
+   |             ^^^^^^^^^
+
+error: cannot find macro `quote_pat!` in this scope
+  --> $DIR/gated-quote.rs:51:13
+   |
+LL |     let x = quote_pat!(ecx, 3);
+   |             ^^^^^^^^^
+
+error: cannot find macro `quote_item!` in this scope
+  --> $DIR/gated-quote.rs:49:13
+   |
+LL |     let x = quote_item!(ecx, 3);
+   |             ^^^^^^^^^^
+
+error: cannot find macro `quote_method!` in this scope
+  --> $DIR/gated-quote.rs:47:13
+   |
+LL |     let x = quote_method!(ecx, 3);
+   |             ^^^^^^^^^^^^
+
+error: cannot find macro `quote_ty!` in this scope
+  --> $DIR/gated-quote.rs:45:13
+   |
+LL |     let x = quote_ty!(ecx, 3);
+   |             ^^^^^^^^
+
+error: cannot find macro `quote_expr!` in this scope
+  --> $DIR/gated-quote.rs:43:13
+   |
+LL |     let x = quote_expr!(ecx, 3);
+   |             ^^^^^^^^^^
+
+error: cannot find macro `quote_tokens!` in this scope
+  --> $DIR/gated-quote.rs:41:13
+   |
+LL |     let x = quote_tokens!(ecx, 3);
+   |             ^^^^^^^^^^^^
+
+error: aborting due to 13 previous errors
+
diff --git a/src/test/compile-fail-fulldeps/issue-15778-fail.rs b/src/test/ui-fulldeps/issue-15778-fail.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/issue-15778-fail.rs
rename to src/test/ui-fulldeps/issue-15778-fail.rs
diff --git a/src/test/ui-fulldeps/issue-15778-fail.stderr b/src/test/ui-fulldeps/issue-15778-fail.stderr
new file mode 100644
index 0000000..49a2b26
--- /dev/null
+++ b/src/test/ui-fulldeps/issue-15778-fail.stderr
@@ -0,0 +1,13 @@
+error: crate is not marked with #![crate_okay]
+  --> $DIR/issue-15778-fail.rs:15:1
+   |
+LL | / #![feature(plugin)] //~ ERROR crate is not marked with #![crate_okay]
+LL | | #![plugin(lint_for_crate)]
+LL | |
+LL | | pub fn main() { }
+   | |_________________^
+   |
+   = note: requested on the command line with `-D crate-not-okay`
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail-fulldeps/issue-48941.rs b/src/test/ui-fulldeps/issue-48941.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/issue-48941.rs
rename to src/test/ui-fulldeps/issue-48941.rs
diff --git a/src/test/ui-fulldeps/issue-48941.stderr b/src/test/ui-fulldeps/issue-48941.stderr
new file mode 100644
index 0000000..606c51f
--- /dev/null
+++ b/src/test/ui-fulldeps/issue-48941.stderr
@@ -0,0 +1,14 @@
+error: expected unsuffixed literal or identifier, found a
+  --> $DIR/issue-48941.rs:20:24
+   |
+LL | #[noop_attribute("hi", rank = a)] //~ ERROR expected unsuffixed literal or identifier, found a
+   |                        ^^^^
+
+error: expected unsuffixed literal or identifier, found =
+  --> $DIR/issue-48941.rs:23:27
+   |
+LL | #[noop_attribute("/user", data= = "<user")] //~ ERROR literal or identifier
+   |                           ^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/compile-fail-fulldeps/lint-group-plugin-deny-cmdline.rs b/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/lint-group-plugin-deny-cmdline.rs
rename to src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs
diff --git a/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.stderr b/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.stderr
new file mode 100644
index 0000000..446fc75
--- /dev/null
+++ b/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.stderr
@@ -0,0 +1,18 @@
+error: item is named 'lintme'
+  --> $DIR/lint-group-plugin-deny-cmdline.rs:18:1
+   |
+LL | fn lintme() { } //~ ERROR item is named 'lintme'
+   | ^^^^^^^^^^^^^^^
+   |
+   = note: `-D test-lint` implied by `-D lint-me`
+
+error: item is named 'pleaselintme'
+  --> $DIR/lint-group-plugin-deny-cmdline.rs:20:1
+   |
+LL | fn pleaselintme() { } //~ ERROR item is named 'pleaselintme'
+   | ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D please-lint` implied by `-D lint-me`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/compile-fail-fulldeps/lint-plugin-deny-attr.rs b/src/test/ui-fulldeps/lint-plugin-deny-attr.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/lint-plugin-deny-attr.rs
rename to src/test/ui-fulldeps/lint-plugin-deny-attr.rs
diff --git a/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr b/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr
new file mode 100644
index 0000000..e0ea1e0
--- /dev/null
+++ b/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr
@@ -0,0 +1,14 @@
+error: item is named 'lintme'
+  --> $DIR/lint-plugin-deny-attr.rs:18:1
+   |
+LL | fn lintme() { } //~ ERROR item is named 'lintme'
+   | ^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-plugin-deny-attr.rs:16:9
+   |
+LL | #![deny(test_lint)]
+   |         ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail-fulldeps/lint-plugin-deny-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/lint-plugin-deny-cmdline.rs
rename to src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs
diff --git a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr
new file mode 100644
index 0000000..9084253
--- /dev/null
+++ b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr
@@ -0,0 +1,10 @@
+error: item is named 'lintme'
+  --> $DIR/lint-plugin-deny-cmdline.rs:18:1
+   |
+LL | fn lintme() { } //~ ERROR item is named 'lintme'
+   | ^^^^^^^^^^^^^^^
+   |
+   = note: requested on the command line with `-D test-lint`
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail-fulldeps/lint-plugin-forbid-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/lint-plugin-forbid-cmdline.rs
rename to src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr
new file mode 100644
index 0000000..30043db
--- /dev/null
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr
@@ -0,0 +1,19 @@
+error[E0453]: allow(test_lint) overruled by outer forbid(test_lint)
+  --> $DIR/lint-plugin-forbid-cmdline.rs:20:9
+   |
+LL | #[allow(test_lint)] //~ ERROR allow(test_lint) overruled by outer forbid(test_lint)
+   |         ^^^^^^^^^ overruled by previous forbid
+   |
+   = note: `forbid` lint level was set on command line
+
+error: item is named 'lintme'
+  --> $DIR/lint-plugin-forbid-cmdline.rs:18:1
+   |
+LL | fn lintme() { } //~ ERROR item is named 'lintme'
+   | ^^^^^^^^^^^^^^^
+   |
+   = note: requested on the command line with `-F test-lint`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs b/src/test/ui-fulldeps/macro-crate-doesnt-resolve.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs
rename to src/test/ui-fulldeps/macro-crate-doesnt-resolve.rs
diff --git a/src/test/ui-fulldeps/macro-crate-doesnt-resolve.stderr b/src/test/ui-fulldeps/macro-crate-doesnt-resolve.stderr
new file mode 100644
index 0000000..c45cfa9
--- /dev/null
+++ b/src/test/ui-fulldeps/macro-crate-doesnt-resolve.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find function `foo` in module `macro_crate_test`
+  --> $DIR/macro-crate-doesnt-resolve.rs:17:23
+   |
+LL |     macro_crate_test::foo(); //~ ERROR cannot find function `foo` in module `macro_crate_test`
+   |                       ^^^ not found in `macro_crate_test`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/compile-fail-fulldeps/macro-crate-rlib.rs b/src/test/ui-fulldeps/macro-crate-rlib.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/macro-crate-rlib.rs
rename to src/test/ui-fulldeps/macro-crate-rlib.rs
diff --git a/src/test/ui-fulldeps/macro-crate-rlib.stderr b/src/test/ui-fulldeps/macro-crate-rlib.stderr
new file mode 100644
index 0000000..8a7f788
--- /dev/null
+++ b/src/test/ui-fulldeps/macro-crate-rlib.stderr
@@ -0,0 +1,9 @@
+error[E0457]: plugin `rlib_crate_test` only found in rlib format, but must be available in dylib format
+  --> $DIR/macro-crate-rlib.rs:16:11
+   |
+LL | #![plugin(rlib_crate_test)]
+   |           ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0457`.
diff --git a/src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs b/src/test/ui-fulldeps/macro-crate-unexported-macro.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs
rename to src/test/ui-fulldeps/macro-crate-unexported-macro.rs
diff --git a/src/test/ui-fulldeps/macro-crate-unexported-macro.stderr b/src/test/ui-fulldeps/macro-crate-unexported-macro.stderr
new file mode 100644
index 0000000..8d87c88
--- /dev/null
+++ b/src/test/ui-fulldeps/macro-crate-unexported-macro.stderr
@@ -0,0 +1,8 @@
+error: cannot find macro `unexported_macro!` in this scope
+  --> $DIR/macro-crate-unexported-macro.rs:17:5
+   |
+LL |     unexported_macro!();
+   |     ^^^^^^^^^^^^^^^^ help: you could try the macro: `exported_macro`
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail-fulldeps/plugin-as-extern-crate.rs b/src/test/ui-fulldeps/plugin-as-extern-crate.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/plugin-as-extern-crate.rs
rename to src/test/ui-fulldeps/plugin-as-extern-crate.rs
diff --git a/src/test/ui-fulldeps/plugin-as-extern-crate.stderr b/src/test/ui-fulldeps/plugin-as-extern-crate.stderr
new file mode 100644
index 0000000..713f1b0
--- /dev/null
+++ b/src/test/ui-fulldeps/plugin-as-extern-crate.stderr
@@ -0,0 +1,14 @@
+error: compiler plugin used as an ordinary library
+  --> $DIR/plugin-as-extern-crate.rs:20:1
+   |
+LL | extern crate macro_crate_test; //~ ERROR compiler plugin used as an ordinary library
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/plugin-as-extern-crate.rs:17:9
+   |
+LL | #![deny(plugin_as_library)]
+   |         ^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail-fulldeps/plugin-attr-register-deny.rs b/src/test/ui-fulldeps/plugin-attr-register-deny.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/plugin-attr-register-deny.rs
rename to src/test/ui-fulldeps/plugin-attr-register-deny.rs
diff --git a/src/test/ui-fulldeps/plugin-attr-register-deny.stderr b/src/test/ui-fulldeps/plugin-attr-register-deny.stderr
new file mode 100644
index 0000000..0bb2d1c
--- /dev/null
+++ b/src/test/ui-fulldeps/plugin-attr-register-deny.stderr
@@ -0,0 +1,26 @@
+error: unused attribute
+  --> $DIR/plugin-attr-register-deny.rs:24:5
+   |
+LL |     #[bar]
+   |     ^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/plugin-attr-register-deny.rs:16:9
+   |
+LL | #![deny(unused_attributes)]
+   |         ^^^^^^^^^^^^^^^^^
+
+error: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
+  --> $DIR/plugin-attr-register-deny.rs:24:5
+   |
+LL |     #[bar]
+   |     ^^^^^^
+
+error: unused attribute
+  --> $DIR/plugin-attr-register-deny.rs:21:1
+   |
+LL | #[foo]
+   | ^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/compile-fail-fulldeps/plugin-plus-extern-crate.rs b/src/test/ui-fulldeps/plugin-plus-extern-crate.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/plugin-plus-extern-crate.rs
rename to src/test/ui-fulldeps/plugin-plus-extern-crate.rs
diff --git a/src/test/ui-fulldeps/plugin-plus-extern-crate.stderr b/src/test/ui-fulldeps/plugin-plus-extern-crate.stderr
new file mode 100644
index 0000000..faefe04
--- /dev/null
+++ b/src/test/ui-fulldeps/plugin-plus-extern-crate.stderr
@@ -0,0 +1,14 @@
+error: compiler plugin used as an ordinary library
+  --> $DIR/plugin-plus-extern-crate.rs:22:1
+   |
+LL | extern crate macro_crate_test; //~ ERROR compiler plugin used as an ordinary library
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/plugin-plus-extern-crate.rs:18:9
+   |
+LL | #![deny(plugin_as_library)]
+   |         ^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail-fulldeps/qquote.rs b/src/test/ui-fulldeps/qquote.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/qquote.rs
rename to src/test/ui-fulldeps/qquote.rs
diff --git a/src/test/ui-fulldeps/qquote.stderr b/src/test/ui-fulldeps/qquote.stderr
new file mode 100644
index 0000000..4c136ad
--- /dev/null
+++ b/src/test/ui-fulldeps/qquote.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `abcd` in this scope
+  --> $DIR/qquote.rs:35:38
+   |
+LL |     let expr = quote_expr!(&cx, 2 - $abcd + 7); //~ ERROR cannot find value `abcd` in this scope
+   |                                      ^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/anon-params-denied-2018.stderr b/src/test/ui/anon-params-denied-2018.stderr
index 24a1e6e..dd9e933 100644
--- a/src/test/ui/anon-params-denied-2018.stderr
+++ b/src/test/ui/anon-params-denied-2018.stderr
@@ -2,13 +2,21 @@
   --> $DIR/anon-params-denied-2018.rs:6:15
    |
 LL |     fn foo(i32); //~ expected one of `:` or `@`, found `)`
-   |               ^ expected one of `:` or `@` here
+   |            ---^ expected one of `:` or `@` here
+   |            |
+   |            help: explicitly ignore parameter: `_: i32`
+   |
+   = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 
 error: expected one of `:` or `@`, found `,`
   --> $DIR/anon-params-denied-2018.rs:8:36
    |
 LL |     fn bar_with_default_impl(String, String) {}
-   |                                    ^ expected one of `:` or `@` here
+   |                              ------^ expected one of `:` or `@` here
+   |                              |
+   |                              help: explicitly ignore parameter: `_: String`
+   |
+   = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/compile-fail-fulldeps/auxiliary/pub_and_stability.rs b/src/test/ui/auxiliary/pub_and_stability.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/auxiliary/pub_and_stability.rs
rename to src/test/ui/auxiliary/pub_and_stability.rs
diff --git a/src/test/compile-fail-fulldeps/auxiliary/use_from_trait_xc.rs b/src/test/ui/auxiliary/use_from_trait_xc.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/auxiliary/use_from_trait_xc.rs
rename to src/test/ui/auxiliary/use_from_trait_xc.rs
diff --git a/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs b/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs
index 30752e8..fd4c108 100644
--- a/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs
+++ b/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs
@@ -49,7 +49,7 @@
 //
 // - [x] Resolving overloaded_call_traits (call, call_mut, call_once)
 // - [x] deref_coercion (shown above)
-// - [x] coerce_unsized e.g. `&[T; n]`, `&mut [T; n] -> &[T]`,
+// - [x] coerce_unsized e.g., `&[T; n]`, `&mut [T; n] -> &[T]`,
 //                      `&mut [T; n] -> &mut [T]`, `&Concrete -> &Trait`
 // - [x] Method Call Receivers (the case we want to support!)
 // - [x] ExprKind::Index and ExprKind::Unary Deref; only need to handle coerce_index_op
diff --git a/src/test/ui/coherence/coherence-all-remote.stderr b/src/test/ui/coherence/coherence-all-remote.stderr
index 1f71969..718ab3d 100644
--- a/src/test/ui/coherence/coherence-all-remote.stderr
+++ b/src/test/ui/coherence/coherence-all-remote.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/coherence-all-remote.rs:16:1
    |
 LL | impl<T> Remote1<T> for isize { }
diff --git a/src/test/ui/coherence/coherence-bigint-param.stderr b/src/test/ui/coherence/coherence-bigint-param.stderr
index 7d2796e..a5d9f5a 100644
--- a/src/test/ui/coherence/coherence-bigint-param.stderr
+++ b/src/test/ui/coherence/coherence-bigint-param.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/coherence-bigint-param.rs:18:1
    |
 LL | impl<T> Remote1<BigInt> for T { }
diff --git a/src/test/ui/coherence/coherence-cow.a.stderr b/src/test/ui/coherence/coherence-cow.a.stderr
index f053333..368935f 100644
--- a/src/test/ui/coherence/coherence-cow.a.stderr
+++ b/src/test/ui/coherence/coherence-cow.a.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/coherence-cow.rs:26:1
    |
 LL | impl<T> Remote for Pair<T,Cover<T>> { } //[a]~ ERROR E0210
diff --git a/src/test/ui/coherence/coherence-cow.b.stderr b/src/test/ui/coherence/coherence-cow.b.stderr
index 269bcd5..74ad850 100644
--- a/src/test/ui/coherence/coherence-cow.b.stderr
+++ b/src/test/ui/coherence/coherence-cow.b.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/coherence-cow.rs:29:1
    |
 LL | impl<T> Remote for Pair<Cover<T>,T> { } //[b]~ ERROR E0210
diff --git a/src/test/ui/coherence/coherence-cow.c.stderr b/src/test/ui/coherence/coherence-cow.c.stderr
index e89308d..2e3a6b5 100644
--- a/src/test/ui/coherence/coherence-cow.c.stderr
+++ b/src/test/ui/coherence/coherence-cow.c.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/coherence-cow.rs:32:1
    |
 LL | impl<T,U> Remote for Pair<Cover<T>,U> { }
diff --git a/src/test/ui/coherence/coherence-cross-crate-conflict.stderr b/src/test/ui/coherence/coherence-cross-crate-conflict.stderr
index ee11967..31c41ab 100644
--- a/src/test/ui/coherence/coherence-cross-crate-conflict.stderr
+++ b/src/test/ui/coherence/coherence-cross-crate-conflict.stderr
@@ -7,7 +7,7 @@
    = note: conflicting implementation in crate `trait_impl_conflict`:
            - impl trait_impl_conflict::Foo for isize;
 
-error[E0210]: type parameter `A` must be used as the type parameter for some local type (e.g. `MyStruct<A>`)
+error[E0210]: type parameter `A` must be used as the type parameter for some local type (e.g., `MyStruct<A>`)
   --> $DIR/coherence-cross-crate-conflict.rs:18:1
    |
 LL | impl<A> Foo for A {
diff --git a/src/test/ui/coherence/coherence-lone-type-parameter.stderr b/src/test/ui/coherence/coherence-lone-type-parameter.stderr
index 6389bc0..e3a7722 100644
--- a/src/test/ui/coherence/coherence-lone-type-parameter.stderr
+++ b/src/test/ui/coherence/coherence-lone-type-parameter.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/coherence-lone-type-parameter.rs:16:1
    |
 LL | impl<T> Remote for T { }
diff --git a/src/test/ui/coherence/coherence-overlapping-pairs.stderr b/src/test/ui/coherence/coherence-overlapping-pairs.stderr
index 41d4788..286ebef 100644
--- a/src/test/ui/coherence/coherence-overlapping-pairs.stderr
+++ b/src/test/ui/coherence/coherence-overlapping-pairs.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/coherence-overlapping-pairs.rs:18:1
    |
 LL | impl<T> Remote for lib::Pair<T,Foo> { }
diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr
index 3545593..80ab0cc 100644
--- a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr
+++ b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/coherence-pair-covered-uncovered-1.rs:21:1
    |
 LL | impl<T, U> Remote1<Pair<T, Local<U>>> for i32 { }
diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr
index f58cb46..25b4948 100644
--- a/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr
+++ b/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/coherence-pair-covered-uncovered.rs:18:1
    |
 LL | impl<T,U> Remote for Pair<T,Local<U>> { }
diff --git a/src/test/ui/coherence/coherence-vec-local-2.stderr b/src/test/ui/coherence/coherence-vec-local-2.stderr
index 2980d4a..0ccd938 100644
--- a/src/test/ui/coherence/coherence-vec-local-2.stderr
+++ b/src/test/ui/coherence/coherence-vec-local-2.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/coherence-vec-local-2.rs:21:1
    |
 LL | impl<T> Remote for Vec<Local<T>> { } //~ ERROR E0210
diff --git a/src/test/ui/constructor-lifetime-args.rs b/src/test/ui/constructor-lifetime-args.rs
index 1fe50cf..a03599a 100644
--- a/src/test/ui/constructor-lifetime-args.rs
+++ b/src/test/ui/constructor-lifetime-args.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // All lifetime parameters in struct constructors are currently considered early bound,
-// i.e. `S::<ARGS>` is interpreted kinda like an associated item `S::<ARGS>::ctor`.
+// i.e., `S::<ARGS>` is interpreted kinda like an associated item `S::<ARGS>::ctor`.
 // This behavior is a bit weird, because if equivalent constructor were written manually
 // it would get late bound lifetime parameters.
 // Variant constructors behave in the same way, lifetime parameters are considered
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2.rs b/src/test/ui/consts/const-eval/const-eval-overflow2.rs
index 8e094a7f..7819caf 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow2.rs
+++ b/src/test/ui/consts/const-eval/const-eval-overflow2.rs
@@ -11,7 +11,7 @@
 #![allow(unused_imports)]
 
 // Note: the relevant lint pass here runs before some of the constant
-// evaluation below (e.g. that performed by codegen and llvm), so if you
+// evaluation below (e.g., that performed by codegen and llvm), so if you
 // change this warn to a deny, then the compiler will exit before
 // those errors are detected.
 
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2b.rs b/src/test/ui/consts/const-eval/const-eval-overflow2b.rs
index c69d030..475a511 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow2b.rs
+++ b/src/test/ui/consts/const-eval/const-eval-overflow2b.rs
@@ -11,7 +11,7 @@
 #![allow(unused_imports)]
 
 // Note: the relevant lint pass here runs before some of the constant
-// evaluation below (e.g. that performed by codegen and llvm), so if you
+// evaluation below (e.g., that performed by codegen and llvm), so if you
 // change this warn to a deny, then the compiler will exit before
 // those errors are detected.
 
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2c.rs b/src/test/ui/consts/const-eval/const-eval-overflow2c.rs
index f442661..039e6b2 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow2c.rs
+++ b/src/test/ui/consts/const-eval/const-eval-overflow2c.rs
@@ -11,7 +11,7 @@
 #![allow(unused_imports)]
 
 // Note: the relevant lint pass here runs before some of the constant
-// evaluation below (e.g. that performed by codegen and llvm), so if you
+// evaluation below (e.g., that performed by codegen and llvm), so if you
 // change this warn to a deny, then the compiler will exit before
 // those errors are detected.
 
diff --git a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.nll.stderr b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.nll.stderr
index 8c4806c..d1250b9 100644
--- a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.nll.stderr
+++ b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.nll.stderr
@@ -4,7 +4,7 @@
 LL | const fn bar() -> u32 { foo() } //~ ERROR `foo` is not yet stable as a const fn
    |                         ^^^^^
    |
-   = help: in Nightly builds, add `#![feature(foo)]` to the crate attributes to enable
+   = help: add `#![feature(foo)]` to the crate attributes to enable
 
 error[E0716]: temporary value dropped while borrowed
   --> $DIR/dont_promote_unstable_const_fn.rs:28:28
diff --git a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr
index b3d7ba3..85b63f5 100644
--- a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr
+++ b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr
@@ -4,7 +4,7 @@
 LL | const fn bar() -> u32 { foo() } //~ ERROR `foo` is not yet stable as a const fn
    |                         ^^^^^
    |
-   = help: in Nightly builds, add `#![feature(foo)]` to the crate attributes to enable
+   = help: add `#![feature(foo)]` to the crate attributes to enable
 
 error[E0597]: borrowed value does not live long enough
   --> $DIR/dont_promote_unstable_const_fn.rs:28:28
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..2f08d12 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
-    fn f() {} // Check that the `NOTE`s still work with an item here (c.f. issue #35115).
+    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 (cf. 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/const-typeid-of.stderr b/src/test/ui/consts/const-typeid-of.stderr
index d13ced9..ba5f659 100644
--- a/src/test/ui/consts/const-typeid-of.stderr
+++ b/src/test/ui/consts/const-typeid-of.stderr
@@ -4,7 +4,7 @@
 LL |     const A_ID: TypeId = TypeId::of::<A>();
    |                          ^^^^^^^^^^^^^^^^^
    |
-   = help: in Nightly builds, add `#![feature(const_type_id)]` to the crate attributes to enable
+   = help: add `#![feature(const_type_id)]` to the crate attributes to enable
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/dropck/dropck-eyepatch.rs b/src/test/ui/dropck/dropck-eyepatch.rs
index d7a671f..fb1c03b 100644
--- a/src/test/ui/dropck/dropck-eyepatch.rs
+++ b/src/test/ui/dropck/dropck-eyepatch.rs
@@ -31,7 +31,7 @@
 // - D means "I implement Drop"
 //
 // - P means "I implement Drop but guarantee my (first) parameter is
-//     pure, i.e. not accessed from the destructor"; no other parameters
+//     pure, i.e., not accessed from the destructor"; no other parameters
 //     are pure.
 //
 // - S means "I do not implement Drop"
diff --git a/src/test/ui/e0119/complex-impl.stderr b/src/test/ui/e0119/complex-impl.stderr
index 1fc4c28..d60f9c4 100644
--- a/src/test/ui/e0119/complex-impl.stderr
+++ b/src/test/ui/e0119/complex-impl.stderr
@@ -8,7 +8,7 @@
            - impl<'a, 'b, 'c, T, U, V, W> complex_impl_support::External for (T, complex_impl_support::M<'a, 'b, 'c, std::boxed::Box<U>, V, W>)
              where <U as std::ops::FnOnce<(T,)>>::Output == V, <V as std::iter::Iterator>::Item == T, 'b : 'a, T : 'a, U: std::ops::FnOnce<(T,)>, U : 'static, V: std::iter::Iterator, V: std::clone::Clone, W: std::ops::Add, <W as std::ops::Add>::Output: std::marker::Copy;
 
-error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g. `MyStruct<R>`)
+error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g., `MyStruct<R>`)
   --> $DIR/complex-impl.rs:19:1
    |
 LL | impl<R> External for (Q, R) {} //~ ERROR must be used
diff --git a/src/test/ui/e0119/issue-28981.stderr b/src/test/ui/e0119/issue-28981.stderr
index 76ff88d..b5ec1c8 100644
--- a/src/test/ui/e0119/issue-28981.stderr
+++ b/src/test/ui/e0119/issue-28981.stderr
@@ -8,7 +8,7 @@
            - impl<T> std::ops::Deref for &T
              where T: ?Sized;
 
-error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct<Foo>`)
+error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g., `MyStruct<Foo>`)
   --> $DIR/issue-28981.rs:15:1
    |
 LL | impl<Foo> Deref for Foo { } //~ ERROR must be used
diff --git a/src/test/ui/error-codes/E0050.stderr b/src/test/ui/error-codes/E0050.stderr
index bff3b7b..6c797e0 100644
--- a/src/test/ui/error-codes/E0050.stderr
+++ b/src/test/ui/error-codes/E0050.stderr
@@ -2,7 +2,7 @@
   --> $DIR/E0050.rs:20:12
    |
 LL |     fn foo(&self, x: u8) -> bool;
-   |                      -- trait requires 2 parameters
+   |            ------------ trait requires 2 parameters
 ...
 LL |     fn foo(&self) -> bool { true } //~ ERROR E0050
    |            ^^^^^ expected 2 parameters, found 1
@@ -11,19 +11,19 @@
   --> $DIR/E0050.rs:21:12
    |
 LL |     fn bar(&self, x: u8, y: u8, z: u8);
-   |                                    -- trait requires 4 parameters
+   |            -------------------------- trait requires 4 parameters
 ...
 LL |     fn bar(&self) { } //~ ERROR E0050
    |            ^^^^^ expected 4 parameters, found 1
 
 error[E0050]: method `less` has 4 parameters but the declaration in trait `Foo::less` has 1
-  --> $DIR/E0050.rs:22:37
+  --> $DIR/E0050.rs:22:13
    |
 LL |     fn less(&self);
    |             ----- trait requires 1 parameter
 ...
 LL |     fn less(&self, x: u8, y: u8, z: u8) { } //~ ERROR E0050
-   |                                     ^^ expected 1 parameter, found 4
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 parameter, found 4
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/error-codes/E0259.rs b/src/test/ui/error-codes/E0259.rs
index 5a47541..b3e633a 100644
--- a/src/test/ui/error-codes/E0259.rs
+++ b/src/test/ui/error-codes/E0259.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(alloc, libc)]
+#![feature(alloc, rustc_private)]
 #![allow(unused_extern_crates)]
 
 extern crate alloc;
diff --git a/src/test/ui/error-codes/E0424.rs b/src/test/ui/error-codes/E0424.rs
index 445d0c5..20d42da 100644
--- a/src/test/ui/error-codes/E0424.rs
+++ b/src/test/ui/error-codes/E0424.rs
@@ -19,4 +19,5 @@
 }
 
 fn main () {
+    let self = "self"; //~ ERROR E0424
 }
diff --git a/src/test/ui/error-codes/E0424.stderr b/src/test/ui/error-codes/E0424.stderr
index a1b7a5f..5eccd7d 100644
--- a/src/test/ui/error-codes/E0424.stderr
+++ b/src/test/ui/error-codes/E0424.stderr
@@ -4,6 +4,12 @@
 LL |         self.bar(); //~ ERROR E0424
    |         ^^^^ `self` value is a keyword only available in methods with `self` parameter
 
-error: aborting due to previous error
+error[E0424]: expected unit struct/variant or constant, found module `self`
+  --> $DIR/E0424.rs:22:9
+   |
+LL |     let self = "self"; //~ ERROR E0424
+   |         ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0424`.
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/compile-fail-fulldeps/explore-issue-38412.rs b/src/test/ui/explore-issue-38412.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/explore-issue-38412.rs
rename to src/test/ui/explore-issue-38412.rs
diff --git a/src/test/ui/explore-issue-38412.stderr b/src/test/ui/explore-issue-38412.stderr
new file mode 100644
index 0000000..8e31c1c
--- /dev/null
+++ b/src/test/ui/explore-issue-38412.stderr
@@ -0,0 +1,132 @@
+error[E0658]: use of unstable library feature 'unstable_undeclared' (see issue #38412)
+  --> $DIR/explore-issue-38412.rs:31:63
+   |
+LL |     let Record { a_stable_pub: _, a_unstable_declared_pub: _, a_unstable_undeclared_pub: _, .. } =
+   |                                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(unstable_undeclared)] to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_undeclared' (see issue #38412)
+  --> $DIR/explore-issue-38412.rs:40:5
+   |
+LL |     r.a_unstable_undeclared_pub; //~ ERROR use of unstable library feature
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(unstable_undeclared)] to the crate attributes to enable
+
+error[E0616]: field `b_crate` of struct `pub_and_stability::Record` is private
+  --> $DIR/explore-issue-38412.rs:41:5
+   |
+LL |     r.b_crate;                   //~ ERROR is private
+   |     ^^^^^^^^^
+
+error[E0616]: field `c_mod` of struct `pub_and_stability::Record` is private
+  --> $DIR/explore-issue-38412.rs:42:5
+   |
+LL |     r.c_mod;                     //~ ERROR is private
+   |     ^^^^^^^
+
+error[E0616]: field `d_priv` of struct `pub_and_stability::Record` is private
+  --> $DIR/explore-issue-38412.rs:43:5
+   |
+LL |     r.d_priv;                    //~ ERROR is private
+   |     ^^^^^^^^
+
+error[E0658]: use of unstable library feature 'unstable_undeclared' (see issue #38412)
+  --> $DIR/explore-issue-38412.rs:47:5
+   |
+LL |     t.2;                         //~ ERROR use of unstable library feature
+   |     ^^^
+   |
+   = help: add #![feature(unstable_undeclared)] to the crate attributes to enable
+
+error[E0616]: field `3` of struct `pub_and_stability::Tuple` is private
+  --> $DIR/explore-issue-38412.rs:48:5
+   |
+LL |     t.3;                         //~ ERROR is private
+   |     ^^^
+
+error[E0616]: field `4` of struct `pub_and_stability::Tuple` is private
+  --> $DIR/explore-issue-38412.rs:49:5
+   |
+LL |     t.4;                         //~ ERROR is private
+   |     ^^^
+
+error[E0616]: field `5` of struct `pub_and_stability::Tuple` is private
+  --> $DIR/explore-issue-38412.rs:50:5
+   |
+LL |     t.5;                         //~ ERROR is private
+   |     ^^^
+
+error[E0658]: use of unstable library feature 'unstable_undeclared' (see issue #38412)
+  --> $DIR/explore-issue-38412.rs:54:7
+   |
+LL |     r.unstable_undeclared_trait_method(); //~ ERROR use of unstable library feature
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(unstable_undeclared)] to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_undeclared' (see issue #38412)
+  --> $DIR/explore-issue-38412.rs:58:7
+   |
+LL |     r.unstable_undeclared();              //~ ERROR use of unstable library feature
+   |       ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(unstable_undeclared)] to the crate attributes to enable
+
+error[E0624]: method `pub_crate` is private
+  --> $DIR/explore-issue-38412.rs:60:7
+   |
+LL |     r.pub_crate();                        //~ ERROR `pub_crate` is private
+   |       ^^^^^^^^^
+
+error[E0624]: method `pub_mod` is private
+  --> $DIR/explore-issue-38412.rs:61:7
+   |
+LL |     r.pub_mod();                          //~ ERROR `pub_mod` is private
+   |       ^^^^^^^
+
+error[E0624]: method `private` is private
+  --> $DIR/explore-issue-38412.rs:62:7
+   |
+LL |     r.private();                          //~ ERROR `private` is private
+   |       ^^^^^^^
+
+error[E0658]: use of unstable library feature 'unstable_undeclared' (see issue #38412)
+  --> $DIR/explore-issue-38412.rs:67:7
+   |
+LL |     t.unstable_undeclared_trait_method(); //~ ERROR use of unstable library feature
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(unstable_undeclared)] to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_undeclared' (see issue #38412)
+  --> $DIR/explore-issue-38412.rs:71:7
+   |
+LL |     t.unstable_undeclared();              //~ ERROR use of unstable library feature
+   |       ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(unstable_undeclared)] to the crate attributes to enable
+
+error[E0624]: method `pub_crate` is private
+  --> $DIR/explore-issue-38412.rs:73:7
+   |
+LL |     t.pub_crate();                        //~ ERROR `pub_crate` is private
+   |       ^^^^^^^^^
+
+error[E0624]: method `pub_mod` is private
+  --> $DIR/explore-issue-38412.rs:74:7
+   |
+LL |     t.pub_mod();                          //~ ERROR `pub_mod` is private
+   |       ^^^^^^^
+
+error[E0624]: method `private` is private
+  --> $DIR/explore-issue-38412.rs:75:7
+   |
+LL |     t.private();                          //~ ERROR `private` is private
+   |       ^^^^^^^
+
+error: aborting due to 19 previous errors
+
+Some errors occurred: E0616, E0624, E0658.
+For more information about an error, try `rustc --explain E0616`.
diff --git a/src/test/ui/extern/auxiliary/invalid-utf8.txt b/src/test/ui/extern/auxiliary/invalid-utf8.txt
new file mode 100644
index 0000000..dc1115b
--- /dev/null
+++ b/src/test/ui/extern/auxiliary/invalid-utf8.txt
@@ -0,0 +1 @@
+Ã(
\ No newline at end of file
diff --git a/src/test/ui/extern/extern-const.fixed b/src/test/ui/extern/extern-const.fixed
index dca5698..fb17934 100644
--- a/src/test/ui/extern/extern-const.fixed
+++ b/src/test/ui/extern/extern-const.fixed
@@ -7,7 +7,7 @@
 // run-rustfix
 // ignore-wasm32 no external library to link to.
 // compile-flags: -g -Z continue-parse-after-error
-#![feature(libc)]
+#![feature(rustc_private)]
 extern crate libc;
 
 #[link(name = "rust_test_helpers", kind = "static")]
diff --git a/src/test/ui/extern/extern-const.rs b/src/test/ui/extern/extern-const.rs
index 07dbe54..f2585f5 100644
--- a/src/test/ui/extern/extern-const.rs
+++ b/src/test/ui/extern/extern-const.rs
@@ -7,7 +7,7 @@
 // run-rustfix
 // ignore-wasm32 no external library to link to.
 // compile-flags: -g -Z continue-parse-after-error
-#![feature(libc)]
+#![feature(rustc_private)]
 extern crate libc;
 
 #[link(name = "rust_test_helpers", kind = "static")]
diff --git a/src/test/ui/extern/external-doc-error.rs b/src/test/ui/extern/external-doc-error.rs
index 5c6f6e4..e17dda6 100644
--- a/src/test/ui/extern/external-doc-error.rs
+++ b/src/test/ui/extern/external-doc-error.rs
@@ -2,7 +2,31 @@
 
 #![feature(external_doc)]
 
-#[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
-pub struct SomeStruct;
+#[doc(include = "not-a-file.md")]
+pub struct SomeStruct; //~^ ERROR couldn't read
+                       //~| HELP external doc paths are relative to the crate root
+
+#[doc(include = "auxiliary/invalid-utf8.txt")]
+pub struct InvalidUtf8; //~^ ERROR wasn't a utf-8 file
+
+#[doc(include)]
+pub struct MissingPath; //~^ ERROR expected path
+                        //~| HELP provide a file path with `=`
+                        //~| SUGGESTION include = "<path>"
+
+#[doc(include("../README.md"))]
+pub struct InvalidPathSyntax; //~^ ERROR expected path
+                              //~| HELP provide a file path with `=`
+                              //~| SUGGESTION include = "../README.md"
+
+#[doc(include = 123)]
+pub struct InvalidPathType; //~^ ERROR expected path
+                            //~| HELP provide a file path with `=`
+                            //~| SUGGESTION include = "<path>"
+
+#[doc(include(123))]
+pub struct InvalidPathSyntaxAndType; //~^ ERROR expected path
+                                     //~| HELP provide a file path with `=`
+                                     //~| SUGGESTION include = "<path>"
 
 fn main() {}
diff --git a/src/test/ui/extern/external-doc-error.stderr b/src/test/ui/extern/external-doc-error.stderr
index 5cc7551..a3be327 100644
--- a/src/test/ui/extern/external-doc-error.stderr
+++ b/src/test/ui/extern/external-doc-error.stderr
@@ -1,8 +1,40 @@
 error: couldn't read $DIR/not-a-file.md: $FILE_NOT_FOUND_MSG (os error 2)
-  --> $DIR/external-doc-error.rs:5:1
+  --> $DIR/external-doc-error.rs:5:17
    |
-LL | #[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[doc(include = "not-a-file.md")]
+   |                 ^^^^^^^^^^^^^^^ couldn't read file
+   |
+   = help: external doc paths are relative to the crate root
 
-error: aborting due to previous error
+error: $DIR/auxiliary/invalid-utf8.txt wasn't a utf-8 file
+  --> $DIR/external-doc-error.rs:9:17
+   |
+LL | #[doc(include = "auxiliary/invalid-utf8.txt")]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ contains invalid utf-8
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:12:7
+   |
+LL | #[doc(include)]
+   |       ^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:17:7
+   |
+LL | #[doc(include("../README.md"))]
+   |       ^^^^^^^^^^^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "../README.md"`
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:22:7
+   |
+LL | #[doc(include = 123)]
+   |       ^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:27:7
+   |
+LL | #[doc(include(123))]
+   |       ^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
+
+error: aborting due to 6 previous errors
 
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-gates/feature-gate-custom_derive.rs b/src/test/ui/feature-gates/feature-gate-custom_derive.rs
deleted file mode 100644
index 0b1b314..0000000
--- a/src/test/ui/feature-gates/feature-gate-custom_derive.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[derive_Clone]
-//~^ ERROR attributes of the form `#[derive_*]` are reserved
-struct Test;
-
-pub fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-custom_derive.stderr b/src/test/ui/feature-gates/feature-gate-custom_derive.stderr
deleted file mode 100644
index 0979372..0000000
--- a/src/test/ui/feature-gates/feature-gate-custom_derive.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644)
-  --> $DIR/feature-gate-custom_derive.rs:11:3
-   |
-LL | #[derive_Clone]
-   |   ^^^^^^^^^^^^
-   |
-   = help: add #![feature(custom_derive)] 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-linker-flavor.rs b/src/test/ui/feature-gates/feature-gate-linker-flavor.rs
deleted file mode 100644
index 56ede01..0000000
--- a/src/test/ui/feature-gates/feature-gate-linker-flavor.rs
+++ /dev/null
@@ -1,20 +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.
-
-// This is a fake compile fail test as there's no way to generate a
-// `#![feature(linker_flavor)]` error. The only reason we have a `linker_flavor`
-// feature gate is to be able to document `-Z linker-flavor` in the unstable
-// 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-linker-flavor.stderr b/src/test/ui/feature-gates/feature-gate-linker-flavor.stderr
deleted file mode 100644
index 7019a66..0000000
--- a/src/test/ui/feature-gates/feature-gate-linker-flavor.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: attribute must be applied to a `static` variable
-  --> $DIR/feature-gate-linker-flavor.rs:16:1
-   |
-LL | #[used]
-   | ^^^^^^^
-
-error: aborting due to previous error
-
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-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/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/imports/issue-56125.rs b/src/test/ui/imports/issue-56125.rs
index 843b52f..0327522 100644
--- a/src/test/ui/imports/issue-56125.rs
+++ b/src/test/ui/imports/issue-56125.rs
@@ -7,13 +7,11 @@
 mod m1 {
     use issue_56125::last_segment::*;
     //~^ ERROR `issue_56125` is ambiguous
-    //~| ERROR unresolved import `issue_56125::last_segment`
 }
 
 mod m2 {
     use issue_56125::non_last_segment::non_last_segment::*;
     //~^ ERROR `issue_56125` is ambiguous
-    //~| ERROR failed to resolve: could not find `non_last_segment` in `issue_56125`
 }
 
 mod m3 {
diff --git a/src/test/ui/imports/issue-56125.stderr b/src/test/ui/imports/issue-56125.stderr
index b1292ef..559979e 100644
--- a/src/test/ui/imports/issue-56125.stderr
+++ b/src/test/ui/imports/issue-56125.stderr
@@ -1,17 +1,5 @@
-error[E0433]: failed to resolve: could not find `non_last_segment` in `issue_56125`
-  --> $DIR/issue-56125.rs:14:22
-   |
-LL |     use issue_56125::non_last_segment::non_last_segment::*;
-   |                      ^^^^^^^^^^^^^^^^ could not find `non_last_segment` in `issue_56125`
-
-error[E0432]: unresolved import `issue_56125::last_segment`
-  --> $DIR/issue-56125.rs:8:22
-   |
-LL |     use issue_56125::last_segment::*;
-   |                      ^^^^^^^^^^^^ could not find `last_segment` in `issue_56125`
-
 error[E0432]: unresolved import `empty::issue_56125`
-  --> $DIR/issue-56125.rs:21:9
+  --> $DIR/issue-56125.rs:19:9
    |
 LL |     use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125`
    |         ^^^^^^^^^^^^^^^^^^ no `issue_56125` in `m3::empty`
@@ -32,7 +20,7 @@
    = help: use `self::issue_56125` to refer to this module unambiguously
 
 error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution)
-  --> $DIR/issue-56125.rs:14:9
+  --> $DIR/issue-56125.rs:13:9
    |
 LL |     use issue_56125::non_last_segment::non_last_segment::*;
    |         ^^^^^^^^^^^ ambiguous name
@@ -40,14 +28,14 @@
    = note: `issue_56125` could refer to an extern crate passed with `--extern`
    = help: use `::issue_56125` to refer to this extern crate unambiguously
 note: `issue_56125` could also refer to the module imported here
-  --> $DIR/issue-56125.rs:14:9
+  --> $DIR/issue-56125.rs:13:9
    |
 LL |     use issue_56125::non_last_segment::non_last_segment::*;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: use `self::issue_56125` to refer to this module unambiguously
 
 error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution)
-  --> $DIR/issue-56125.rs:22:9
+  --> $DIR/issue-56125.rs:20:9
    |
 LL |     use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
    |         ^^^^^^^^^^^ ambiguous name
@@ -55,13 +43,13 @@
    = note: `issue_56125` could refer to an extern crate passed with `--extern`
    = help: use `::issue_56125` to refer to this extern crate unambiguously
 note: `issue_56125` could also refer to the unresolved item imported here
-  --> $DIR/issue-56125.rs:21:9
+  --> $DIR/issue-56125.rs:19:9
    |
 LL |     use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125`
    |         ^^^^^^^^^^^^^^^^^^
    = help: use `self::issue_56125` to refer to this unresolved item unambiguously
 
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
-Some errors occurred: E0432, E0433, E0659.
+Some errors occurred: E0432, E0659.
 For more information about an error, try `rustc --explain E0432`.
diff --git a/src/test/ui/imports/unused.rs b/src/test/ui/imports/unused.rs
index 1eb756f..d241ab6 100644
--- a/src/test/ui/imports/unused.rs
+++ b/src/test/ui/imports/unused.rs
@@ -23,7 +23,7 @@
     }
 
     mod m3 {
-        pub(super) use super::f; // Check that this is counted as used (c.f. #36249).
+        pub(super) use super::f; // Check that this is counted as used (cf. issue #36249).
     }
 
     pub mod m4 {
diff --git a/src/test/compile-fail-fulldeps/issue-18986.rs b/src/test/ui/issue-18986.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/issue-18986.rs
rename to src/test/ui/issue-18986.rs
diff --git a/src/test/ui/issue-18986.stderr b/src/test/ui/issue-18986.stderr
new file mode 100644
index 0000000..241cc42
--- /dev/null
+++ b/src/test/ui/issue-18986.stderr
@@ -0,0 +1,9 @@
+error[E0574]: expected struct, variant or union type, found trait `Trait`
+  --> $DIR/issue-18986.rs:18:9
+   |
+LL |         Trait { x: 42 } => () //~ ERROR expected struct, variant or union type, found trait `Trait`
+   |         ^^^^^ not a struct, variant or union type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/issue-55846.rs b/src/test/ui/issue-55846.rs
new file mode 100644
index 0000000..bd76675
--- /dev/null
+++ b/src/test/ui/issue-55846.rs
@@ -0,0 +1,39 @@
+// run-pass
+
+// Regression test for #55846, which once caused an ICE.
+
+use std::marker::PhantomData;
+
+struct Foo;
+
+struct Bar<A> {
+    a: PhantomData<A>,
+}
+
+impl Fooifier for Foo {
+    type Assoc = Foo;
+}
+
+trait Fooifier {
+    type Assoc;
+}
+
+trait Barifier<H> {
+    fn barify();
+}
+
+impl<H> Barifier<H> for Bar<H> {
+    fn barify() {
+        println!("All correct!");
+    }
+}
+
+impl Bar<<Foo as Fooifier>::Assoc> {
+    fn this_shouldnt_crash() {
+        <Self as Barifier<<Foo as Fooifier>::Assoc>>::barify();
+    }
+}
+
+fn main() {
+    Bar::<Foo>::this_shouldnt_crash();
+}
diff --git a/src/test/ui/issues/issue-1251.rs b/src/test/ui/issues/issue-1251.rs
index b42404c..125f6e1 100644
--- a/src/test/ui/issues/issue-1251.rs
+++ b/src/test/ui/issues/issue-1251.rs
@@ -14,7 +14,7 @@
 // pretty-expanded FIXME #23616
 // ignore-wasm32-bare no libc to test ffi with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 #![crate_id="rust_get_test_int"]
 
diff --git a/src/test/ui/issues/issue-20261.rs b/src/test/ui/issues/issue-20261.rs
index bb4dbdc..0330ac6 100644
--- a/src/test/ui/issues/issue-20261.rs
+++ b/src/test/ui/issues/issue-20261.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn main() {
-    // NB: this (almost) typechecks when default binding modes are enabled.
+    // N.B., this (almost) typechecks when default binding modes are enabled.
     for (ref i,) in [].iter() {
         i.clone();
         //~^ ERROR type annotations needed
diff --git a/src/test/ui/issues/issue-22034.rs b/src/test/ui/issues/issue-22034.rs
index 2708de2..bee324f 100644
--- a/src/test/ui/issues/issue-22034.rs
+++ b/src/test/ui/issues/issue-22034.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
diff --git a/src/test/ui/issues/issue-27842.stderr b/src/test/ui/issues/issue-27842.stderr
index 0265948..dea7acd 100644
--- a/src/test/ui/issues/issue-27842.stderr
+++ b/src/test/ui/issues/issue-27842.stderr
@@ -10,7 +10,7 @@
 LL |     let _ = tup[i];
    |             ^^^^^^
    |
-   = help: to access tuple elements, use tuple indexing syntax (e.g. `tuple.0`)
+   = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr
index e2630b5..ed6b325 100644
--- a/src/test/ui/issues/issue-31173.stderr
+++ b/src/test/ui/issues/issue-31173.stderr
@@ -14,8 +14,8 @@
    |          ^^^^^^^
    |
    = note: the method `collect` exists but the following trait bounds were not satisfied:
-           `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
            `&mut std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
+           `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-32655.rs b/src/test/ui/issues/issue-32655.rs
index 25ecd5d..bbe95a4 100644
--- a/src/test/ui/issues/issue-32655.rs
+++ b/src/test/ui/issues/issue-32655.rs
@@ -13,7 +13,7 @@
 
 macro_rules! foo (
     () => (
-        #[derive_Clone] //~ ERROR attributes of the form
+        #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown
         struct T;
     );
 );
@@ -25,7 +25,7 @@
 foo!();
 
 bar!(
-    #[derive_Clone] //~ ERROR attributes of the form
+    #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown
     struct S;
 );
 
diff --git a/src/test/ui/issues/issue-32655.stderr b/src/test/ui/issues/issue-32655.stderr
index f930217..88da51a 100644
--- a/src/test/ui/issues/issue-32655.stderr
+++ b/src/test/ui/issues/issue-32655.stderr
@@ -1,21 +1,21 @@
-error[E0658]: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644)
+error[E0658]: The attribute `derive_Clone` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
   --> $DIR/issue-32655.rs:16:11
    |
-LL |         #[derive_Clone] //~ ERROR attributes of the form
+LL |         #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown
    |           ^^^^^^^^^^^^
 ...
 LL | foo!();
    | ------- in this macro invocation
    |
-   = help: add #![feature(custom_derive)] to the crate attributes to enable
+   = help: add #![feature(custom_attribute)] to the crate attributes to enable
 
-error[E0658]: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644)
+error[E0658]: The attribute `derive_Clone` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
   --> $DIR/issue-32655.rs:28:7
    |
-LL |     #[derive_Clone] //~ ERROR attributes of the form
+LL |     #[derive_Clone] //~ ERROR attribute `derive_Clone` is currently unknown
    |       ^^^^^^^^^^^^
    |
-   = help: add #![feature(custom_derive)] to the crate attributes to enable
+   = help: add #![feature(custom_attribute)] to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-35677.rs b/src/test/ui/issues/issue-35677.rs
new file mode 100644
index 0000000..46d3f7e
--- /dev/null
+++ b/src/test/ui/issues/issue-35677.rs
@@ -0,0 +1,5 @@
+use std::collections::HashMap;
+fn intersect_map<K, V>(this: &mut HashMap<K, V>, other: HashMap<K, V>) -> bool {
+    this.drain()
+    //~^ ERROR no method named
+}
diff --git a/src/test/ui/issues/issue-35677.stderr b/src/test/ui/issues/issue-35677.stderr
new file mode 100644
index 0000000..dca096b
--- /dev/null
+++ b/src/test/ui/issues/issue-35677.stderr
@@ -0,0 +1,18 @@
+error[E0601]: `main` function not found in crate `issue_35677`
+   |
+   = note: consider adding a `main` function to `$DIR/issue-35677.rs`
+
+error[E0599]: no method named `drain` found for type `&mut std::collections::HashMap<K, V>` in the current scope
+  --> $DIR/issue-35677.rs:3:10
+   |
+LL |     this.drain()
+   |          ^^^^^
+   |
+   = note: the method `drain` exists but the following trait bounds were not satisfied:
+           `K : std::cmp::Eq`
+           `K : std::hash::Hash`
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0599, E0601.
+For more information about an error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-36744-without-calls.rs b/src/test/ui/issues/issue-36744-without-calls.rs
index 8a47ebb..c158400 100644
--- a/src/test/ui/issues/issue-36744-without-calls.rs
+++ b/src/test/ui/issues/issue-36744-without-calls.rs
@@ -11,7 +11,7 @@
 // compile-pass
 // Tests for an LLVM abort when storing a lifetime-parametric fn into
 // context that is expecting one that is not lifetime-parametric
-// (i.e. has no `for <'_>`).
+// (i.e., has no `for <'_>`).
 
 pub struct A<'a>(&'a ());
 pub struct S<T>(T);
diff --git a/src/test/ui/issues/issue-37887.stderr b/src/test/ui/issues/issue-37887.stderr
index 48fb6c2..7a5a5cd 100644
--- a/src/test/ui/issues/issue-37887.stderr
+++ b/src/test/ui/issues/issue-37887.stderr
@@ -4,13 +4,13 @@
 LL |     use libc::*; //~ ERROR unresolved import
    |         ^^^^ maybe a missing `extern crate libc;`?
 
-error[E0658]: use of unstable library feature 'libc': use `libc` from crates.io (see issue #27783)
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? (see issue #27812)
   --> $DIR/issue-37887.rs:12:5
    |
 LL |     extern crate libc; //~ ERROR use of unstable
    |     ^^^^^^^^^^^^^^^^^^
    |
-   = help: add #![feature(libc)] to the crate attributes to enable
+   = help: add #![feature(rustc_private)] to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-40861.stderr b/src/test/ui/issues/issue-40861.stderr
index dbde40f..660f0ff 100644
--- a/src/test/ui/issues/issue-40861.stderr
+++ b/src/test/ui/issues/issue-40861.stderr
@@ -4,7 +4,7 @@
 LL |     ()[f(&[1.0])];
    |     ^^^^^^^^^^^^^
    |
-   = help: to access tuple elements, use tuple indexing syntax (e.g. `tuple.0`)
+   = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-41974.stderr b/src/test/ui/issues/issue-41974.stderr
index eca40ed..d6d4f7b 100644
--- a/src/test/ui/issues/issue-41974.stderr
+++ b/src/test/ui/issues/issue-41974.stderr
@@ -15,7 +15,7 @@
 LL | impl<T> Drop for T where T: A { //~ ERROR E0119
    |                  ^ implementing Drop requires a struct
 
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/issue-41974.rs:17:1
    |
 LL | impl<T> Drop for T where T: A { //~ ERROR E0119
diff --git a/src/test/ui/issues/issue-52060.stderr b/src/test/ui/issues/issue-52060.stderr
index 988bfd4..7c3f769 100644
--- a/src/test/ui/issues/issue-52060.stderr
+++ b/src/test/ui/issues/issue-52060.stderr
@@ -10,7 +10,7 @@
 LL | static B: [u32; 1] = [0; A.len()];
    |                          ^^^^^^^
    |
-   = help: in Nightly builds, add `#![feature(const_slice_len)]` to the crate attributes to enable
+   = help: add `#![feature(const_slice_len)]` to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lint/lint-ctypes.rs b/src/test/ui/lint/lint-ctypes.rs
index e09aaba..4c9f1f9 100644
--- a/src/test/ui/lint/lint-ctypes.rs
+++ b/src/test/ui/lint/lint-ctypes.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![deny(improper_ctypes)]
-#![feature(libc)]
+#![feature(rustc_private)]
 
 #![allow(private_in_public)]
 
diff --git a/src/test/ui/lint/lint-unexported-no-mangle.stderr b/src/test/ui/lint/lint-unexported-no-mangle.stderr
index 063915d..1df2d7b 100644
--- a/src/test/ui/lint/lint-unexported-no-mangle.stderr
+++ b/src/test/ui/lint/lint-unexported-no-mangle.stderr
@@ -1,8 +1,8 @@
-warning: lint `private_no_mangle_fns` has been removed: `no longer an warning, #[no_mangle] functions always exported`
+warning: lint `private_no_mangle_fns` has been removed: `no longer a warning, #[no_mangle] functions always exported`
    |
    = note: requested on the command line with `-F private_no_mangle_fns`
 
-warning: lint `private_no_mangle_statics` has been removed: `no longer an warning, #[no_mangle] statics always exported`
+warning: lint `private_no_mangle_statics` has been removed: `no longer a warning, #[no_mangle] statics always exported`
    |
    = note: requested on the command line with `-F private_no_mangle_statics`
 
diff --git a/src/test/ui/lint/lint-unused-imports.rs b/src/test/ui/lint/lint-unused-imports.rs
index 5bb2ab7..64a4851 100644
--- a/src/test/ui/lint/lint-unused-imports.rs
+++ b/src/test/ui/lint/lint-unused-imports.rs
@@ -81,7 +81,7 @@
     }
 }
 
-// c.f. issue #35135
+// cf. issue #35135.
 #[allow(unused_variables)]
 fn h() {
     use test2::foo; //~ ERROR unused import: `test2::foo`
diff --git a/src/test/ui/macros/assert.rs b/src/test/ui/macros/assert.rs
new file mode 100644
index 0000000..8732cb5
--- /dev/null
+++ b/src/test/ui/macros/assert.rs
@@ -0,0 +1,4 @@
+fn main() {
+    assert!();  //~ ERROR requires a boolean expression
+    debug_assert!(); //~ ERROR requires a boolean expression
+}
diff --git a/src/test/ui/macros/assert.stderr b/src/test/ui/macros/assert.stderr
new file mode 100644
index 0000000..89faba0
--- /dev/null
+++ b/src/test/ui/macros/assert.stderr
@@ -0,0 +1,16 @@
+error: macro requires a boolean expression as an argument
+  --> $DIR/assert.rs:2:5
+   |
+LL |     assert!();  //~ ERROR requires a boolean expression
+   |     ^^^^^^^^^^ boolean expression required
+
+error: macro requires a boolean expression as an argument
+  --> $DIR/assert.rs:3:5
+   |
+LL |     debug_assert!(); //~ ERROR requires a boolean expression
+   |     ^^^^^^^^^^^^^^^^ boolean expression required
+   |
+   = 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: aborting due to 2 previous errors
+
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/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr
index 86a92a7..1fbac9d 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.stderr
+++ b/src/test/ui/mismatched_types/issue-36053-2.stderr
@@ -5,8 +5,8 @@
    |                                                       ^^^^^
    |
    = note: the method `count` exists but the following trait bounds were not satisfied:
-           `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
            `&mut std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
+           `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/issue-36053-2.rs:17:32
diff --git a/src/test/ui/namespace/namespace-mix.rs b/src/test/ui/namespace/namespace-mix.rs
index c1c724f..22a9da8 100644
--- a/src/test/ui/namespace/namespace-mix.rs
+++ b/src/test/ui/namespace/namespace-mix.rs
@@ -26,7 +26,7 @@
     pub struct Item;
 }
 
-// Use something emitting the type argument name, e.g. unsatisfied bound.
+// Use something emitting the type argument name, e.g., unsatisfied bound.
 trait Impossible {}
 fn check<T: Impossible>(_: T) {}
 
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-use.rs
index 186ecc5..633cbdb 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-use.rs
+++ b/src/test/ui/nll/issue-21232-partial-init-and-use.rs
@@ -61,7 +61,7 @@
 // As a shorthand for the cases above, adding a numeric summary to
 // each test's fn name to denote each point on each axis.
 //
-// E.g. 1000 = field fully init struct; 0211 = local void reinit tuple
+// e.g., 1000 = field fully init struct; 0211 = local void reinit tuple
 
 // It got pretty monotonous writing the same code over and over, and I
 // feared I would forget details. So I abstracted some desiderata into
diff --git a/src/test/ui/nll/issue-55850.nll.stderr b/src/test/ui/nll/issue-55850.nll.stderr
new file mode 100644
index 0000000..08e5217
--- /dev/null
+++ b/src/test/ui/nll/issue-55850.nll.stderr
@@ -0,0 +1,18 @@
+error[E0597]: `s` does not live long enough
+  --> $DIR/issue-55850.rs:38:16
+   |
+LL |         yield &s[..] //~ ERROR `s` does not live long enough [E0597]
+   |                ^ borrowed value does not live long enough
+LL |     })
+   |     - `s` dropped here while still borrowed
+
+error[E0626]: borrow may still be in use when generator yields
+  --> $DIR/issue-55850.rs:38:16
+   |
+LL |         yield &s[..] //~ ERROR `s` does not live long enough [E0597]
+   |         -------^---- possible yield occurs here
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0597, E0626.
+For more information about an error, try `rustc --explain E0597`.
diff --git a/src/test/ui/nll/issue-55850.rs b/src/test/ui/nll/issue-55850.rs
new file mode 100644
index 0000000..4140815
--- /dev/null
+++ b/src/test/ui/nll/issue-55850.rs
@@ -0,0 +1,44 @@
+// 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.
+
+#![allow(unused_mut)]
+#![feature(generators, generator_trait)]
+
+use std::ops::Generator;
+use std::ops::GeneratorState::Yielded;
+
+pub struct GenIter<G>(G);
+
+impl <G> Iterator for GenIter<G>
+where
+    G: Generator,
+{
+    type Item = G::Yield;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        unsafe {
+            match self.0.resume() {
+                Yielded(y) => Some(y),
+                _ => None
+            }
+        }
+    }
+}
+
+fn bug<'a>() -> impl Iterator<Item = &'a str> {
+    GenIter(move || {
+        let mut s = String::new();
+        yield &s[..] //~ ERROR `s` does not live long enough [E0597]
+    })
+}
+
+fn main() {
+    bug();
+}
diff --git a/src/test/ui/nll/issue-55850.stderr b/src/test/ui/nll/issue-55850.stderr
new file mode 100644
index 0000000..26b4c82
--- /dev/null
+++ b/src/test/ui/nll/issue-55850.stderr
@@ -0,0 +1,17 @@
+error[E0597]: `s` does not live long enough
+  --> $DIR/issue-55850.rs:38:16
+   |
+LL |         yield &s[..] //~ ERROR `s` does not live long enough [E0597]
+   |                ^ borrowed value does not live long enough
+LL |     })
+   |     - borrowed value only lives until here
+   |
+note: borrowed value must be valid for the lifetime 'a as defined on the function body at 35:8...
+  --> $DIR/issue-55850.rs:35:8
+   |
+LL | fn bug<'a>() -> impl Iterator<Item = &'a str> {
+   |        ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/no-implicit-prelude-nested.rs b/src/test/ui/no-implicit-prelude-nested.rs
index c64839a..0250cf5 100644
--- a/src/test/ui/no-implicit-prelude-nested.rs
+++ b/src/test/ui/no-implicit-prelude-nested.rs
@@ -10,7 +10,7 @@
 
 // Test that things from the prelude aren't in scope. Use many of them
 // so that renaming some things won't magically make this test fail
-// for the wrong reason (e.g. if `Add` changes to `Addition`, and
+// for the wrong reason (e.g., if `Add` changes to `Addition`, and
 // `no_implicit_prelude` stops working, then the `impl Add` will still
 // fail with the same error message).
 
diff --git a/src/test/ui/no-implicit-prelude.rs b/src/test/ui/no-implicit-prelude.rs
index 0e39d9e..8a4a0ae 100644
--- a/src/test/ui/no-implicit-prelude.rs
+++ b/src/test/ui/no-implicit-prelude.rs
@@ -12,7 +12,7 @@
 
 // Test that things from the prelude aren't in scope. Use many of them
 // so that renaming some things won't magically make this test fail
-// for the wrong reason (e.g. if `Add` changes to `Addition`, and
+// for the wrong reason (e.g., if `Add` changes to `Addition`, and
 // `no_implicit_prelude` stops working, then the `impl Add` will still
 // fail with the same error message).
 
diff --git a/src/test/compile-fail-fulldeps/no-link-unknown-crate.rs b/src/test/ui/no-link-unknown-crate.rs
similarity index 100%
rename from src/test/compile-fail-fulldeps/no-link-unknown-crate.rs
rename to src/test/ui/no-link-unknown-crate.rs
diff --git a/src/test/ui/no-link-unknown-crate.stderr b/src/test/ui/no-link-unknown-crate.stderr
new file mode 100644
index 0000000..182b484
--- /dev/null
+++ b/src/test/ui/no-link-unknown-crate.stderr
@@ -0,0 +1,9 @@
+error[E0463]: can't find crate for `doesnt_exist`
+  --> $DIR/no-link-unknown-crate.rs:12:1
+   |
+LL | extern crate doesnt_exist; //~ ERROR can't find crate
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0463`.
diff --git a/src/test/ui/non-copyable-void.rs b/src/test/ui/non-copyable-void.rs
index 63e5f96..3599190 100644
--- a/src/test/ui/non-copyable-void.rs
+++ b/src/test/ui/non-copyable-void.rs
@@ -10,7 +10,7 @@
 
 // ignore-wasm32-bare no libc to test ffi with
 
-#![feature(libc)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
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/orphan-check-diagnostics.stderr b/src/test/ui/orphan-check-diagnostics.stderr
index dc134dd..22422f1 100644
--- a/src/test/ui/orphan-check-diagnostics.stderr
+++ b/src/test/ui/orphan-check-diagnostics.stderr
@@ -1,4 +1,4 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/orphan-check-diagnostics.rs:20:1
    |
 LL | impl<T> RemoteTrait for T where T: LocalTrait {}
diff --git a/src/test/ui/parser/assoc-oddities-1.rs b/src/test/ui/parser/assoc-oddities-1.rs
index 63408b7..866d742 100644
--- a/src/test/ui/parser/assoc-oddities-1.rs
+++ b/src/test/ui/parser/assoc-oddities-1.rs
@@ -15,7 +15,7 @@
     x = if c { a } else { b }();
     x = if true { 1 } else { 0 } as *mut _;
     // however this does not parse and probably should fail to retain compat?
-    // NB: `..` here is arbitrary, failure happens/should happen ∀ops that aren’t `=`
+    // N.B., `..` here is arbitrary, failure happens/should happen ∀ops that aren’t `=`
     // see assoc-oddities-2 and assoc-oddities-3
     ..if c { a } else { b }[n]; //~ ERROR expected one of
 }
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/const-pat-ice.rs b/src/test/ui/pattern/const-pat-ice.rs
new file mode 100644
index 0000000..6496a2a
--- /dev/null
+++ b/src/test/ui/pattern/const-pat-ice.rs
@@ -0,0 +1,13 @@
+// failure-status: 101
+
+// This is a repro test for an ICE in our pattern handling of constants.
+
+const FOO: &&&u32 = &&&42;
+
+fn main() {
+    match unimplemented!() {
+        &&&42 => {},
+        FOO => {},
+        _ => {},
+    }
+}
diff --git a/src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs b/src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs
new file mode 100644
index 0000000..ff06588
--- /dev/null
+++ b/src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs
@@ -0,0 +1,8 @@
+// run-pass
+
+fn main() {
+    let -2147483648..=2147483647 = 1;
+    let 0..=255 = 0u8;
+    let -128..=127 = 0i8;
+    let '\u{0000}'..='\u{10FFFF}' = 'v';
+}
diff --git a/src/test/ui/pattern/slice-pattern-const-2.rs b/src/test/ui/pattern/slice-pattern-const-2.rs
index 6f9501d..6cfef11 100644
--- a/src/test/ui/pattern/slice-pattern-const-2.rs
+++ b/src/test/ui/pattern/slice-pattern-const-2.rs
@@ -1,4 +1,4 @@
-// compile-pass
+#![deny(unreachable_patterns)]
 
 fn main() {
     let s = &[0x00; 4][..]; //Slice of any value
@@ -6,19 +6,26 @@
     match s {
         MAGIC_TEST => (),
         [0x00, 0x00, 0x00, 0x00] => (),
-        [4, 5, 6, 7] => (), // this should warn
+        [4, 5, 6, 7] => (), //~ ERROR unreachable pattern
         _ => (),
     }
     match s {
         [0x00, 0x00, 0x00, 0x00] => (),
         MAGIC_TEST => (),
-        [4, 5, 6, 7] => (), // this should warn
+        [4, 5, 6, 7] => (), //~ ERROR unreachable pattern
         _ => (),
     }
     match s {
         [0x00, 0x00, 0x00, 0x00] => (),
         [4, 5, 6, 7] => (),
-        MAGIC_TEST => (), // this should warn
+        MAGIC_TEST => (), // FIXME(oli-obk): this should warn, but currently does not
+        _ => (),
+    }
+    const FOO: [u32; 1] = [4];
+    match [99] {
+        [0x00] => (),
+        [4] => (),
+        FOO => (), //~ ERROR unreachable pattern
         _ => (),
     }
 }
diff --git a/src/test/ui/pattern/slice-pattern-const-2.stderr b/src/test/ui/pattern/slice-pattern-const-2.stderr
new file mode 100644
index 0000000..95651cc
--- /dev/null
+++ b/src/test/ui/pattern/slice-pattern-const-2.stderr
@@ -0,0 +1,26 @@
+error: unreachable pattern
+  --> $DIR/slice-pattern-const-2.rs:9:9
+   |
+LL |         [4, 5, 6, 7] => (), //~ ERROR unreachable pattern
+   |         ^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/slice-pattern-const-2.rs:1:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/slice-pattern-const-2.rs:15:9
+   |
+LL |         [4, 5, 6, 7] => (), //~ ERROR unreachable pattern
+   |         ^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/slice-pattern-const-2.rs:28:9
+   |
+LL |         FOO => (), //~ ERROR unreachable pattern
+   |         ^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/pattern/slice-pattern-const-3.rs b/src/test/ui/pattern/slice-pattern-const-3.rs
index e7a30ce..8805c43 100644
--- a/src/test/ui/pattern/slice-pattern-const-3.rs
+++ b/src/test/ui/pattern/slice-pattern-const-3.rs
@@ -1,4 +1,4 @@
-// compile-pass
+#![deny(unreachable_patterns)]
 
 fn main() {
     let s = &["0x00"; 4][..]; //Slice of any value
@@ -6,19 +6,26 @@
     match s {
         MAGIC_TEST => (),
         ["0x00", "0x00", "0x00", "0x00"] => (),
-        ["4", "5", "6", "7"] => (), // this should warn
+        ["4", "5", "6", "7"] => (), // FIXME(oli-obk): this should warn, but currently does not
         _ => (),
     }
     match s {
         ["0x00", "0x00", "0x00", "0x00"] => (),
         MAGIC_TEST => (),
-        ["4", "5", "6", "7"] => (), // this should warn
+        ["4", "5", "6", "7"] => (), // FIXME(oli-obk): this should warn, but currently does not
         _ => (),
     }
     match s {
         ["0x00", "0x00", "0x00", "0x00"] => (),
         ["4", "5", "6", "7"] => (),
-        MAGIC_TEST => (), // this should warn
+        MAGIC_TEST => (), // FIXME(oli-obk): this should warn, but currently does not
+        _ => (),
+    }
+    const FOO: [&str; 1] = ["boo"];
+    match ["baa"] {
+        ["0x00"] => (),
+        ["boo"] => (),
+        FOO => (), //~ ERROR unreachable pattern
         _ => (),
     }
 }
diff --git a/src/test/ui/pattern/slice-pattern-const-3.stderr b/src/test/ui/pattern/slice-pattern-const-3.stderr
new file mode 100644
index 0000000..531bbbc
--- /dev/null
+++ b/src/test/ui/pattern/slice-pattern-const-3.stderr
@@ -0,0 +1,14 @@
+error: unreachable pattern
+  --> $DIR/slice-pattern-const-3.rs:28:9
+   |
+LL |         FOO => (), //~ ERROR unreachable pattern
+   |         ^^^
+   |
+note: lint level defined here
+  --> $DIR/slice-pattern-const-3.rs:1:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pattern/slice-pattern-const.rs b/src/test/ui/pattern/slice-pattern-const.rs
index d353f6c..f0a0451 100644
--- a/src/test/ui/pattern/slice-pattern-const.rs
+++ b/src/test/ui/pattern/slice-pattern-const.rs
@@ -1,4 +1,4 @@
-//compile-pass
+#![deny(unreachable_patterns)]
 
 fn main() {
     let s = &[0x00; 4][..]; //Slice of any value
@@ -6,19 +6,42 @@
     match s {
         MAGIC_TEST => (),
         [0x00, 0x00, 0x00, 0x00] => (),
-        [84, 69, 83, 84] => (), // this should warn
+        [84, 69, 83, 84] => (), //~ ERROR unreachable pattern
         _ => (),
     }
     match s {
         [0x00, 0x00, 0x00, 0x00] => (),
         MAGIC_TEST => (),
-        [84, 69, 83, 84] => (), // this should warn
+        [84, 69, 83, 84] => (), //~ ERROR unreachable pattern
         _ => (),
     }
     match s {
         [0x00, 0x00, 0x00, 0x00] => (),
         [84, 69, 83, 84] => (),
-        MAGIC_TEST => (), // this should warn
+        MAGIC_TEST => (), //~ ERROR unreachable pattern
         _ => (),
     }
+    const FOO: [u8; 1] = [4];
+    match [99] {
+        [0x00] => (),
+        [4] => (),
+        FOO => (), //~ ERROR unreachable pattern
+        _ => (),
+    }
+    const BAR: &[u8; 1] = &[4];
+    match &[99] {
+        [0x00] => (),
+        [4] => (),
+        BAR => (), //~ ERROR unreachable pattern
+        b"a" => (),
+        _ => (),
+    }
+
+    const BOO: &[u8; 0] = &[];
+    match &[] {
+        [] => (),
+        BOO => (), //~ ERROR unreachable pattern
+        b"" => (), //~ ERROR unreachable pattern
+        _ => (), //~ ERROR unreachable pattern
+    }
 }
diff --git a/src/test/ui/pattern/slice-pattern-const.stderr b/src/test/ui/pattern/slice-pattern-const.stderr
new file mode 100644
index 0000000..412e015
--- /dev/null
+++ b/src/test/ui/pattern/slice-pattern-const.stderr
@@ -0,0 +1,56 @@
+error: unreachable pattern
+  --> $DIR/slice-pattern-const.rs:9:9
+   |
+LL |         [84, 69, 83, 84] => (), //~ ERROR unreachable pattern
+   |         ^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/slice-pattern-const.rs:1:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/slice-pattern-const.rs:15:9
+   |
+LL |         [84, 69, 83, 84] => (), //~ ERROR unreachable pattern
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/slice-pattern-const.rs:21:9
+   |
+LL |         MAGIC_TEST => (), //~ ERROR unreachable pattern
+   |         ^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/slice-pattern-const.rs:28:9
+   |
+LL |         FOO => (), //~ ERROR unreachable pattern
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/slice-pattern-const.rs:35:9
+   |
+LL |         BAR => (), //~ ERROR unreachable pattern
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/slice-pattern-const.rs:43:9
+   |
+LL |         BOO => (), //~ ERROR unreachable pattern
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/slice-pattern-const.rs:44:9
+   |
+LL |         b"" => (), //~ ERROR unreachable pattern
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/slice-pattern-const.rs:45:9
+   |
+LL |         _ => (), //~ ERROR unreachable pattern
+   |         ^
+
+error: aborting due to 8 previous errors
+
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/print_type_sizes/generics.rs b/src/test/ui/print_type_sizes/generics.rs
index fa5921c..5b6918d 100644
--- a/src/test/ui/print_type_sizes/generics.rs
+++ b/src/test/ui/print_type_sizes/generics.rs
@@ -30,7 +30,7 @@
 //     Copy.
 //
 //     (I suspect this reflect some naivety within the rust compiler
-//      itself; it should be checking for drop glue, i.e. a destructor
+//      itself; it should be checking for drop glue, i.e., a destructor
 //      somewhere in the monomorphized types. It should not matter whether
 //      the type is Copy.)
 #[derive(Copy, Clone)]
diff --git a/src/test/compile-fail/proc-macro/attr-invalid-exprs.rs b/src/test/ui/proc-macro/attr-invalid-exprs.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/attr-invalid-exprs.rs
rename to src/test/ui/proc-macro/attr-invalid-exprs.rs
diff --git a/src/test/ui/proc-macro/attr-invalid-exprs.stderr b/src/test/ui/proc-macro/attr-invalid-exprs.stderr
new file mode 100644
index 0000000..c28def6
--- /dev/null
+++ b/src/test/ui/proc-macro/attr-invalid-exprs.stderr
@@ -0,0 +1,28 @@
+error: expected expression, found `<eof>`
+  --> $DIR/attr-invalid-exprs.rs:21:13
+   |
+LL |     let _ = #[no_output] "Hello, world!";
+   |             ^^^^^^^^^^^^
+
+error: macro expansion ignores token `,` and any following
+  --> $DIR/attr-invalid-exprs.rs:24:13
+   |
+LL |     let _ = #[duplicate] "Hello, world!";
+   |             ^^^^^^^^^^^^- help: you might be missing a semicolon here: `;`
+   |             |
+   |             caused by the macro expansion here
+   |
+   = note: the usage of `duplicate!` is likely invalid in expression context
+
+error: macro expansion ignores token `,` and any following
+  --> $DIR/attr-invalid-exprs.rs:33:9
+   |
+LL |         #[duplicate]
+   |         ^^^^^^^^^^^^- help: you might be missing a semicolon here: `;`
+   |         |
+   |         caused by the macro expansion here
+   |
+   = note: the usage of `duplicate!` is likely invalid in expression context
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/compile-fail/proc-macro/attr-stmt-expr.rs b/src/test/ui/proc-macro/attr-stmt-expr.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/attr-stmt-expr.rs
rename to src/test/ui/proc-macro/attr-stmt-expr.rs
diff --git a/src/test/ui/proc-macro/attr-stmt-expr.stderr b/src/test/ui/proc-macro/attr-stmt-expr.stderr
new file mode 100644
index 0000000..ee9bc77
--- /dev/null
+++ b/src/test/ui/proc-macro/attr-stmt-expr.stderr
@@ -0,0 +1,19 @@
+error[E0658]: attributes on expressions are experimental. (see issue #15701)
+  --> $DIR/attr-stmt-expr.rs:20:5
+   |
+LL |     #[expect_print_expr]
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(stmt_expr_attributes)] to the crate attributes to enable
+
+error[E0658]: attributes on expressions are experimental. (see issue #15701)
+  --> $DIR/attr-stmt-expr.rs:33:5
+   |
+LL |     #[expect_expr]
+   |     ^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(stmt_expr_attributes)] 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/compile-fail/proc-macro/attribute-with-error.rs b/src/test/ui/proc-macro/attribute-with-error.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/attribute-with-error.rs
rename to src/test/ui/proc-macro/attribute-with-error.rs
diff --git a/src/test/ui/proc-macro/attribute-with-error.stderr b/src/test/ui/proc-macro/attribute-with-error.stderr
new file mode 100644
index 0000000..d2b4ac6
--- /dev/null
+++ b/src/test/ui/proc-macro/attribute-with-error.stderr
@@ -0,0 +1,39 @@
+error[E0308]: mismatched types
+  --> $DIR/attribute-with-error.rs:21:18
+   |
+LL |     let a: i32 = "foo";
+   |                  ^^^^^ expected i32, found reference
+   |
+   = note: expected type `i32`
+              found type `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/attribute-with-error.rs:23:18
+   |
+LL |     let b: i32 = "f'oo";
+   |                  ^^^^^^ expected i32, found reference
+   |
+   = note: expected type `i32`
+              found type `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/attribute-with-error.rs:36:22
+   |
+LL |         let a: i32 = "foo";
+   |                      ^^^^^ expected i32, found reference
+   |
+   = note: expected type `i32`
+              found type `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/attribute-with-error.rs:46:22
+   |
+LL |         let a: i32 = "foo";
+   |                      ^^^^^ expected i32, found reference
+   |
+   = note: expected type `i32`
+              found type `&'static str`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/compile-fail/proc-macro/attribute.rs b/src/test/ui/proc-macro/attribute.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/attribute.rs
rename to src/test/ui/proc-macro/attribute.rs
diff --git a/src/test/ui/proc-macro/attribute.stderr b/src/test/ui/proc-macro/attribute.stderr
new file mode 100644
index 0000000..c752c53
--- /dev/null
+++ b/src/test/ui/proc-macro/attribute.stderr
@@ -0,0 +1,50 @@
+error: attribute must be of form: #[proc_macro_derive(TraitName)]
+  --> $DIR/attribute.rs:18:1
+   |
+LL | #[proc_macro_derive]
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: attribute must be of form: #[proc_macro_derive(TraitName)]
+  --> $DIR/attribute.rs:24:1
+   |
+LL | #[proc_macro_derive = "foo"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: must only be one word
+  --> $DIR/attribute.rs:31:5
+   |
+LL |     a = "b"
+   |     ^^^^^^^
+
+error: attribute must have either one or two arguments
+  --> $DIR/attribute.rs:38:1
+   |
+LL | #[proc_macro_derive(b, c, d)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: must only be one word
+  --> $DIR/attribute.rs:44:21
+   |
+LL | #[proc_macro_derive(d(e))]
+   |                     ^^^^
+
+error: must only be one word
+  --> $DIR/attribute.rs:50:35
+   |
+LL | #[proc_macro_derive(f, attributes(g = "h"))]
+   |                                   ^^^^^^^
+
+error: must only be one word
+  --> $DIR/attribute.rs:56:35
+   |
+LL | #[proc_macro_derive(i, attributes(j(k)))]
+   |                                   ^^^^
+
+error: attribute must have either one or two arguments
+  --> $DIR/attribute.rs:62:1
+   |
+LL | #[proc_macro_derive(l, attributes(m), n)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/compile-fail/proc-macro/attributes-included.rs b/src/test/ui/proc-macro/attributes-included.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/attributes-included.rs
rename to src/test/ui/proc-macro/attributes-included.rs
diff --git a/src/test/ui/proc-macro/attributes-included.stderr b/src/test/ui/proc-macro/attributes-included.stderr
new file mode 100644
index 0000000..e7eeccc
--- /dev/null
+++ b/src/test/ui/proc-macro/attributes-included.stderr
@@ -0,0 +1,13 @@
+warning: unused variable: `a`
+  --> $DIR/attributes-included.rs:27:9
+   |
+LL |     let a: i32 = "foo"; //~ WARN: unused variable
+   |         ^ help: consider using `_a` instead
+   |
+note: lint level defined here
+  --> $DIR/attributes-included.rs:14:9
+   |
+LL | #![warn(unused)]
+   |         ^^^^^^
+   = note: #[warn(unused_variables)] implied by #[warn(unused)]
+
diff --git a/src/test/compile-fail/proc-macro/auxiliary/attr-stmt-expr.rs b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/attr-stmt-expr.rs
rename to src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/attribute-with-error.rs b/src/test/ui/proc-macro/auxiliary/attribute-with-error.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/attribute-with-error.rs
rename to src/test/ui/proc-macro/auxiliary/attribute-with-error.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/attributes-included.rs b/src/test/ui/proc-macro/auxiliary/attributes-included.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/attributes-included.rs
rename to src/test/ui/proc-macro/auxiliary/attributes-included.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/bang_proc_macro2.rs b/src/test/ui/proc-macro/auxiliary/bang_proc_macro2.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/bang_proc_macro2.rs
rename to src/test/ui/proc-macro/auxiliary/bang_proc_macro2.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/derive-a-b.rs b/src/test/ui/proc-macro/auxiliary/derive-a-b.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/derive-a-b.rs
rename to src/test/ui/proc-macro/auxiliary/derive-a-b.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/derive-a.rs b/src/test/ui/proc-macro/auxiliary/derive-a.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/derive-a.rs
rename to src/test/ui/proc-macro/auxiliary/derive-a.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/derive-b.rs b/src/test/ui/proc-macro/auxiliary/derive-b.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/derive-b.rs
rename to src/test/ui/proc-macro/auxiliary/derive-b.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/derive-bad.rs b/src/test/ui/proc-macro/auxiliary/derive-bad.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/derive-bad.rs
rename to src/test/ui/proc-macro/auxiliary/derive-bad.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/derive-unstable-2.rs b/src/test/ui/proc-macro/auxiliary/derive-unstable-2.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/derive-unstable-2.rs
rename to src/test/ui/proc-macro/auxiliary/derive-unstable-2.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/derive-unstable.rs b/src/test/ui/proc-macro/auxiliary/derive-unstable.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/derive-unstable.rs
rename to src/test/ui/proc-macro/auxiliary/derive-unstable.rs
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/edition-imports-2015.rs b/src/test/ui/proc-macro/auxiliary/edition-imports-2015.rs
similarity index 95%
rename from src/test/ui-fulldeps/proc-macro/auxiliary/edition-imports-2015.rs
rename to src/test/ui/proc-macro/auxiliary/edition-imports-2015.rs
index 5bb818f..27c59b8 100644
--- a/src/test/ui-fulldeps/proc-macro/auxiliary/edition-imports-2015.rs
+++ b/src/test/ui/proc-macro/auxiliary/edition-imports-2015.rs
@@ -1,4 +1,5 @@
 // edition:2015
+// force-host
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/src/test/compile-fail/proc-macro/auxiliary/issue-41211.rs b/src/test/ui/proc-macro/auxiliary/issue-41211.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/issue-41211.rs
rename to src/test/ui/proc-macro/auxiliary/issue-41211.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/issue_38586.rs b/src/test/ui/proc-macro/auxiliary/issue_38586.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/issue_38586.rs
rename to src/test/ui/proc-macro/auxiliary/issue_38586.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/issue_50493.rs b/src/test/ui/proc-macro/auxiliary/issue_50493.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/issue_50493.rs
rename to src/test/ui/proc-macro/auxiliary/issue_50493.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/more-gates.rs b/src/test/ui/proc-macro/auxiliary/more-gates.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/more-gates.rs
rename to src/test/ui/proc-macro/auxiliary/more-gates.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/proc-macro-gates.rs b/src/test/ui/proc-macro/auxiliary/proc-macro-gates.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/proc-macro-gates.rs
rename to src/test/ui/proc-macro/auxiliary/proc-macro-gates.rs
diff --git a/src/test/compile-fail/proc-macro/auxiliary/test-macros.rs b/src/test/ui/proc-macro/auxiliary/test-macros.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/auxiliary/test-macros.rs
rename to src/test/ui/proc-macro/auxiliary/test-macros.rs
diff --git a/src/test/compile-fail/proc-macro/define-two.rs b/src/test/ui/proc-macro/define-two.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/define-two.rs
rename to src/test/ui/proc-macro/define-two.rs
diff --git a/src/test/ui/proc-macro/define-two.stderr b/src/test/ui/proc-macro/define-two.stderr
new file mode 100644
index 0000000..1ca2e0a
--- /dev/null
+++ b/src/test/ui/proc-macro/define-two.stderr
@@ -0,0 +1,14 @@
+error[E0428]: the name `A` is defined multiple times
+  --> $DIR/define-two.rs:25:21
+   |
+LL | #[proc_macro_derive(A)]
+   |                     - previous definition of the macro `A` here
+...
+LL | #[proc_macro_derive(A)] //~ ERROR the name `A` is defined multiple times
+   |                     ^ `A` redefined here
+   |
+   = note: `A` must be defined only once in the macro namespace of this module
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0428`.
diff --git a/src/test/compile-fail/proc-macro/derive-bad.rs b/src/test/ui/proc-macro/derive-bad.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/derive-bad.rs
rename to src/test/ui/proc-macro/derive-bad.rs
diff --git a/src/test/ui/proc-macro/derive-bad.stderr b/src/test/ui/proc-macro/derive-bad.stderr
new file mode 100644
index 0000000..57e72a0
--- /dev/null
+++ b/src/test/ui/proc-macro/derive-bad.stderr
@@ -0,0 +1,14 @@
+error: expected `:`, found `}`
+  --> $DIR/derive-bad.rs:17:5
+   |
+LL |     A
+   |     ^ expected `:`
+
+error: proc-macro derive produced unparseable tokens
+  --> $DIR/derive-bad.rs:17:5
+   |
+LL |     A
+   |     ^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/compile-fail/proc-macro/derive-still-gated.rs b/src/test/ui/proc-macro/derive-still-gated.rs
similarity index 86%
rename from src/test/compile-fail/proc-macro/derive-still-gated.rs
rename to src/test/ui/proc-macro/derive-still-gated.rs
index f36236c..edf5cc7 100644
--- a/src/test/compile-fail/proc-macro/derive-still-gated.rs
+++ b/src/test/ui/proc-macro/derive-still-gated.rs
@@ -15,7 +15,7 @@
 #[macro_use]
 extern crate derive_a;
 
-#[derive_A] //~ ERROR: attributes of the form `#[derive_*]` are reserved for the compiler
+#[derive_A] //~ ERROR attribute `derive_A` is currently unknown
 struct A;
 
 fn main() {}
diff --git a/src/test/ui/proc-macro/derive-still-gated.stderr b/src/test/ui/proc-macro/derive-still-gated.stderr
new file mode 100644
index 0000000..4e5dd34
--- /dev/null
+++ b/src/test/ui/proc-macro/derive-still-gated.stderr
@@ -0,0 +1,11 @@
+error[E0658]: The attribute `derive_A` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
+  --> $DIR/derive-still-gated.rs:18:3
+   |
+LL | #[derive_A] //~ ERROR attribute `derive_A` is currently unknown
+   |   ^^^^^^^^
+   |
+   = help: add #![feature(custom_attribute)] 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-fulldeps/proc-macro/edition-imports-2018.rs b/src/test/ui/proc-macro/edition-imports-2018.rs
similarity index 100%
rename from src/test/ui-fulldeps/proc-macro/edition-imports-2018.rs
rename to src/test/ui/proc-macro/edition-imports-2018.rs
diff --git a/src/test/compile-fail/proc-macro/expand-to-unstable-2.rs b/src/test/ui/proc-macro/expand-to-unstable-2.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/expand-to-unstable-2.rs
rename to src/test/ui/proc-macro/expand-to-unstable-2.rs
diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.stderr b/src/test/ui/proc-macro/expand-to-unstable-2.stderr
new file mode 100644
index 0000000..855e905
--- /dev/null
+++ b/src/test/ui/proc-macro/expand-to-unstable-2.stderr
@@ -0,0 +1,11 @@
+error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642)
+  --> $DIR/expand-to-unstable-2.rs:18:10
+   |
+LL | #[derive(Unstable)]
+   |          ^^^^^^^^
+   |
+   = help: add #![feature(rustc_attrs)] 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/compile-fail/proc-macro/expand-to-unstable.rs b/src/test/ui/proc-macro/expand-to-unstable.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/expand-to-unstable.rs
rename to src/test/ui/proc-macro/expand-to-unstable.rs
diff --git a/src/test/ui/proc-macro/expand-to-unstable.stderr b/src/test/ui/proc-macro/expand-to-unstable.stderr
new file mode 100644
index 0000000..e851b0e
--- /dev/null
+++ b/src/test/ui/proc-macro/expand-to-unstable.stderr
@@ -0,0 +1,11 @@
+error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library
+  --> $DIR/expand-to-unstable.rs:18:10
+   |
+LL | #[derive(Unstable)]
+   |          ^^^^^^^^
+   |
+   = help: add #![feature(core_intrinsics)] 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/compile-fail/proc-macro/export-macro.rs b/src/test/ui/proc-macro/export-macro.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/export-macro.rs
rename to src/test/ui/proc-macro/export-macro.rs
diff --git a/src/test/ui/proc-macro/export-macro.stderr b/src/test/ui/proc-macro/export-macro.stderr
new file mode 100644
index 0000000..f82d5ab
--- /dev/null
+++ b/src/test/ui/proc-macro/export-macro.stderr
@@ -0,0 +1,10 @@
+error: cannot export macro_rules! macros from a `proc-macro` crate type currently
+  --> $DIR/export-macro.rs:19:1
+   |
+LL | / macro_rules! foo {
+LL | |     ($e:expr) => ($e)
+LL | | }
+   | |_^
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/proc-macro/exports.rs b/src/test/ui/proc-macro/exports.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/exports.rs
rename to src/test/ui/proc-macro/exports.rs
diff --git a/src/test/ui/proc-macro/exports.stderr b/src/test/ui/proc-macro/exports.stderr
new file mode 100644
index 0000000..3637d0f
--- /dev/null
+++ b/src/test/ui/proc-macro/exports.stderr
@@ -0,0 +1,26 @@
+error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
+  --> $DIR/exports.rs:17:1
+   |
+LL | pub fn a() {} //~ ERROR: cannot export any items
+   | ^^^^^^^^^^^^^
+
+error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
+  --> $DIR/exports.rs:18:1
+   |
+LL | pub struct B; //~ ERROR: cannot export any items
+   | ^^^^^^^^^^^^^
+
+error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
+  --> $DIR/exports.rs:19:1
+   |
+LL | pub enum C {} //~ ERROR: cannot export any items
+   | ^^^^^^^^^^^^^
+
+error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
+  --> $DIR/exports.rs:20:1
+   |
+LL | pub mod d {} //~ ERROR: cannot export any items
+   | ^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/compile-fail/proc-macro/illegal-proc-macro-derive-use.rs b/src/test/ui/proc-macro/illegal-proc-macro-derive-use.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/illegal-proc-macro-derive-use.rs
rename to src/test/ui/proc-macro/illegal-proc-macro-derive-use.rs
diff --git a/src/test/ui/proc-macro/illegal-proc-macro-derive-use.stderr b/src/test/ui/proc-macro/illegal-proc-macro-derive-use.stderr
new file mode 100644
index 0000000..715ff0e
--- /dev/null
+++ b/src/test/ui/proc-macro/illegal-proc-macro-derive-use.stderr
@@ -0,0 +1,14 @@
+error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type
+  --> $DIR/illegal-proc-macro-derive-use.rs:13:1
+   |
+LL | #[proc_macro_derive(Foo)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the `#[proc_macro_derive]` attribute may only be used on bare functions
+  --> $DIR/illegal-proc-macro-derive-use.rs:20:1
+   |
+LL | #[proc_macro_derive(Foo)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/compile-fail/proc-macro/import.rs b/src/test/ui/proc-macro/import.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/import.rs
rename to src/test/ui/proc-macro/import.rs
diff --git a/src/test/ui/proc-macro/import.stderr b/src/test/ui/proc-macro/import.stderr
new file mode 100644
index 0000000..f3633b2
--- /dev/null
+++ b/src/test/ui/proc-macro/import.stderr
@@ -0,0 +1,9 @@
+error[E0432]: unresolved import `derive_a::derive_a`
+  --> $DIR/import.rs:18:5
+   |
+LL | use derive_a::derive_a;
+   |     ^^^^^^^^^^^^^^^^^^ no `derive_a` in the root
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/src/test/compile-fail/proc-macro/issue-37788.rs b/src/test/ui/proc-macro/issue-37788.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/issue-37788.rs
rename to src/test/ui/proc-macro/issue-37788.rs
diff --git a/src/test/ui/proc-macro/issue-37788.stderr b/src/test/ui/proc-macro/issue-37788.stderr
new file mode 100644
index 0000000..f5ddf9b
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-37788.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-37788.rs:18:5
+   |
+LL | fn main() {
+   |           - expected `()` because of default return type
+LL |     // Test that constructing the `visible_parent_map` (in `cstore_impl.rs`) does not ICE.
+LL |     std::cell::Cell::new(0) //~ ERROR mismatched types
+   |     ^^^^^^^^^^^^^^^^^^^^^^^- help: try adding a semicolon: `;`
+   |     |
+   |     expected (), found struct `std::cell::Cell`
+   |
+   = note: expected type `()`
+              found type `std::cell::Cell<{integer}>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/compile-fail/proc-macro/issue-38586.rs b/src/test/ui/proc-macro/issue-38586.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/issue-38586.rs
rename to src/test/ui/proc-macro/issue-38586.rs
diff --git a/src/test/ui/proc-macro/issue-38586.stderr b/src/test/ui/proc-macro/issue-38586.stderr
new file mode 100644
index 0000000..6ba2c0b
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-38586.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `foo` in this scope
+  --> $DIR/issue-38586.rs:16:10
+   |
+LL | #[derive(A)] //~ ERROR `foo`
+   |          ^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/compile-fail/proc-macro/issue-41211.rs b/src/test/ui/proc-macro/issue-41211.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/issue-41211.rs
rename to src/test/ui/proc-macro/issue-41211.rs
diff --git a/src/test/ui/proc-macro/issue-41211.stderr b/src/test/ui/proc-macro/issue-41211.stderr
new file mode 100644
index 0000000..ba5fad4
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-41211.stderr
@@ -0,0 +1,11 @@
+error[E0658]: The attribute `emit_unchanged` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
+  --> $DIR/issue-41211.rs:18:4
+   |
+LL | #![emit_unchanged]
+   |    ^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(custom_attribute)] 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/compile-fail/proc-macro/issue-50493.rs b/src/test/ui/proc-macro/issue-50493.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/issue-50493.rs
rename to src/test/ui/proc-macro/issue-50493.rs
diff --git a/src/test/ui/proc-macro/issue-50493.stderr b/src/test/ui/proc-macro/issue-50493.stderr
new file mode 100644
index 0000000..3dcb526
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-50493.stderr
@@ -0,0 +1,15 @@
+error: visibilities can only be restricted to ancestor modules
+  --> $DIR/issue-50493.rs:18:12
+   |
+LL |     pub(in restricted) field: usize, //~ visibilities can only be restricted to ancestor modules
+   |            ^^^^^^^^^^
+
+error[E0616]: field `field` of struct `Restricted` is private
+  --> $DIR/issue-50493.rs:16:10
+   |
+LL | #[derive(Derive)] //~ ERROR field `field` of struct `Restricted` is private
+   |          ^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0616`.
diff --git a/src/test/compile-fail/proc-macro/item-error.rs b/src/test/ui/proc-macro/item-error.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/item-error.rs
rename to src/test/ui/proc-macro/item-error.rs
diff --git a/src/test/ui/proc-macro/item-error.stderr b/src/test/ui/proc-macro/item-error.stderr
new file mode 100644
index 0000000..d193286
--- /dev/null
+++ b/src/test/ui/proc-macro/item-error.stderr
@@ -0,0 +1,9 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/item-error.rs:20:8
+   |
+LL |     a: &u64
+   |        ^ expected lifetime parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/compile-fail/proc-macro/lints_in_proc_macros.rs b/src/test/ui/proc-macro/lints_in_proc_macros.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/lints_in_proc_macros.rs
rename to src/test/ui/proc-macro/lints_in_proc_macros.rs
diff --git a/src/test/ui/proc-macro/lints_in_proc_macros.stderr b/src/test/ui/proc-macro/lints_in_proc_macros.stderr
new file mode 100644
index 0000000..42d9a30
--- /dev/null
+++ b/src/test/ui/proc-macro/lints_in_proc_macros.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `foobar2` in this scope
+  --> $DIR/lints_in_proc_macros.rs:22:5
+   |
+LL |     bang_proc_macro2!();
+   |     ^^^^^^^^^^^^^^^^^^^^ did you mean `foobar`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/compile-fail/proc-macro/macros-in-extern.rs b/src/test/ui/proc-macro/macros-in-extern.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/macros-in-extern.rs
rename to src/test/ui/proc-macro/macros-in-extern.rs
diff --git a/src/test/ui/proc-macro/macros-in-extern.stderr b/src/test/ui/proc-macro/macros-in-extern.stderr
new file mode 100644
index 0000000..5c51de4
--- /dev/null
+++ b/src/test/ui/proc-macro/macros-in-extern.stderr
@@ -0,0 +1,27 @@
+error[E0658]: macro invocations in `extern {}` blocks are experimental (see issue #49476)
+  --> $DIR/macros-in-extern.rs:25:5
+   |
+LL |     #[no_output]
+   |     ^^^^^^^^^^^^
+   |
+   = help: add #![feature(macros_in_extern)] to the crate attributes to enable
+
+error[E0658]: macro invocations in `extern {}` blocks are experimental (see issue #49476)
+  --> $DIR/macros-in-extern.rs:29:5
+   |
+LL |     #[nop_attr]
+   |     ^^^^^^^^^^^
+   |
+   = help: add #![feature(macros_in_extern)] to the crate attributes to enable
+
+error[E0658]: macro invocations in `extern {}` blocks are experimental (see issue #49476)
+  --> $DIR/macros-in-extern.rs:33:5
+   |
+LL |     emit_input!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(macros_in_extern)] to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/compile-fail/proc-macro/more-gates.rs b/src/test/ui/proc-macro/more-gates.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/more-gates.rs
rename to src/test/ui/proc-macro/more-gates.rs
diff --git a/src/test/ui/proc-macro/more-gates.stderr b/src/test/ui/proc-macro/more-gates.stderr
new file mode 100644
index 0000000..d5f30d5
--- /dev/null
+++ b/src/test/ui/proc-macro/more-gates.stderr
@@ -0,0 +1,43 @@
+error[E0658]: procedural macros cannot expand to macro definitions (see issue #54727)
+  --> $DIR/more-gates.rs:17:1
+   |
+LL | #[attr2mac1]
+   | ^^^^^^^^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: procedural macros cannot expand to macro definitions (see issue #54727)
+  --> $DIR/more-gates.rs:20:1
+   |
+LL | #[attr2mac2]
+   | ^^^^^^^^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: procedural macros cannot expand to macro definitions (see issue #54727)
+  --> $DIR/more-gates.rs:24:1
+   |
+LL | mac2mac1!(); //~ ERROR: cannot expand to macro definitions
+   | ^^^^^^^^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: procedural macros cannot expand to macro definitions (see issue #54727)
+  --> $DIR/more-gates.rs:25:1
+   |
+LL | mac2mac2!(); //~ ERROR: cannot expand to macro definitions
+   | ^^^^^^^^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: procedural macros cannot expand to macro definitions (see issue #54727)
+  --> $DIR/more-gates.rs:27:1
+   |
+LL | tricky!();
+   | ^^^^^^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/compile-fail/proc-macro/no-macro-use-attr.rs b/src/test/ui/proc-macro/no-macro-use-attr.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/no-macro-use-attr.rs
rename to src/test/ui/proc-macro/no-macro-use-attr.rs
diff --git a/src/test/ui/proc-macro/no-macro-use-attr.stderr b/src/test/ui/proc-macro/no-macro-use-attr.stderr
new file mode 100644
index 0000000..447cb26
--- /dev/null
+++ b/src/test/ui/proc-macro/no-macro-use-attr.stderr
@@ -0,0 +1,20 @@
+warning: unused extern crate
+  --> $DIR/no-macro-use-attr.rs:16:1
+   |
+LL | extern crate derive_a;
+   | ^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+   |
+note: lint level defined here
+  --> $DIR/no-macro-use-attr.rs:14:9
+   |
+LL | #![warn(unused_extern_crates)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: compilation successful
+  --> $DIR/no-macro-use-attr.rs:20:1
+   |
+LL | fn main() {} //~ ERROR compilation successful
+   | ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/proc-macro/proc-macro-attributes.rs b/src/test/ui/proc-macro/proc-macro-attributes.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/proc-macro-attributes.rs
rename to src/test/ui/proc-macro/proc-macro-attributes.rs
diff --git a/src/test/ui/proc-macro/proc-macro-attributes.stderr b/src/test/ui/proc-macro/proc-macro-attributes.stderr
new file mode 100644
index 0000000..a1289c6
--- /dev/null
+++ b/src/test/ui/proc-macro/proc-macro-attributes.stderr
@@ -0,0 +1,11 @@
+error[E0658]: The attribute `C` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
+  --> $DIR/proc-macro-attributes.rs:17:3
+   |
+LL | #[C] //~ ERROR attribute `C` is currently unknown to the compiler
+   |   ^
+   |
+   = help: add #![feature(custom_attribute)] 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/compile-fail/proc-macro/proc-macro-gates.rs b/src/test/ui/proc-macro/proc-macro-gates.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/proc-macro-gates.rs
rename to src/test/ui/proc-macro/proc-macro-gates.rs
diff --git a/src/test/ui/proc-macro/proc-macro-gates.stderr b/src/test/ui/proc-macro/proc-macro-gates.stderr
new file mode 100644
index 0000000..d5c85d9
--- /dev/null
+++ b/src/test/ui/proc-macro/proc-macro-gates.stderr
@@ -0,0 +1,137 @@
+error[E0658]: non-builtin inner attributes are unstable (see issue #54726)
+  --> $DIR/proc-macro-gates.rs:21:5
+   |
+LL |     #![a] //~ ERROR: non-builtin inner attributes are unstable
+   |     ^^^^^
+   |
+   = help: add #![feature(custom_inner_attributes)] to the crate attributes to enable
+
+error[E0658]: non-builtin inner attributes are unstable (see issue #54726)
+  --> $DIR/proc-macro-gates.rs:28:5
+   |
+LL |     #![a] //~ ERROR: custom attributes cannot be applied to modules
+   |     ^^^^^
+   |
+   = help: add #![feature(custom_inner_attributes)] to the crate attributes to enable
+
+error[E0658]: custom attributes cannot be applied to modules (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:24:1
+   |
+LL | #[a] //~ ERROR: custom attributes cannot be applied to modules
+   | ^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: custom attributes cannot be applied to modules (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:28:5
+   |
+LL |     #![a] //~ ERROR: custom attributes cannot be applied to modules
+   |     ^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error: custom attribute invocations must be of the form #[foo] or #[foo(..)], the macro name must only be followed by a delimiter token
+  --> $DIR/proc-macro-gates.rs:32:1
+   |
+LL | #[a = y] //~ ERROR: must only be followed by a delimiter token
+   | ^^^^^^^^
+
+error[E0658]: custom attributes cannot be applied to statements (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:41:5
+   |
+LL |     #[a] //~ ERROR: custom attributes cannot be applied to statements
+   |     ^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: custom attributes cannot be applied to statements (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:45:5
+   |
+LL |     #[a] //~ ERROR: custom attributes cannot be applied to statements
+   |     ^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: custom attributes cannot be applied to statements (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:49:5
+   |
+LL |     #[a] //~ ERROR: custom attributes cannot be applied to statements
+   |     ^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: custom attributes cannot be applied to expressions (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:53:14
+   |
+LL |     let _x = #[a] 2; //~ ERROR: custom attributes cannot be applied to expressions
+   |              ^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: custom attributes cannot be applied to expressions (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:56:15
+   |
+LL |     let _x = [#[a] 2]; //~ ERROR: custom attributes cannot be applied to expressions
+   |               ^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: custom attributes cannot be applied to expressions (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:59:14
+   |
+LL |     let _x = #[a] println!(); //~ ERROR: custom attributes cannot be applied to expressions
+   |              ^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: procedural macros cannot be expanded to types (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:63:13
+   |
+LL |     let _x: m!(u32) = 3; //~ ERROR: procedural macros cannot be expanded to types
+   |             ^^^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: procedural macros cannot be expanded to patterns (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:64:12
+   |
+LL |     if let m!(Some(_x)) = Some(3) {} //~ ERROR: procedural macros cannot be expanded to patterns
+   |            ^^^^^^^^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: procedural macros cannot be expanded to statements (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:66:5
+   |
+LL |     m!(struct S;); //~ ERROR: procedural macros cannot be expanded to statements
+   |     ^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: procedural macros cannot be expanded to statements (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:67:5
+   |
+LL |     m!(let _x = 3;); //~ ERROR: procedural macros cannot be expanded to statements
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: procedural macros cannot be expanded to expressions (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:69:14
+   |
+LL |     let _x = m!(3); //~ ERROR: procedural macros cannot be expanded to expressions
+   |              ^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error[E0658]: procedural macros cannot be expanded to expressions (see issue #54727)
+  --> $DIR/proc-macro-gates.rs:70:15
+   |
+LL |     let _x = [m!(3)]; //~ ERROR: procedural macros cannot be expanded to expressions
+   |               ^^^^^
+   |
+   = help: add #![feature(proc_macro_hygiene)] to the crate attributes to enable
+
+error: aborting due to 17 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/compile-fail/proc-macro/proc-macro-gates2.rs b/src/test/ui/proc-macro/proc-macro-gates2.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/proc-macro-gates2.rs
rename to src/test/ui/proc-macro/proc-macro-gates2.rs
diff --git a/src/test/ui/proc-macro/proc-macro-gates2.stderr b/src/test/ui/proc-macro/proc-macro-gates2.stderr
new file mode 100644
index 0000000..2c0f2b0
--- /dev/null
+++ b/src/test/ui/proc-macro/proc-macro-gates2.stderr
@@ -0,0 +1,19 @@
+error[E0658]: The attribute `a` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
+  --> $DIR/proc-macro-gates2.rs:23:11
+   |
+LL | fn _test6<#[a] T>() {}
+   |           ^^^^
+   |
+   = help: add #![feature(custom_attribute)] to the crate attributes to enable
+
+error[E0658]: The attribute `a` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
+  --> $DIR/proc-macro-gates2.rs:28:9
+   |
+LL |         #[a] //~ ERROR: unknown to the compiler
+   |         ^^^^
+   |
+   = help: add #![feature(custom_attribute)] 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/compile-fail/proc-macro/pub-at-crate-root.rs b/src/test/ui/proc-macro/pub-at-crate-root.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/pub-at-crate-root.rs
rename to src/test/ui/proc-macro/pub-at-crate-root.rs
diff --git a/src/test/ui/proc-macro/pub-at-crate-root.stderr b/src/test/ui/proc-macro/pub-at-crate-root.stderr
new file mode 100644
index 0000000..ba9a860
--- /dev/null
+++ b/src/test/ui/proc-macro/pub-at-crate-root.stderr
@@ -0,0 +1,32 @@
+error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
+  --> $DIR/pub-at-crate-root.rs:18:1
+   |
+LL | / pub mod a { //~ `proc-macro` crate types cannot export any items
+LL | |     use proc_macro::TokenStream;
+LL | |
+LL | |     #[proc_macro_derive(B)]
+...  |
+LL | |     }
+LL | | }
+   | |_^
+
+error: functions tagged with `#[proc_macro_derive]` must currently reside in the root of the crate
+  --> $DIR/pub-at-crate-root.rs:22:5
+   |
+LL | /     pub fn bar(a: TokenStream) -> TokenStream {
+LL | |     //~^ ERROR: must currently reside in the root of the crate
+LL | |         a
+LL | |     }
+   | |_____^
+
+error: functions tagged with `#[proc_macro_derive]` must be `pub`
+  --> $DIR/pub-at-crate-root.rs:29:1
+   |
+LL | / fn bar(a: proc_macro::TokenStream) -> proc_macro::TokenStream {
+LL | | //~^ ERROR: functions tagged with `#[proc_macro_derive]` must be `pub`
+LL | |     a
+LL | | }
+   | |_^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/compile-fail/proc-macro/shadow-builtin.rs b/src/test/ui/proc-macro/shadow-builtin.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/shadow-builtin.rs
rename to src/test/ui/proc-macro/shadow-builtin.rs
diff --git a/src/test/ui/proc-macro/shadow-builtin.stderr b/src/test/ui/proc-macro/shadow-builtin.stderr
new file mode 100644
index 0000000..6d04c90
--- /dev/null
+++ b/src/test/ui/proc-macro/shadow-builtin.stderr
@@ -0,0 +1,8 @@
+error: cannot override a built-in #[derive] mode
+  --> $DIR/shadow-builtin.rs:20:21
+   |
+LL | #[proc_macro_derive(PartialEq)]
+   |                     ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/proc-macro/shadow.rs b/src/test/ui/proc-macro/shadow.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/shadow.rs
rename to src/test/ui/proc-macro/shadow.rs
diff --git a/src/test/ui/proc-macro/shadow.stderr b/src/test/ui/proc-macro/shadow.stderr
new file mode 100644
index 0000000..847fc73
--- /dev/null
+++ b/src/test/ui/proc-macro/shadow.stderr
@@ -0,0 +1,18 @@
+error[E0259]: the name `derive_a` is defined multiple times
+  --> $DIR/shadow.rs:16:1
+   |
+LL | extern crate derive_a;
+   | ---------------------- previous import of the extern crate `derive_a` here
+LL | #[macro_use]
+LL | extern crate derive_a; //~ ERROR the name `derive_a` is defined multiple times
+   | ^^^^^^^^^^^^^^^^^^^^^^ `derive_a` reimported here
+   |
+   = note: `derive_a` must be defined only once in the type namespace of this module
+help: you can use `as` to change the binding name of the import
+   |
+LL | extern crate derive_a as other_derive_a; //~ ERROR the name `derive_a` is defined multiple times
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0259`.
diff --git a/src/test/compile-fail/proc-macro/two-crate-types-1.rs b/src/test/ui/proc-macro/two-crate-types-1.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/two-crate-types-1.rs
rename to src/test/ui/proc-macro/two-crate-types-1.rs
diff --git a/src/test/ui/proc-macro/two-crate-types-1.stderr b/src/test/ui/proc-macro/two-crate-types-1.stderr
new file mode 100644
index 0000000..deaba1c
--- /dev/null
+++ b/src/test/ui/proc-macro/two-crate-types-1.stderr
@@ -0,0 +1,4 @@
+error: cannot mix `proc-macro` crate type with others
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/proc-macro/two-crate-types-2.rs b/src/test/ui/proc-macro/two-crate-types-2.rs
similarity index 100%
rename from src/test/compile-fail/proc-macro/two-crate-types-2.rs
rename to src/test/ui/proc-macro/two-crate-types-2.rs
diff --git a/src/test/ui/proc-macro/two-crate-types-2.stderr b/src/test/ui/proc-macro/two-crate-types-2.stderr
new file mode 100644
index 0000000..deaba1c
--- /dev/null
+++ b/src/test/ui/proc-macro/two-crate-types-2.stderr
@@ -0,0 +1,4 @@
+error: cannot mix `proc-macro` crate type with others
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pub/pub-ident-fn-2.rs b/src/test/ui/pub/pub-ident-fn-2.rs
index 44884bf..648b106 100644
--- a/src/test/ui/pub/pub-ident-fn-2.rs
+++ b/src/test/ui/pub/pub-ident-fn-2.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub foo(s: usize) { bar() }
-//~^ ERROR missing `fn` for method definition
+//~^ ERROR missing `fn` for function definition
 
 fn main() {
     foo(2);
diff --git a/src/test/ui/pub/pub-ident-fn-2.stderr b/src/test/ui/pub/pub-ident-fn-2.stderr
index bbbb3df..ed7430f 100644
--- a/src/test/ui/pub/pub-ident-fn-2.stderr
+++ b/src/test/ui/pub/pub-ident-fn-2.stderr
@@ -1,9 +1,9 @@
-error: missing `fn` for method definition
+error: missing `fn` for function definition
   --> $DIR/pub-ident-fn-2.rs:11:4
    |
 LL | pub foo(s: usize) { bar() }
    |    ^
-help: add `fn` here to parse `foo` as a public method
+help: add `fn` here to parse `foo` as a public function
    |
 LL | pub fn foo(s: usize) { bar() }
    |     ^^
diff --git a/src/test/ui/pub/pub-ident-fn-or-struct-2.rs b/src/test/ui/pub/pub-ident-fn-or-struct-2.rs
index 1ccadc8..e528e86 100644
--- a/src/test/ui/pub/pub-ident-fn-or-struct-2.rs
+++ b/src/test/ui/pub/pub-ident-fn-or-struct-2.rs
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 pub S();
-//~^ ERROR missing `fn` or `struct` for method or struct definition
+//~^ ERROR missing `fn` or `struct` for function or struct definition
 
 fn main() {}
diff --git a/src/test/ui/pub/pub-ident-fn-or-struct-2.stderr b/src/test/ui/pub/pub-ident-fn-or-struct-2.stderr
index e492a8c..d423b83 100644
--- a/src/test/ui/pub/pub-ident-fn-or-struct-2.stderr
+++ b/src/test/ui/pub/pub-ident-fn-or-struct-2.stderr
@@ -1,4 +1,4 @@
-error: missing `fn` or `struct` for method or struct definition
+error: missing `fn` or `struct` for function or struct definition
   --> $DIR/pub-ident-fn-or-struct-2.rs:11:4
    |
 LL | pub S();
diff --git a/src/test/ui/pub/pub-ident-fn-or-struct.rs b/src/test/ui/pub/pub-ident-fn-or-struct.rs
index 0664918..d5254bf 100644
--- a/src/test/ui/pub/pub-ident-fn-or-struct.rs
+++ b/src/test/ui/pub/pub-ident-fn-or-struct.rs
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 pub S (foo) bar
-//~^ ERROR missing `fn` or `struct` for method or struct definition
+//~^ ERROR missing `fn` or `struct` for function or struct definition
 
 fn main() {}
diff --git a/src/test/ui/pub/pub-ident-fn-or-struct.stderr b/src/test/ui/pub/pub-ident-fn-or-struct.stderr
index c1bff34..b8b5e8a 100644
--- a/src/test/ui/pub/pub-ident-fn-or-struct.stderr
+++ b/src/test/ui/pub/pub-ident-fn-or-struct.stderr
@@ -1,4 +1,4 @@
-error: missing `fn` or `struct` for method or struct definition
+error: missing `fn` or `struct` for function or struct definition
   --> $DIR/pub-ident-fn-or-struct.rs:11:4
    |
 LL | pub S (foo) bar
diff --git a/src/test/ui/pub/pub-ident-fn-with-lifetime-2.rs b/src/test/ui/pub/pub-ident-fn-with-lifetime-2.rs
new file mode 100644
index 0000000..1ee8c84
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-fn-with-lifetime-2.rs
@@ -0,0 +1,6 @@
+pub   bar<'a>(&self, _s: &'a usize) -> bool { true }
+//~^ ERROR missing `fn` for method definition
+
+fn main() {
+    bar(2);
+}
diff --git a/src/test/ui/pub/pub-ident-fn-with-lifetime-2.stderr b/src/test/ui/pub/pub-ident-fn-with-lifetime-2.stderr
new file mode 100644
index 0000000..c403774
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-fn-with-lifetime-2.stderr
@@ -0,0 +1,12 @@
+error: missing `fn` for method definition
+  --> $DIR/pub-ident-fn-with-lifetime-2.rs:1:4
+   |
+LL | pub   bar<'a>(&self, _s: &'a usize) -> bool { true }
+   |    ^^^
+help: add `fn` here to parse `bar` as a public method
+   |
+LL | pub fn bar<'a>(&self, _s: &'a usize) -> bool { true }
+   |     ^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pub/pub-ident-fn-with-lifetime.rs b/src/test/ui/pub/pub-ident-fn-with-lifetime.rs
new file mode 100644
index 0000000..84f7bdc
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-fn-with-lifetime.rs
@@ -0,0 +1,6 @@
+pub   foo<'a>(_s: &'a usize) -> bool { true }
+//~^ ERROR missing `fn` for function definition
+
+fn main() {
+    foo(2);
+}
diff --git a/src/test/ui/pub/pub-ident-fn-with-lifetime.stderr b/src/test/ui/pub/pub-ident-fn-with-lifetime.stderr
new file mode 100644
index 0000000..8582380
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-fn-with-lifetime.stderr
@@ -0,0 +1,12 @@
+error: missing `fn` for function definition
+  --> $DIR/pub-ident-fn-with-lifetime.rs:1:4
+   |
+LL | pub   foo<'a>(_s: &'a usize) -> bool { true }
+   |    ^^^
+help: add `fn` here to parse `foo` as a public function
+   |
+LL | pub fn foo<'a>(_s: &'a usize) -> bool { true }
+   |     ^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pub/pub-ident-fn.fixed b/src/test/ui/pub/pub-ident-fn.fixed
index f2d0c6c..667e021 100644
--- a/src/test/ui/pub/pub-ident-fn.fixed
+++ b/src/test/ui/pub/pub-ident-fn.fixed
@@ -11,7 +11,7 @@
 // run-rustfix
 
 pub fn foo(_s: usize) -> bool { true }
-//~^ ERROR missing `fn` for method definition
+//~^ ERROR missing `fn` for function definition
 
 fn main() {
     foo(2);
diff --git a/src/test/ui/pub/pub-ident-fn.rs b/src/test/ui/pub/pub-ident-fn.rs
index 82c32f5..91bbf58 100644
--- a/src/test/ui/pub/pub-ident-fn.rs
+++ b/src/test/ui/pub/pub-ident-fn.rs
@@ -11,7 +11,7 @@
 // run-rustfix
 
 pub   foo(_s: usize) -> bool { true }
-//~^ ERROR missing `fn` for method definition
+//~^ ERROR missing `fn` for function definition
 
 fn main() {
     foo(2);
diff --git a/src/test/ui/pub/pub-ident-fn.stderr b/src/test/ui/pub/pub-ident-fn.stderr
index f7c96b8..1df6dd8 100644
--- a/src/test/ui/pub/pub-ident-fn.stderr
+++ b/src/test/ui/pub/pub-ident-fn.stderr
@@ -1,9 +1,9 @@
-error: missing `fn` for method definition
+error: missing `fn` for function definition
   --> $DIR/pub-ident-fn.rs:13:4
    |
 LL | pub   foo(_s: usize) -> bool { true }
    |    ^^^
-help: add `fn` here to parse `foo` as a public method
+help: add `fn` here to parse `foo` as a public function
    |
 LL | pub fn foo(_s: usize) -> bool { true }
    |     ^^
diff --git a/src/test/ui/pub/pub-ident-struct-with-lifetime.rs b/src/test/ui/pub/pub-ident-struct-with-lifetime.rs
new file mode 100644
index 0000000..2feb026
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-struct-with-lifetime.rs
@@ -0,0 +1,4 @@
+pub S<'a> {
+//~^ ERROR missing `struct` for struct definition
+}
+fn main() {}
diff --git a/src/test/ui/pub/pub-ident-struct-with-lifetime.stderr b/src/test/ui/pub/pub-ident-struct-with-lifetime.stderr
new file mode 100644
index 0000000..2bbcf5d
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-struct-with-lifetime.stderr
@@ -0,0 +1,12 @@
+error: missing `struct` for struct definition
+  --> $DIR/pub-ident-struct-with-lifetime.rs:1:4
+   |
+LL | pub S<'a> {
+   |    ^
+help: add `struct` here to parse `S` as a public struct
+   |
+LL | pub struct S<'a> {
+   |     ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pub/pub-ident-with-lifetime-incomplete.rs b/src/test/ui/pub/pub-ident-with-lifetime-incomplete.rs
new file mode 100644
index 0000000..c86a9f2
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-with-lifetime-incomplete.rs
@@ -0,0 +1,5 @@
+fn main() {
+}
+
+pub   foo<'a>
+//~^ ERROR missing `fn` or `struct` for function or struct definition
diff --git a/src/test/ui/pub/pub-ident-with-lifetime-incomplete.stderr b/src/test/ui/pub/pub-ident-with-lifetime-incomplete.stderr
new file mode 100644
index 0000000..0e0b127
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-with-lifetime-incomplete.stderr
@@ -0,0 +1,8 @@
+error: missing `fn` or `struct` for function or struct definition
+  --> $DIR/pub-ident-with-lifetime-incomplete.rs:4:4
+   |
+LL | pub   foo<'a>
+   |    ^^^
+
+error: aborting due to previous error
+
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/issue-56537-closure-uses-region-from-container.rs b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
new file mode 100644
index 0000000..24676fe
--- /dev/null
+++ b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
@@ -0,0 +1,74 @@
+// This is a collection of examples where a function's formal
+// parameter has an explicit lifetime and a closure within that
+// function returns that formal parameter. The closure's return type,
+// to be correctly inferred, needs to include the lifetime introduced
+// by the function.
+//
+// This works today, which precludes changing things so that closures
+// follow the same lifetime-elision rules used elsehwere. See
+// rust-lang/rust#56537
+
+// compile-pass
+// We are already testing NLL explicitly via the revision system below.
+// ignore-compare-mode-nll
+
+// revisions: ll nll migrate
+//[ll] compile-flags:-Zborrowck=ast
+//[nll] compile-flags:-Zborrowck=mir -Z two-phase-borrows
+//[migrate] compile-flags:-Zborrowck=migrate -Z two-phase-borrows
+
+fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x| { p }; // no type annotation at all
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x| -> &str { p }; // type annotation on the return type
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x| -> &'w str { p }; // type+region annotation on return type
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_arg_type_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x: &str| -> &str { p }; // type annotation on arg and return types
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_arg_type_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x: &str| -> &'w str { p }; // fully annotated
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn main() {
+    let world = format!("World");
+    let w1: &str = {
+        let hello = format!("He11o");
+        willy_no_annot(&world, &hello)
+    };
+    let w2: &str = {
+        let hello = format!("He22o");
+        willy_ret_type_annot(&world, &hello)
+    };
+    let w3: &str = {
+        let hello = format!("He33o");
+        willy_ret_region_annot(&world, &hello)
+    };
+    let w4: &str = {
+        let hello = format!("He44o");
+        willy_arg_type_ret_type_annot(&world, &hello)
+    };
+    let w5: &str = {
+        let hello = format!("He55o");
+        willy_arg_type_ret_region_annot(&world, &hello)
+    };
+    assert_eq!((w1, w2, w3, w4, w5),
+               ("World","World","World","World","World"));
+}
diff --git a/src/test/ui/regions/regions-free-region-ordering-incorrect.rs b/src/test/ui/regions/regions-free-region-ordering-incorrect.rs
index 9cb61c2..2508002 100644
--- a/src/test/ui/regions/regions-free-region-ordering-incorrect.rs
+++ b/src/test/ui/regions/regions-free-region-ordering-incorrect.rs
@@ -10,23 +10,23 @@
 
 // Test that free regions ordering only goes one way. That is,
 // we have `&'a Node<'b, T>`, which implies that `'a <= 'b`,
-// but not `'b <= 'a`. Hence returning `&self.val` (which has lifetime
+// but not `'b <= 'a`. Hence, returning `&self.val` (which has lifetime
 // `'a`) where `'b` is expected yields an error.
 //
 // This test began its life as a test for issue #4325.
 
-struct Node<'b, T:'b> {
-  val: T,
-  next: Option<&'b Node<'b, T>>
+struct Node<'b, T: 'b> {
+    val: T,
+    next: Option<&'b Node<'b, T>>
 }
 
 impl<'b, T> Node<'b, T> {
-  fn get<'a>(&'a self) -> &'b T {
-    match self.next {
-      Some(ref next) => next.get(),
-      None => &self.val //~ ERROR cannot infer
+    fn get<'a>(&'a self) -> &'b T {
+        match self.next {
+            Some(ref next) => next.get(),
+            None => &self.val //~ ERROR cannot infer
+        }
     }
-  }
 }
 
 fn main() {}
diff --git a/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr b/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr
index 3dce04e..6b28ab4 100644
--- a/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr
+++ b/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr
@@ -1,32 +1,32 @@
 error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
-  --> $DIR/regions-free-region-ordering-incorrect.rs:27:15
+  --> $DIR/regions-free-region-ordering-incorrect.rs:27:21
    |
-LL |       None => &self.val //~ ERROR cannot infer
-   |               ^^^^^^^^^
+LL |             None => &self.val //~ ERROR cannot infer
+   |                     ^^^^^^^^^
    |
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the method body at 24:10...
-  --> $DIR/regions-free-region-ordering-incorrect.rs:24:10
+note: first, the lifetime cannot outlive the lifetime 'a as defined on the method body at 24:12...
+  --> $DIR/regions-free-region-ordering-incorrect.rs:24:12
    |
-LL |   fn get<'a>(&'a self) -> &'b T {
-   |          ^^
+LL |     fn get<'a>(&'a self) -> &'b T {
+   |            ^^
 note: ...so that reference does not outlive borrowed content
-  --> $DIR/regions-free-region-ordering-incorrect.rs:27:15
+  --> $DIR/regions-free-region-ordering-incorrect.rs:27:21
    |
-LL |       None => &self.val //~ ERROR cannot infer
-   |               ^^^^^^^^^
+LL |             None => &self.val //~ ERROR cannot infer
+   |                     ^^^^^^^^^
 note: but, the lifetime must be valid for the lifetime 'b as defined on the impl at 23:6...
   --> $DIR/regions-free-region-ordering-incorrect.rs:23:6
    |
 LL | impl<'b, T> Node<'b, T> {
    |      ^^
 note: ...so that reference does not outlive borrowed content
-  --> $DIR/regions-free-region-ordering-incorrect.rs:25:5
+  --> $DIR/regions-free-region-ordering-incorrect.rs:25:9
    |
-LL | /     match self.next {
-LL | |       Some(ref next) => next.get(),
-LL | |       None => &self.val //~ ERROR cannot infer
-LL | |     }
-   | |_____^
+LL | /         match self.next {
+LL | |             Some(ref next) => next.get(),
+LL | |             None => &self.val //~ ERROR cannot infer
+LL | |         }
+   | |_________^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/issue-5035.rs b/src/test/ui/resolve/issue-5035.rs
index e9b50dd..3ed41c6 100644
--- a/src/test/ui/resolve/issue-5035.rs
+++ b/src/test/ui/resolve/issue-5035.rs
@@ -14,6 +14,6 @@
 
 use ImportError; //~ ERROR unresolved import `ImportError` [E0432]
                  //~^ no `ImportError` in the root
-impl ImportError for () {} // check that this is not an additional error (c.f. #35142)
+impl ImportError for () {} // check that this is not an additional error (cf. issue #35142)
 
 fn main() {}
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/meta.rs b/src/test/ui/rfc-2126-extern-absolute-paths/meta.rs
index 499a322..004c4a0 100644
--- a/src/test/ui/rfc-2126-extern-absolute-paths/meta.rs
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/meta.rs
@@ -11,7 +11,7 @@
 // edition:2018
 
 // Tests that `meta` is whitelisted, even if the crate doesn't exist
-// yet (i.e. it causes a different error than `not-whitelisted.rs`).
+// yet (i.e., it causes a different error than `not-whitelisted.rs`).
 use meta; //~ ERROR can't find crate for `meta`
 
 fn main() {}
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/run-pass/traits/trait-alias.rs b/src/test/ui/run-pass/traits/trait-alias.rs
new file mode 100644
index 0000000..9be5664
--- /dev/null
+++ b/src/test/ui/run-pass/traits/trait-alias.rs
@@ -0,0 +1,7 @@
+// run-pass
+#![feature(trait_alias)]
+
+pub trait Foo {}
+pub trait FooAlias = Foo;
+
+fn main() {}
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/simd-intrinsic/simd-intrinsic-generic-select.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs
index d74d681..2a2d35e 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs
@@ -33,6 +33,7 @@
 
 extern "platform-intrinsic" {
     fn simd_select<T, U>(x: T, a: U, b: U) -> U;
+    fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
 }
 
 fn main() {
@@ -52,5 +53,14 @@
 
         simd_select(z, z, z);
         //~^ ERROR mask element type is `f32`, expected `i_`
+
+        simd_select_bitmask(0u8, x, x);
+        //~^ ERROR mask length `8` != other vector length `4`
+
+        simd_select_bitmask(0.0f32, x, x);
+        //~^ ERROR `f32` is not an integral type
+
+        simd_select_bitmask("x", x, x);
+        //~^ ERROR `&str` is not an integral type
     }
 }
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr
index 61e4202..584f3d5 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr
@@ -1,21 +1,39 @@
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
-  --> $DIR/simd-intrinsic-generic-select.rs:47:9
+  --> $DIR/simd-intrinsic-generic-select.rs:48:9
    |
 LL |         simd_select(m8, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `u32`, expected `i_`
-  --> $DIR/simd-intrinsic-generic-select.rs:50:9
+  --> $DIR/simd-intrinsic-generic-select.rs:51:9
    |
 LL |         simd_select(x, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `f32`, expected `i_`
-  --> $DIR/simd-intrinsic-generic-select.rs:53:9
+  --> $DIR/simd-intrinsic-generic-select.rs:54:9
    |
 LL |         simd_select(z, z, z);
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
+  --> $DIR/simd-intrinsic-generic-select.rs:57:9
+   |
+LL |         simd_select_bitmask(0u8, x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `f32` is not an integral type
+  --> $DIR/simd-intrinsic-generic-select.rs:60:9
+   |
+LL |         simd_select_bitmask(0.0f32, x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `&str` is not an integral type
+  --> $DIR/simd-intrinsic-generic-select.rs:63:9
+   |
+LL |         simd_select_bitmask("x", x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-single-nominal-type.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-single-nominal-type.rs
index 0d0bf24..5e009ea 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-single-nominal-type.rs
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-single-nominal-type.rs
@@ -16,7 +16,7 @@
 struct B(i16, i16, i16, i16, i16, i16, i16, i16);
 
 // each intrinsic definition has to use the same nominal type for any
-// vector structure throughout that declaration (i.e. every instance
+// vector structure throughout that declaration (i.e., every instance
 // of i16x8 in each `fn ...;` needs to be either A or B)
 
 extern "platform-intrinsic" {
diff --git a/src/test/ui/span/issue-24805-dropck-trait-has-items.rs b/src/test/ui/span/issue-24805-dropck-trait-has-items.rs
index 7552338..b9e4ffa 100644
--- a/src/test/ui/span/issue-24805-dropck-trait-has-items.rs
+++ b/src/test/ui/span/issue-24805-dropck-trait-has-items.rs
@@ -25,7 +25,7 @@
 impl<'a,T> HasMethodWithSelfArg for &'a T { }
 impl<'a,T> HasType for &'a T { type Something = (); }
 
-// e.g. `impl_drop!(Send, D_Send)` expands to:
+// e.g., `impl_drop!(Send, D_Send)` expands to:
 //   ```rust
 //   struct D_Send<T:Send>(T);
 //   impl<T:Send> Drop for D_Send<T> { fn drop(&mut self) { } }
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
new file mode 100644
index 0000000..8592af1
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+
+use std::fmt::Debug;
+
+fn foo(d: impl Debug + 'static) {
+//~^ HELP consider adding an explicit lifetime bound  `'static` to `impl Debug`
+    bar(d);
+//~^ ERROR the parameter type `impl Debug` may not live long enough
+//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
+}
+
+fn bar(d: impl Debug + 'static) {
+    println!("{:?}", d)
+}
+
+fn main() {
+  foo("hi");
+}
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
new file mode 100644
index 0000000..c67d78e
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
@@ -0,0 +1,18 @@
+// run-rustfix
+
+use std::fmt::Debug;
+
+fn foo(d: impl Debug) {
+//~^ HELP consider adding an explicit lifetime bound  `'static` to `impl Debug`
+    bar(d);
+//~^ ERROR the parameter type `impl Debug` may not live long enough
+//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
+}
+
+fn bar(d: impl Debug + 'static) {
+    println!("{:?}", d)
+}
+
+fn main() {
+  foo("hi");
+}
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
new file mode 100644
index 0000000..cba231d
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
@@ -0,0 +1,19 @@
+error[E0310]: the parameter type `impl Debug` may not live long enough
+  --> $DIR/suggest-impl-trait-lifetime.rs:7:5
+   |
+LL |     bar(d);
+   |     ^^^
+   |
+note: ...so that the type `impl Debug` will meet its required lifetime bounds
+  --> $DIR/suggest-impl-trait-lifetime.rs:7:5
+   |
+LL |     bar(d);
+   |     ^^^
+help: consider adding an explicit lifetime bound  `'static` to `impl Debug`...
+   |
+LL | fn foo(d: impl Debug + 'static) {
+   |           ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs b/src/test/ui/trait-method-number-parameters.rs
similarity index 74%
copy from src/test/ui/feature-gate-exhaustive_integer_patterns.rs
copy to src/test/ui/trait-method-number-parameters.rs
index 3aa1522..c2591e4 100644
--- a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs
+++ b/src/test/ui/trait-method-number-parameters.rs
@@ -8,9 +8,16 @@
 // 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 => {}
+trait Foo {
+    fn foo(&mut self, x: i32, y: i32) -> i32;
+}
+
+impl Foo for i32 {
+    fn foo(
+        &mut self, //~ ERROR
+        x: i32,
+    ) {
     }
 }
+
+fn main() {}
diff --git a/src/test/ui/trait-method-number-parameters.stderr b/src/test/ui/trait-method-number-parameters.stderr
new file mode 100644
index 0000000..98a08d2
--- /dev/null
+++ b/src/test/ui/trait-method-number-parameters.stderr
@@ -0,0 +1,13 @@
+error[E0050]: method `foo` has 2 parameters but the declaration in trait `Foo::foo` has 3
+  --> $DIR/trait-method-number-parameters.rs:17:9
+   |
+LL |       fn foo(&mut self, x: i32, y: i32) -> i32;
+   |              ------------------------- trait requires 3 parameters
+...
+LL | /         &mut self, //~ ERROR
+LL | |         x: i32,
+   | |______________^ expected 3 parameters, found 2
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0050`.
diff --git a/src/test/ui/traits/trait-impl-different-num-params.stderr b/src/test/ui/traits/trait-impl-different-num-params.stderr
index c3bbf99..1802444 100644
--- a/src/test/ui/traits/trait-impl-different-num-params.stderr
+++ b/src/test/ui/traits/trait-impl-different-num-params.stderr
@@ -2,7 +2,7 @@
   --> $DIR/trait-impl-different-num-params.rs:15:12
    |
 LL |     fn bar(&self, x: usize) -> Self;
-   |                      ----- trait requires 2 parameters
+   |            --------------- trait requires 2 parameters
 ...
 LL |     fn bar(&self) -> isize {
    |            ^^^^^ expected 2 parameters, found 1
diff --git a/src/test/ui/type/type-alias-bounds.rs b/src/test/ui/type/type-alias-bounds.rs
index a17bb9e..41f260a 100644
--- a/src/test/ui/type/type-alias-bounds.rs
+++ b/src/test/ui/type/type-alias-bounds.rs
@@ -48,7 +48,7 @@
     x.1.push(y); // &'a i32: 'static does not hold
 }
 
-// Bounds are not checked either, i.e. the definition is not necessarily well-formed
+// Bounds are not checked either, i.e., the definition is not necessarily well-formed
 struct Sendable<T: Send>(T);
 type MySendable<T> = Sendable<T>; // no error here!
 
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/unnecessary-extern-crate.rs b/src/test/ui/unnecessary-extern-crate.rs
index 110cfef..4eb3c3d 100644
--- a/src/test/ui/unnecessary-extern-crate.rs
+++ b/src/test/ui/unnecessary-extern-crate.rs
@@ -11,7 +11,7 @@
 // edition:2018
 
 #![deny(unused_extern_crates)]
-#![feature(alloc, test, libc, crate_visibility_modifier)]
+#![feature(alloc, test, rustc_private, crate_visibility_modifier)]
 
 extern crate libc;
 //~^ ERROR unused extern crate
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index bf95b31..ea6c711 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -14,7 +14,7 @@
 
 use std::collections::BTreeMap;
 use std::env;
-use std::fs::File;
+use std::fs;
 use std::io::{self, Read, Write};
 use std::path::{PathBuf, Path};
 use std::process::{Command, Stdio};
@@ -606,7 +606,7 @@
 
         let filename = path.file_name().unwrap().to_str().unwrap();
         let sha256 = self.output.join(format!("{}.sha256", filename));
-        t!(t!(File::create(&sha256)).write_all(&sha.stdout));
+        t!(fs::write(&sha256, &sha.stdout));
 
         let stdout = String::from_utf8_lossy(&sha.stdout);
         stdout.split_whitespace().next().unwrap().to_string()
@@ -621,8 +621,10 @@
         let asc = self.output.join(format!("{}.asc", filename));
         println!("signing: {:?}", path);
         let mut cmd = Command::new("gpg");
-        cmd.arg("--no-tty")
+        cmd.arg("--pinentry-mode=loopback")
+            .arg("--no-tty")
             .arg("--yes")
+            .arg("--batch")
             .arg("--passphrase-fd").arg("0")
             .arg("--personal-digest-preferences").arg("SHA512")
             .arg("--armor")
@@ -643,7 +645,7 @@
 
     fn write(&self, contents: &str, channel_name: &str, suffix: &str) {
         let dst = self.output.join(format!("channel-rust-{}{}", channel_name, suffix));
-        t!(t!(File::create(&dst)).write_all(contents.as_bytes()));
+        t!(fs::write(&dst, contents));
         self.hash(&dst);
         self.sign(&dst);
     }
diff --git a/src/tools/cargo b/src/tools/cargo
index 5e85ba1..2cf1f5d 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 5e85ba14aaa20f8133863373404cb0af69eeef2c
+Subproject commit 2cf1f5dda2f7ed84e94c4d32f643e0f1f15352f0
diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs
index 5b717c4..ab74e7b 100644
--- a/src/tools/cargotest/main.rs
+++ b/src/tools/cargotest/main.rs
@@ -11,8 +11,7 @@
 use std::env;
 use std::process::Command;
 use std::path::{Path, PathBuf};
-use std::fs::File;
-use std::io::Write;
+use std::fs;
 
 struct Test {
     repo: &'static str,
@@ -91,10 +90,7 @@
     println!("testing {}", test.repo);
     let dir = clone_repo(test, out_dir);
     if let Some(lockfile) = test.lock {
-        File::create(&dir.join("Cargo.lock"))
-            .expect("")
-            .write_all(lockfile.as_bytes())
-            .expect("");
+        fs::write(&dir.join("Cargo.lock"), lockfile).unwrap();
     }
     if !run_cargo_test(cargo, &dir, test.packages) {
         panic!("tests failed for {}", test.repo);
diff --git a/src/tools/clippy b/src/tools/clippy
index 29bf75c..b7a431e 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 29bf75cd3147d4e34a5e70bd167898a8105f7e5d
+Subproject commit b7a431ea1ddb96a396921bf9b5f2f6d8690cd474
diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs
index 8d20a9e..7b967a10 100644
--- a/src/tools/compiletest/src/errors.rs
+++ b/src/tools/compiletest/src/errors.rs
@@ -56,7 +56,7 @@
 #[derive(Debug)]
 pub struct Error {
     pub line_num: usize,
-    /// What kind of message we expect (e.g. warning, error, suggestion).
+    /// What kind of message we expect (e.g., warning, error, suggestion).
     /// `None` if not specified or unknown message kind.
     pub kind: Option<ErrorKind>,
     pub msg: String,
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index f4a82ae..0038399 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -715,7 +715,7 @@
         }
     }
 
-    /// Parses a name-value directive which contains config-specific information, e.g. `ignore-x86`
+    /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
     /// or `normalize-stderr-32bit`.
     fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective {
         if line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-') {
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index f63950b..9aefd15 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -38,7 +38,7 @@
 use std::env;
 use std::ffi::OsString;
 use std::fs;
-use std::io::{self, Read};
+use std::io::{self, ErrorKind};
 use std::path::{Path, PathBuf};
 use std::process::Command;
 use test::ColorConfig;
@@ -511,7 +511,11 @@
     test::TestOpts {
         filter: config.filter.clone(),
         filter_exact: config.filter_exact,
-        run_ignored: config.run_ignored,
+        run_ignored: if config.run_ignored {
+            test::RunIgnored::Yes
+        } else {
+            test::RunIgnored::No
+        },
         format: if config.quiet {
             test::OutputFormat::Terse
         } else {
@@ -686,13 +690,11 @@
 ) -> bool {
     let stamp_name = stamp(config, testpaths, revision);
     // Check hash.
-    let mut f = match fs::File::open(&stamp_name) {
+    let contents = match fs::read_to_string(&stamp_name) {
         Ok(f) => f,
+        Err(ref e) if e.kind() == ErrorKind::InvalidData => panic!("Can't read stamp contents"),
         Err(_) => return true,
     };
-    let mut contents = String::new();
-    f.read_to_string(&mut contents)
-        .expect("Can't read stamp contents");
     let expected_hash = runtest::compute_stamp_hash(config);
     if contents != expected_hash {
         return true;
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index c654230..45527a7 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -458,11 +458,7 @@
             None => 2,
         };
 
-        let mut src = String::new();
-        File::open(&self.testpaths.file)
-            .unwrap()
-            .read_to_string(&mut src)
-            .unwrap();
+        let src = fs::read_to_string(&self.testpaths.file).unwrap();
         let mut srcs = vec![src];
 
         let mut round = 0;
@@ -500,12 +496,7 @@
         let mut expected = match self.props.pp_exact {
             Some(ref file) => {
                 let filepath = self.testpaths.file.parent().unwrap().join(file);
-                let mut s = String::new();
-                File::open(&filepath)
-                    .unwrap()
-                    .read_to_string(&mut s)
-                    .unwrap();
-                s
+                fs::read_to_string(&filepath).unwrap()
             }
             None => srcs[srcs.len() - 2].clone(),
         };
@@ -1949,10 +1940,7 @@
 
     fn dump_output_file(&self, out: &str, extension: &str) {
         let outfile = self.make_out_name(extension);
-        File::create(&outfile)
-            .unwrap()
-            .write_all(out.as_bytes())
-            .unwrap();
+        fs::write(&outfile, out).unwrap();
     }
 
     /// Create a filename for output with the given extension.  Example:
@@ -2149,11 +2137,7 @@
         path: &P,
         mut other_files: Option<&mut Vec<String>>,
     ) -> Vec<usize> {
-        let mut file =
-            fs::File::open(path).expect("markdown_test_output_check_entry File::open failed");
-        let mut content = String::new();
-        file.read_to_string(&mut content)
-            .expect("markdown_test_output_check_entry read_to_string failed");
+        let content = fs::read_to_string(&path).unwrap();
         let mut ignore = false;
         content
             .lines()
@@ -2826,11 +2810,7 @@
     }
 
     fn check_mir_dump(&self) {
-        let mut test_file_contents = String::new();
-        fs::File::open(self.testpaths.file.clone())
-            .unwrap()
-            .read_to_string(&mut test_file_contents)
-            .unwrap();
+        let test_file_contents = fs::read_to_string(&self.testpaths.file).unwrap();
         if let Some(idx) = test_file_contents.find("// END RUST SOURCE") {
             let (_, tests_text) = test_file_contents.split_at(idx + "// END_RUST SOURCE".len());
             let tests_text_str = String::from(tests_text);
@@ -2894,9 +2874,7 @@
         }
         self.check_mir_test_timestamp(test_name, &output_file);
 
-        let mut dumped_file = fs::File::open(output_file.clone()).unwrap();
-        let mut dumped_string = String::new();
-        dumped_file.read_to_string(&mut dumped_string).unwrap();
+        let dumped_string = fs::read_to_string(&output_file).unwrap();
         let mut dumped_lines = dumped_string
             .lines()
             .map(|l| nocomment_mir_line(l))
@@ -3108,19 +3086,13 @@
     }
 
     fn load_expected_output_from_path(&self, path: &Path) -> Result<String, String> {
-        let mut result = String::new();
-        match File::open(path).and_then(|mut f| f.read_to_string(&mut result)) {
-            Ok(_) => Ok(result),
-            Err(e) => Err(format!(
-                "failed to load expected output from `{}`: {}",
-                path.display(),
-                e
-            )),
-        }
+        fs::read_to_string(path).map_err(|err| {
+            format!("failed to load expected output from `{}`: {}", path.display(), err)
+        })
     }
 
     fn delete_file(&self, file: &PathBuf) {
-        if let Err(e) = ::std::fs::remove_file(file) {
+        if let Err(e) = fs::remove_file(file) {
             self.fatal(&format!(
                 "failed to delete `{}`: {}",
                 file.display(),
@@ -3182,16 +3154,13 @@
         for output_file in &files {
             if actual.is_empty() {
                 self.delete_file(output_file);
-            } else {
-                match File::create(&output_file).and_then(|mut f| f.write_all(actual.as_bytes())) {
-                    Ok(()) => {}
-                    Err(e) => self.fatal(&format!(
-                        "failed to write {} to `{}`: {}",
-                        kind,
-                        output_file.display(),
-                        e
-                    )),
-                }
+            } else if let Err(err) = fs::write(&output_file, &actual) {
+                self.fatal(&format!(
+                    "failed to write {} to `{}`: {}",
+                    kind,
+                    output_file.display(),
+                    err,
+                ));
             }
         }
 
@@ -3243,9 +3212,8 @@
     }
 
     fn create_stamp(&self) {
-        let mut f = File::create(::stamp(&self.config, self.testpaths, self.revision)).unwrap();
-        f.write_all(compute_stamp_hash(&self.config).as_bytes())
-            .unwrap();
+        let stamp = ::stamp(&self.config, self.testpaths, self.revision);
+        fs::write(&stamp, compute_stamp_hash(&self.config)).unwrap();
     }
 }
 
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index a5556e1..03add41 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -18,8 +18,8 @@
 use std::collections::BTreeMap;
 use std::env;
 use std::error::Error;
-use std::fs::{read_dir, File};
-use std::io::{Read, Write};
+use std::fs::{self, read_dir, File};
+use std::io::Write;
 use std::path::Path;
 use std::path::PathBuf;
 use std::cell::RefCell;
@@ -210,8 +210,7 @@
     for entry in read_dir(metadata_dir)? {
         let path = entry?.path();
 
-        let mut metadata_str = String::new();
-        File::open(&path).and_then(|mut f| f.read_to_string(&mut metadata_str))?;
+        let metadata_str = fs::read_to_string(&path)?;
 
         let some_errors: ErrorMetadataMap = json::decode(&metadata_str)?;
 
diff --git a/src/tools/miri b/src/tools/miri
index 61f2076..bccadeb 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 61f20761d3124f5a1b1caee8aa15637cc7f92d8e
+Subproject commit bccadeb4f7cbeeb14097a365653148afe8bbd159
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 4ade87f..a65d263 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -34,6 +34,16 @@
     'rust-by-example': '@steveklabnik @marioidival @projektir',
 }
 
+EMOJI = {
+    'miri': '🛰️',
+    'clippy-driver': '📎',
+    'rls': '💻',
+    'rustfmt': '📝',
+    'book': '📖',
+    'nomicon': '👿',
+    'reference': '📚',
+    'rust-by-example': '👩‍🏫',
+}
 
 def read_current_status(current_commit, path):
     '''Reads build status of `current_commit` from content of `history/*.tsv`
@@ -63,13 +73,12 @@
         }
 
         slug = 'rust-lang/rust'
-        message = textwrap.dedent('''\
-            📣 Toolstate changed by {}!
-
+        long_message = textwrap.dedent('''\
             Tested on commit {}@{}.
             Direct link to PR: <{}>
 
-        ''').format(relevant_pr_number, slug, current_commit, relevant_pr_url)
+        ''').format(slug, current_commit, relevant_pr_url)
+        emoji_status = []
         anything_changed = False
         for status in latest:
             tool = status['tool']
@@ -81,12 +90,18 @@
                 status[os] = new
                 if new > old:
                     changed = True
-                    message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
-                        .format(tool, os, old, new, MAINTAINERS.get(tool))
+                    long_message += '🎉 {} on {}: {} → {}.\n' \
+                        .format(tool, os, old, new)
+                    emoji = "{}🎉".format(EMOJI.get(tool))
+                    if msg not in emoji_status:
+                        emoji_status += [msg]
                 elif new < old:
                     changed = True
-                    message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
+                    long_message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
                         .format(tool, os, old, new, MAINTAINERS.get(tool))
+                    emoji = "{}💔".format(EMOJI.get(tool))
+                    if msg not in emoji_status:
+                        emoji_status += [msg]
 
             if changed:
                 status['commit'] = current_commit
@@ -96,6 +111,9 @@
         if not anything_changed:
             return ''
 
+        short_message = "📣 Toolstate changed by {}! ({})"
+            .format(relevant_pr_number, '/'.join(emoji_status))
+        message = short_message + "\n\n" + long_message
         f.seek(0)
         f.truncate(0)
         json.dump(latest, f, indent=4, separators=(',', ': '))
diff --git a/src/tools/rls b/src/tools/rls
index cfd8449..bd5b899 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit cfd8449bd6fcfc6a0b53889c616faa4de4513636
+Subproject commit bd5b899afb05e14d33e210ede3da241ca1ca088f
diff --git a/src/tools/rustc-std-workspace-core/Cargo.toml b/src/tools/rustc-std-workspace-core/Cargo.toml
new file mode 100644
index 0000000..f000d63
--- /dev/null
+++ b/src/tools/rustc-std-workspace-core/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "rustc-std-workspace-core"
+version = "1.0.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+license = 'MIT/Apache-2.0'
+description = """
+Hack for the compiler's own build system
+"""
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+core = { path = "../../libcore" }
diff --git a/src/tools/rustc-std-workspace-core/README.md b/src/tools/rustc-std-workspace-core/README.md
new file mode 100644
index 0000000..9c2b1fa
--- /dev/null
+++ b/src/tools/rustc-std-workspace-core/README.md
@@ -0,0 +1,29 @@
+# The `rustc-std-workspace-core` crate
+
+This crate is a shim and empty crate which simply depends on `libcore` and
+reexports all of its contents. The crate is the crux of empowering the standard
+library to depend on crates from crates.io
+
+Crates on crates.io that the standard library depend on the
+`rustc-std-workspace-core` crate from crates.io. On crates.io, however, this
+crate is empty. We use `[patch]` to override it to this crate in this
+repository. As a result, crates on crates.io will draw a dependency edge to
+`libcore`, the version defined in this repository. That should draw all the
+dependency edges to ensure Cargo builds crates successfully!
+
+Note that crates on crates.io need to depend on this crate with the name `core`
+for everything to work correctly. To do that they can use:
+
+```toml
+core = { version = "1.0.0", optional = true, package = 'rustc-std-workspace-core' }
+```
+
+Through the use of the `package` key the crate is renamed to `core`, meaning
+it'll look like
+
+```
+--extern core=.../librustc_std_workspace_core-XXXXXXX.rlib
+```
+
+when Cargo invokes the compiler, satisfying the implicit `extern crate core`
+directive injected by the compiler.
diff --git a/src/tools/rustc-std-workspace-core/lib.rs b/src/tools/rustc-std-workspace-core/lib.rs
new file mode 100644
index 0000000..e2946fe
--- /dev/null
+++ b/src/tools/rustc-std-workspace-core/lib.rs
@@ -0,0 +1,6 @@
+#![feature(no_core)]
+#![no_core]
+
+extern crate core;
+
+pub use core::*;
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index f2b08f8..5acfee2 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -17,7 +17,7 @@
 # Currently Cargo/RLS depend on `failure` which depends on `synstructure` which
 # enables this feature. Clippy, however, does not depend on anything that
 # enables this feature. Enable it unconditionally.
-syn = { version = "0.14", features = ['extra-traits'] }
+syn = { version = "0.15", features = ['extra-traits'] }
 
 [target.'cfg(windows)'.dependencies.winapi]
 version = "0.3"
@@ -50,9 +50,11 @@
 ]
 
 [dependencies]
-serde_json = { version = "1.0.31", features = ["raw_value"] }
-rand = { version = "0.5.5", features = ["i128_support"] }
 curl-sys = { version = "0.4.13", optional = true }
+parking_lot = { version = "0.6", features = ['nightly'] }
+rand = { version = "0.5.5", features = ["i128_support"] }
+serde_json = { version = "1.0.31", features = ["raw_value"] }
+smallvec = { version = "0.6", features = ['union'] }
 
 [target.'cfg(not(windows))'.dependencies]
 openssl = { version = "0.10.12", optional = true }
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 43206f4..be13559 160000
--- a/src/tools/rustfmt
+++ b/src/tools/rustfmt
@@ -1 +1 @@
-Subproject commit 43206f41625b8ad670d65bcad37686b40a1c7c48
+Subproject commit be135599ef5e54b5219f9adec68e1ee267ea0584
diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs
index f6e42c8..ae93055 100644
--- a/src/tools/tidy/src/bins.rs
+++ b/src/tools/tidy/src/bins.rs
@@ -24,13 +24,10 @@
 #[cfg(unix)]
 pub fn check(path: &Path, bad: &mut bool) {
     use std::fs;
-    use std::io::Read;
     use std::process::{Command, Stdio};
     use std::os::unix::prelude::*;
 
-    if let Ok(mut file) = fs::File::open("/proc/version") {
-        let mut contents = String::new();
-        file.read_to_string(&mut contents).unwrap();
+    if let Ok(contents) = fs::read_to_string("/proc/version") {
         // Probably on Windows Linux Subsystem or Docker via VirtualBox,
         // all files will be marked as executable, so skip checking.
         if contents.contains("Microsoft") || contents.contains("boot2docker") {
diff --git a/src/tools/tidy/src/cargo.rs b/src/tools/tidy/src/cargo.rs
index 466d2fa..ac7e968 100644
--- a/src/tools/tidy/src/cargo.rs
+++ b/src/tools/tidy/src/cargo.rs
@@ -15,8 +15,7 @@
 //! `extern crate` declarations. This should help us keep the DAG correctly
 //! structured through various refactorings to prune out unnecessary edges.
 
-use std::io::prelude::*;
-use std::fs::File;
+use std::fs;
 use std::path::Path;
 
 pub fn check(path: &Path, bad: &mut bool) {
@@ -41,10 +40,8 @@
 // Verify that the dependencies in Cargo.toml at `tomlfile` are sync'd with the
 // `extern crate` annotations in the lib.rs at `libfile`.
 fn verify(tomlfile: &Path, libfile: &Path, bad: &mut bool) {
-    let mut toml = String::new();
-    let mut librs = String::new();
-    t!(t!(File::open(tomlfile)).read_to_string(&mut toml));
-    t!(t!(File::open(libfile)).read_to_string(&mut librs));
+    let toml = t!(fs::read_to_string(&tomlfile));
+    let librs = t!(fs::read_to_string(&libfile));
 
     if toml.contains("name = \"bootstrap\"") {
         return
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 3e27c3d..2b5cff6 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -11,8 +11,7 @@
 //! Check license of third-party deps by inspecting vendor
 
 use std::collections::{BTreeSet, HashSet, HashMap};
-use std::fs::File;
-use std::io::Read;
+use std::fs;
 use std::path::Path;
 use std::process::Command;
 
@@ -53,6 +52,8 @@
     "ryu",                // Apache-2.0, rls/cargo/... (b/c of serde)
     "bytesize",           // Apache-2.0, cargo
     "im-rc",              // MPL-2.0+, cargo
+    "adler32",            // BSD-3-Clause AND Zlib, cargo dep that isn't used
+    "fortanix-sgx-abi",   // MPL-2.0+, libstd but only for sgx target
 ];
 
 /// Which crates to check against the whitelist?
@@ -63,12 +64,14 @@
 
 /// Whitelist of crates rustc is allowed to depend on. Avoid adding to the list if possible.
 const WHITELIST: &[Crate] = &[
+    Crate("adler32"),
     Crate("aho-corasick"),
     Crate("arrayvec"),
     Crate("atty"),
     Crate("backtrace"),
     Crate("backtrace-sys"),
     Crate("bitflags"),
+    Crate("build_const"),
     Crate("byteorder"),
     Crate("cc"),
     Crate("cfg-if"),
@@ -76,6 +79,8 @@
     Crate("chalk-macros"),
     Crate("cloudabi"),
     Crate("cmake"),
+    Crate("crc"),
+    Crate("crc32fast"),
     Crate("crossbeam-deque"),
     Crate("crossbeam-epoch"),
     Crate("crossbeam-utils"),
@@ -101,6 +106,8 @@
     Crate("memmap"),
     Crate("memoffset"),
     Crate("miniz-sys"),
+    Crate("miniz_oxide"),
+    Crate("miniz_oxide_c_api"),
     Crate("nodrop"),
     Crate("num_cpus"),
     Crate("owning_ref"),
@@ -110,7 +117,12 @@
     Crate("polonius-engine"),
     Crate("quick-error"),
     Crate("rand"),
+    Crate("rand_chacha"),
     Crate("rand_core"),
+    Crate("rand_hc"),
+    Crate("rand_isaac"),
+    Crate("rand_pcg"),
+    Crate("rand_xorshift"),
     Crate("redox_syscall"),
     Crate("redox_termios"),
     Crate("regex"),
@@ -120,8 +132,12 @@
     Crate("rustc-hash"),
     Crate("rustc-rayon"),
     Crate("rustc-rayon-core"),
+    Crate("rustc_version"),
     Crate("scoped-tls"),
     Crate("scopeguard"),
+    Crate("semver"),
+    Crate("semver-parser"),
+    Crate("serde"),
     Crate("smallvec"),
     Crate("stable_deref_trait"),
     Crate("tempfile"),
@@ -133,9 +149,9 @@
     Crate("unicode-width"),
     Crate("unreachable"),
     Crate("utf8-ranges"),
+    Crate("vcpkg"),
     Crate("version_check"),
     Crate("void"),
-    Crate("vcpkg"),
     Crate("winapi"),
     Crate("winapi-build"),
     Crate("winapi-i686-pc-windows-gnu"),
@@ -262,8 +278,7 @@
     if !path.exists() {
         panic!("{} does not exist", path.display());
     }
-    let mut contents = String::new();
-    t!(t!(File::open(path)).read_to_string(&mut contents));
+    let contents = t!(fs::read_to_string(&path));
 
     let mut found_license = false;
     for line in contents.lines() {
diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs
index a78d2d4..377a7c3 100644
--- a/src/tools/tidy/src/extdeps.rs
+++ b/src/tools/tidy/src/extdeps.rs
@@ -10,8 +10,7 @@
 
 // ! Check for external package sources. Allow only vendorable packages.
 
-use std::fs::File;
-use std::io::Read;
+use std::fs;
 use std::path::Path;
 
 /// List of whitelisted sources for packages
@@ -25,8 +24,7 @@
     let path = path.join("../Cargo.lock");
 
     // open and read the whole file
-    let mut cargo_lock = String::new();
-    t!(t!(File::open(path)).read_to_string(&mut cargo_lock));
+    let cargo_lock = t!(fs::read_to_string(&path));
 
     // process each line
     for line in cargo_lock.lines() {
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 85b123e..ff8fa2f 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -20,7 +20,7 @@
 
 use std::collections::HashMap;
 use std::fmt;
-use std::fs::File;
+use std::fs::{self, File};
 use std::io::prelude::*;
 use std::path::Path;
 
@@ -61,12 +61,9 @@
 
     let mut contents = String::new();
 
-    super::walk_many(&[&path.join("test/ui-fulldeps"),
-                       &path.join("test/ui"),
-                       &path.join("test/compile-fail"),
-                       &path.join("test/compile-fail-fulldeps"),
-                       &path.join("test/parse-fail"),
-                       &path.join("test/ui"),],
+    super::walk_many(&[&path.join("test/ui"),
+                       &path.join("test/ui-fulldeps"),
+                       &path.join("test/compile-fail")],
                      &mut |path| super::filter_dirs(path),
                      &mut |file| {
         let filename = file.file_name().unwrap().to_string_lossy();
@@ -183,9 +180,7 @@
 }
 
 pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
-    let mut contents = String::new();
-    let path = base_src_path.join("libsyntax/feature_gate.rs");
-    t!(t!(File::open(path)).read_to_string(&mut contents));
+    let contents = t!(fs::read_to_string(base_src_path.join("libsyntax/feature_gate.rs")));
 
     // we allow rustc-internal features to omit a tracking issue.
     // these features must be marked with `// rustc internal` in its own group.
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 700103d..614d205 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -56,15 +56,11 @@
 
 fn filter_dirs(path: &Path) -> bool {
     let skip = [
-        "src/dlmalloc",
         "src/llvm",
         "src/llvm-emscripten",
         "src/libbacktrace",
-        "src/libcompiler_builtins",
         "src/librustc_data_structures/owning_ref",
-        "src/compiler-rt",
-        "src/liblibc",
-        "src/rt/hoedown",
+        "src/vendor",
         "src/tools/cargo",
         "src/tools/clang",
         "src/tools/rls",
@@ -76,6 +72,7 @@
         "src/tools/lldb",
         "src/target",
         "src/stdsimd",
+        "src/rust-sgx",
         "target",
         "vendor",
     ];
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 822db25..acf7202 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -26,7 +26,6 @@
 //! exceptions:
 //!
 //! - core may not have platform-specific code
-//! - libcompiler_builtins may have platform-specific code
 //! - libpanic_abort may have platform-specific code
 //! - libpanic_unwind may have platform-specific code
 //! - libunwind may have platform-specific code
@@ -50,8 +49,6 @@
 // Paths that may contain platform-specific code
 const EXCEPTION_PATHS: &[&str] = &[
     // std crates
-    "src/libcompiler_builtins",
-    "src/liblibc",
     "src/libpanic_abort",
     "src/libpanic_unwind",
     "src/libunwind",